X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/5b540e86a46ab0641cd7cc7bdd4fe6eb3b7a9f36..65fc84b32e2a558cca3a66587ac4cd06e16f1471:/uidlist.c diff --git a/uidlist.c b/uidlist.c index 02d551d0..38c265b3 100644 --- a/uidlist.c +++ b/uidlist.c @@ -25,6 +25,13 @@ #include "rsync.h" +#ifdef GETGROUPS_T +# ifndef NGROUPS_MAX +/* It ought to be defined, but just in case. */ +# define NGROUPS_MAX 32 +# endif +#endif + extern int preserve_uid; extern int preserve_gid; extern int numeric_ids; @@ -71,7 +78,7 @@ static char *gid_to_name(gid_t gid) static int map_uid(int id, char *name) { uid_t uid; - if (name_to_uid(name, &uid) && uid != 0) + if (uid != 0 && name_to_uid(name, &uid)) return uid; return id; } @@ -79,7 +86,7 @@ static int map_uid(int id, char *name) static int map_gid(int id, char *name) { gid_t gid; - if (name_to_gid(name, &gid) && gid != 0) + if (gid != 0 && name_to_gid(name, &gid)) return gid; return id; } @@ -117,12 +124,21 @@ static int is_in_group(gid_t gid) if (gid == last_in) return last_out; if (ngroups < -1) { - /* treat failure (-1) as if not member of any group */ + gid_t mygid = getgid(); ngroups = getgroups(0, 0); - if (ngroups > 0) { - gidset = new_array(GETGROUPS_T, ngroups); + /* If that didn't work, perhaps 0 isn't treated specially? */ + if (ngroups < 0) + ngroups = NGROUPS_MAX; + gidset = new_array(GETGROUPS_T, ngroups+1); + if (ngroups > 0) ngroups = getgroups(ngroups, gidset); + /* The default gid might not be in the list on some systems. */ + for (n = 0; n < ngroups; n++) { + if (gidset[n] == mygid) + break; } + if (n == ngroups) + gidset[ngroups++] = mygid; } last_in = gid; @@ -142,7 +158,7 @@ static int is_in_group(gid_t gid) static gid_t match_gid(gid_t gid) { - static gid_t last_in, last_out; + static gid_t last_in = (gid_t) -2, last_out; struct idlist *list = gidlist; if (gid == last_in) return last_out; @@ -160,7 +176,7 @@ static gid_t match_gid(gid_t gid) if (am_root) last_out = gid; else - last_out = (gid_t)-1; + last_out = GID_NONE; return last_out; } @@ -307,7 +323,7 @@ void recv_uid_list(int f, struct file_list *flist) } list->id2 = map_gid(id, name); if (!am_root && !is_in_group(list->id2)) - list->id2 = (gid_t)-1; + list->id2 = GID_NONE; free(name); } } @@ -316,12 +332,10 @@ void recv_uid_list(int f, struct file_list *flist) /* now convert the uid/gid of all files in the list to the mapped uid/gid */ - for (i=0;icount;i++) { - if (am_root && preserve_uid && flist->files[i]->uid != 0) { + for (i = 0; i < flist->count; i++) { + if (am_root && preserve_uid && flist->files[i]->uid != 0) flist->files[i]->uid = match_uid(flist->files[i]->uid); - } - if (preserve_gid && flist->files[i]->gid != 0) { + if (preserve_gid && (!am_root || flist->files[i]->gid != 0)) flist->files[i]->gid = match_gid(flist->files[i]->gid); - } } }