Some uid/gid fixes for (id_t)-1.
authorWayne Davison <wayned@samba.org>
Tue, 22 Feb 2011 18:48:13 +0000 (10:48 -0800)
committerWayne Davison <wayned@samba.org>
Tue, 22 Feb 2011 18:48:13 +0000 (10:48 -0800)
The code now avoids any special internal meaning for gid -1.  If chown()
is called with a uid or gid of -1, complain that the ID is not settable
and signal a transfer error.

rsync.c
uidlist.c

diff --git a/rsync.c b/rsync.c
index bb58fc9dc26fca6e26d1d0968bc8b899d7ef43c2..143eb38f02a264cf36052bcda17f688e2fa53f70 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -463,9 +463,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                        }
                }
                if (am_root >= 0) {
-                       if (do_lchown(fname,
-                           change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid,
-                           change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid) != 0) {
+                       uid_t uid = change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid;
+                       gid_t gid = change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid;
+                       if (do_lchown(fname, uid, gid) != 0) {
                                /* We shouldn't have attempted to change uid
                                 * or gid unless have the privilege. */
                                rsyserr(FERROR_XFER, errno, "%s %s failed",
@@ -473,6 +473,10 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
                                    full_fname(fname));
                                goto cleanup;
                        }
+                       if (uid == (uid_t)-1 && sxp->st.st_uid != (uid_t)-1)
+                               rprintf(FERROR_XFER, "uid 4294967295 (-1) is impossible to set on %s\n", full_fname(fname));
+                       if (gid == (gid_t)-1 && sxp->st.st_gid != (gid_t)-1)
+                               rprintf(FERROR_XFER, "gid 4294967295 (-1) is impossible to set on %s\n", full_fname(fname));
                        /* A lchown had been done, so we need to re-stat if
                         * the destination had the setuid or setgid bits set
                         * (due to the side effect of the chown call). */
index dd26a559242eac18d4196a163104937c94b95a2c..e43ae5c435d63811c50390b8a155b70e05d2e9bb 100644 (file)
--- a/uidlist.c
+++ b/uidlist.c
@@ -39,8 +39,6 @@ extern int numeric_ids;
 # endif
 #endif
 
-#define GID_NONE ((gid_t)-1)
-
 struct idlist {
        struct idlist *next;
        const char *name;
@@ -103,12 +101,12 @@ static gid_t map_gid(gid_t id, const char *name)
 static int is_in_group(gid_t gid)
 {
 #ifdef HAVE_GETGROUPS
-       static gid_t last_in = GID_NONE, last_out;
-       static int ngroups = -2;
+       static gid_t last_in;
+       static int ngroups = -2, last_out = -1;
        static GETGROUPS_T *gidset;
        int n;
 
-       if (gid == last_in)
+       if (gid == last_in && last_out >= 0)
                return last_out;
        if (ngroups < -1) {
                gid_t mygid = MY_GID();