X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/72fc7ec59bd5c4c34214cf911a27f16b6749679a..ade7292aeea55eb7e9d59fe36cdba85ae020782f:/uidlist.c diff --git a/uidlist.c b/uidlist.c index 896e16ca..27e7046e 100644 --- a/uidlist.c +++ b/uidlist.c @@ -1,17 +1,17 @@ -/* +/* Copyright (C) Andrew Tridgell 1996 Copyright (C) Paul Mackerras 1996 - + 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. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -25,13 +25,17 @@ #include "rsync.h" -#ifdef GETGROUPS_T +#ifdef HAVE_GETGROUPS +# if !defined(GETGROUPS_T) +# define GETGROUPS_T gid_t +# endif # ifndef NGROUPS_MAX /* It ought to be defined, but just in case. */ # define NGROUPS_MAX 32 # endif #endif +extern int verbose; extern int preserve_uid; extern int preserve_gid; extern int numeric_ids; @@ -91,32 +95,10 @@ static int map_gid(int id, char *name) return id; } -/* this function is a definate candidate for a faster algorithm */ -static uid_t match_uid(uid_t uid) -{ - static uid_t last_in, last_out; - struct idlist *list = uidlist; - - if (uid == last_in) return last_out; - - last_in = uid; - - while (list) { - if (list->id == (int)uid) { - last_out = (uid_t)list->id2; - return last_out; - } - list = list->next; - } - - last_out = uid; - return last_out; -} - static int is_in_group(gid_t gid) { -#ifdef GETGROUPS_T - static gid_t last_in = (gid_t) -2, last_out; +#ifdef HAVE_GETGROUPS + static gid_t last_in = GID_NONE, last_out; static int ngroups = -2; static GETGROUPS_T *gidset; int n; @@ -124,11 +106,9 @@ static int is_in_group(gid_t gid) if (gid == last_in) return last_out; if (ngroups < -1) { - gid_t mygid = getgid(); - ngroups = getgroups(0, 0); - /* If that didn't work, perhaps 0 isn't treated specially? */ - if (ngroups < 0) - ngroups = NGROUPS_MAX; + gid_t mygid = MY_GID(); + if ((ngroups = getgroups(0, 0)) < 0) + ngroups = 0; gidset = new_array(GETGROUPS_T, ngroups+1); if (ngroups > 0) ngroups = getgroups(ngroups, gidset); @@ -139,29 +119,68 @@ static int is_in_group(gid_t gid) } if (n == ngroups) gidset[ngroups++] = mygid; + if (verbose > 3) { + char gidbuf[NGROUPS_MAX*16+32]; + int pos; + sprintf(gidbuf, "process has %d gid%s: ", + ngroups, ngroups == 1? "" : "s"); + pos = strlen(gidbuf); + for (n = 0; n < ngroups; n++) { + sprintf(gidbuf+pos, " %ld", (long)gidset[n]); + pos += strlen(gidbuf+pos); + } + rprintf(FINFO, "%s\n", gidbuf); + } } last_in = gid; - last_out = 0; for (n = 0; n < ngroups; n++) { - if (gidset[n] == gid) { - last_out = 1; - break; - } + if (gidset[n] == gid) + return last_out = 1; } - return last_out; + return last_out = 0; #else - return 0; + static gid_t mygid = GID_NONE; + if (mygid == GID_NONE) { + mygid = MY_GID(); + if (verbose > 3) + rprintf(FINFO, "process has gid %ld\n", (long)mygid); + } + return gid == mygid; #endif } +/* this function is a definate candidate for a faster algorithm */ +static uid_t match_uid(uid_t uid) +{ + static uid_t last_in, last_out; + struct idlist *list = uidlist; + + if (uid == last_in) + return last_out; + + last_in = uid; + + while (list) { + if (list->id == (int)uid) { + last_out = (uid_t)list->id2; + return last_out; + } + list = list->next; + } + + last_out = uid; + return last_out; +} + static gid_t match_gid(gid_t gid) { - static gid_t last_in, last_out; + static gid_t last_in = GID_NONE, last_out = GID_NONE; struct idlist *list = gidlist; - if (gid == last_in) return last_out; + if (gid == last_in) + return last_out; last_in = gid; @@ -173,7 +192,7 @@ static gid_t match_gid(gid_t gid) list = list->next; } - if (am_root) + if (am_root || is_in_group(gid)) last_out = gid; else last_out = GID_NONE; @@ -258,7 +277,7 @@ void send_uid_list(int f) } /* terminate the uid list with a 0 uid. We explicitly exclude - 0 from the list */ + * 0 from the list */ write_int(f, 0); } @@ -276,7 +295,7 @@ void send_uid_list(int f) } /* recv a complete uid/gid mapping from the peer and map the uid/gid - in the file list to local names */ + * in the file list to local names */ void recv_uid_list(int f, struct file_list *flist) { int id, i; @@ -303,6 +322,13 @@ void recv_uid_list(int f, struct file_list *flist) list->id2 = map_uid(id, name); free(name); } + if (verbose > 3) { + for (list = uidlist; list; list = list->next) { + rprintf(FINFO, "uid %ld (%s) maps to %ld\n", + (long)list->id, list->name, + (long)list->id2); + } + } } @@ -326,12 +352,19 @@ void recv_uid_list(int f, struct file_list *flist) list->id2 = GID_NONE; free(name); } + if (verbose > 3) { + for (list = gidlist; list; list = list->next) { + rprintf(FINFO, "gid %ld (%s) maps to %ld\n", + (long)list->id, list->name, + (long)list->id2); + } + } } if (!(am_root && preserve_uid) && !preserve_gid) return; /* now convert the uid/gid of all files in the list to the mapped - uid/gid */ + * uid/gid */ 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);