X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/82ad07c4182f744c07b96a15df4572e559ed7dc8..1c3344a105f656a45f6b46e1710c3fc4ab862a9a:/uidlist.c diff --git a/uidlist.c b/uidlist.c index 8104eca7..2503d8a8 100644 --- a/uidlist.c +++ b/uidlist.c @@ -3,12 +3,11 @@ * * Copyright (C) 1996 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras - * Copyright (C) 2004, 2005, 2006 Wayne Davison + * Copyright (C) 2004-2007 Wayne Davison * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -33,10 +32,11 @@ #endif extern int verbose; +extern int am_root; extern int preserve_uid; extern int preserve_gid; +extern int preserve_acls; extern int numeric_ids; -extern int am_root; struct idlist { struct idlist *next; @@ -79,7 +79,7 @@ static char *gid_to_name(gid_t gid) return NULL; } -static int map_uid(int id, char *name) +static uid_t map_uid(uid_t id, char *name) { uid_t uid; if (id != 0 && name_to_uid(name, &uid)) @@ -87,7 +87,7 @@ static int map_uid(int id, char *name) return id; } -static int map_gid(int id, char *name) +static gid_t map_gid(gid_t id, char *name) { gid_t gid; if (id != 0 && name_to_gid(name, &gid)) @@ -155,41 +155,41 @@ static int is_in_group(gid_t gid) } /* Add a uid to the list of uids. Only called on receiving side. */ -static struct idlist *recv_add_uid(int id, char *name) +static uid_t recv_add_uid(uid_t id, char *name) { - int id2 = name ? map_uid(id, name) : id; + uid_t id2 = name ? map_uid(id, name) : id; struct idlist *node; - node = add_to_list(&uidlist, id, name, id2); + node = add_to_list(&uidlist, (int)id, name, (int)id2); if (verbose > 3) { rprintf(FINFO, "uid %d(%s) maps to %d\n", - id, name ? name : "", id2); + (int)id, name ? name : "", (int)id2); } - return node; + return id2; } /* Add a gid to the list of gids. Only called on receiving side. */ -static struct idlist *recv_add_gid(int id, char *name) +static gid_t recv_add_gid(gid_t id, char *name) { - int id2 = name ? map_gid(id, name) : id; + gid_t id2 = name ? map_gid(id, name) : id; struct idlist *node; if (!am_root && !is_in_group(id2)) id2 = GID_NONE; - node = add_to_list(&gidlist, id, name, id2); + node = add_to_list(&gidlist, (int)id, name, (int)id2); if (verbose > 3) { rprintf(FINFO, "gid %d(%s) maps to %d\n", - id, name ? name : "", id2); + (int)id, name ? name : "", (int)id2); } - return node; + return id2; } /* this function is a definate candidate for a faster algorithm */ -static uid_t match_uid(uid_t uid) +uid_t match_uid(uid_t uid) { static uid_t last_in, last_out; struct idlist *list; @@ -210,7 +210,7 @@ static uid_t match_uid(uid_t uid) return last_out = uid; } -static gid_t match_gid(gid_t gid) +gid_t match_gid(gid_t gid) { static gid_t last_in = GID_NONE, last_out = GID_NONE; struct idlist *list; @@ -228,49 +228,51 @@ static gid_t match_gid(gid_t gid) return last_out = (gid_t)list->id2; } - list = recv_add_gid(gid, NULL); - return last_out = list->id2; + return last_out = recv_add_gid(gid, NULL); } /* Add a uid to the list of uids. Only called on sending side. */ -void add_uid(uid_t uid) +char *add_uid(uid_t uid) { struct idlist *list; + struct idlist *node; if (uid == 0) /* don't map root */ - return; + return NULL; for (list = uidlist; list; list = list->next) { if (list->id == (int)uid) - return; + return NULL; } - add_to_list(&uidlist, (int)uid, uid_to_name(uid), 0); + node = add_to_list(&uidlist, (int)uid, uid_to_name(uid), 0); + return node->name; } /* Add a gid to the list of gids. Only called on sending side. */ -void add_gid(gid_t gid) +char *add_gid(gid_t gid) { struct idlist *list; + struct idlist *node; if (gid == 0) /* don't map root */ - return; + return NULL; for (list = gidlist; list; list = list->next) { if (list->id == (int)gid) - return; + return NULL; } - add_to_list(&gidlist, (int)gid, gid_to_name(gid), 0); + node = add_to_list(&gidlist, (int)gid, gid_to_name(gid), 0); + return node->name; } - /* send a complete uid/gid mapping to the peer */ void send_uid_list(int f) { struct idlist *list; - if (preserve_uid) { + if (preserve_uid || preserve_acls) { int len; /* we send sequences of uid/byte-length/name */ for (list = uidlist; list; list = list->next) { @@ -287,7 +289,7 @@ void send_uid_list(int f) write_int(f, 0); } - if (preserve_gid) { + if (preserve_gid || preserve_acls) { int len; for (list = gidlist; list; list = list->next) { if (!list->name) @@ -301,44 +303,61 @@ void send_uid_list(int f) } } +uid_t recv_user_name(int f, uid_t uid) +{ + int len = read_byte(f); + char *name = new_array(char, len+1); + if (!name) + out_of_memory("recv_user_name"); + read_sbuf(f, name, len); + return recv_add_uid(uid, name); /* node keeps name's memory */ +} + +gid_t recv_group_name(int f, gid_t gid) +{ + int len = read_byte(f); + char *name = new_array(char, len+1); + if (!name) + out_of_memory("recv_group_name"); + read_sbuf(f, name, len); + return recv_add_gid(gid, name); /* node keeps name's memory */ +} + /* recv a complete uid/gid mapping from the peer and map the uid/gid * in the file list to local names */ void recv_uid_list(int f, struct file_list *flist) { int id, i; - char *name; - if (preserve_uid && !numeric_ids) { + if ((preserve_uid || preserve_acls) && !numeric_ids) { /* read the uid list */ - while ((id = read_int(f)) != 0) { - int len = read_byte(f); - name = new_array(char, len+1); - if (!name) - out_of_memory("recv_uid_list"); - read_sbuf(f, name, len); - recv_add_uid(id, name); /* node keeps name's memory */ - } + while ((id = read_int(f)) != 0) + recv_user_name(f, (uid_t)id); } - if (preserve_gid && !numeric_ids) { + if ((preserve_gid || preserve_acls) && !numeric_ids) { /* read the gid list */ - while ((id = read_int(f)) != 0) { - int len = read_byte(f); - name = new_array(char, len+1); - if (!name) - out_of_memory("recv_uid_list"); - read_sbuf(f, name, len); - recv_add_gid(id, name); /* node keeps name's memory */ - } + while ((id = read_int(f)) != 0) + recv_group_name(f, (gid_t)id); + } + +#ifdef SUPPORT_ACLS + if (preserve_acls && !numeric_ids) { + id_t *id; + while ((id = next_acl_uid(flist)) != NULL) + *id = match_uid(*id); + while ((id = next_acl_gid(flist)) != NULL) + *id = match_gid(*id); } +#endif /* Now convert all the uids/gids from sender values to our values. */ if (am_root && preserve_uid && !numeric_ids) { for (i = 0; i < flist->count; i++) - F_UID(flist->files[i]) = match_uid(F_UID(flist->files[i])); + F_OWNER(flist->files[i]) = match_uid(F_UID(flist->files[i])); } if (preserve_gid && (!am_root || !numeric_ids)) { for (i = 0; i < flist->count; i++) - F_GID(flist->files[i]) = match_gid(F_GID(flist->files[i])); + F_GROUP(flist->files[i]) = match_gid(F_GID(flist->files[i])); } }