On Thu, 2009-02-12 at 21:23 -0800, Harry Mangalam wrote:
> I've created a special user to backup a server which has some users 
> who don't want all their files backed up, so I'm trying to address 
> their concerns by using the uid= and gid= lines in rsyncd.conf to 
> have the rsyncd run with 'uid=backuppc' and 'gid=backuppc' privs, set 
> in the global section.  Then I add backuppc to the appropriate group 
> in /etc/group as below.
> 
> In this way, rsync will have read permissions only for those users who 
> have made their files g+rX and who have agreed to have the backuppc 
> user added to their group in /etc/group.
> 
> ie 'minas' is a user who has his /home/dir set as 
> drwxr-x--- 39 minas minas 4096 2009-02-06 23:01 /home/minas
> 
> I've tried to have address this by setting his /etc/group line as:
> 
> minas:x:1000:backuppc
> 
> expecting that since 'backuppc' is now a member of the 'minas' group, 
> rsync running with 'backuppc' privs can read the files 'minas' user 
> allows the 'minas' group to read.  This change allows the 'backuppc' 
> user to read those files from the shell.
> 
> However, this does not work for the backup (rsyncd refuses to read the 
> files with an entry in /var/log/rsyncd.log:

On Fri, 2009-02-13 at 09:21 -0800, Harry Mangalam wrote:
> 2009/02/13 09:06:28 [9818] rsync: link_stat "." (in minas) failed: 
> Permission denied (13)

The problem is that the daemon takes on only the specified uid and gid,
not the supplementary groups of the uid.  The attached patch (also in
wip/supplementary-groups of my repository) adds a daemon parameter to
take on the supplementary groups.  Please test this and tell us whether
it works for you.

-- 
Matt
>From 1175c760bc7408a28b831e18db5d2e4fae78c0fa Mon Sep 17 00:00:00 2001
From: Matt McCutchen <m...@mattmccutchen.net>
Date: Sat, 14 Feb 2009 20:49:56 -0500
Subject: [PATCH] Add "supplementary groups" daemon parameter to take on the supplementary
 groups of the specified "uid" as well as the specified "gid".
To: rsync-patc...@mattmccutchen.net

---
 clientserver.c |   11 ++++++++++-
 configure.in   |    2 +-
 loadparm.c     |    6 ++++++
 rsyncd.conf.yo |    5 +++++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/clientserver.c b/clientserver.c
index 059be75..4e6e661 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -413,6 +413,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
 	int argc;
 	char **argv, **orig_argv, **orig_early_argv, *module_chdir;
 	char line[BIGPATHBUFLEN];
+	char *uname = NULL;
 	uid_t uid = (uid_t)-2;  /* canonically "nobody" */
 	gid_t gid = (gid_t)-2;
 	char *p, *err_msg = NULL;
@@ -489,7 +490,7 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
 	am_root = (MY_UID() == 0);
 
 	if (am_root) {
-		p = lp_uid(i);
+		uname = p = lp_uid(i);
 		if (!name_to_uid(p, &uid)) {
 			if (!isDigit(p)) {
 				rprintf(FLOG, "Invalid uid %s\n", p);
@@ -730,6 +731,14 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
 			return -1;
 		}
 #endif
+#ifdef HAVE_INITGROUPS
+		if (lp_supplementary_groups(i) && uname != NULL
+			&& initgroups(uname, gid)) {
+			rsyserr(FLOG, errno, "initgroups failed");
+			io_printf(f_out, "@ERROR: initgroups failed\n");
+			return -1;
+		}
+#endif
 
 		if (setuid(uid)) {
 			rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
diff --git a/configure.in b/configure.in
index d03bc4e..75fc037 100644
--- a/configure.in
+++ b/configure.in
@@ -549,7 +549,7 @@ AC_FUNC_ALLOCA
 AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
     fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
     memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
-    strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
+    strlcat strlcpy strtol mallinfo getgroups setgroups initgroups geteuid getegid \
     setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
     strerror putenv iconv_open locale_charset nl_langinfo getxattr \
     extattr_get_link sigaction sigprocmask setattrlist)
diff --git a/loadparm.c b/loadparm.c
index e8759ad..da2c91c 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -146,6 +146,7 @@ typedef struct {
 	BOOL read_only;
 	BOOL reverse_lookup;
 	BOOL strict_modes;
+	BOOL supplementary_groups;
 	BOOL transfer_logging;
 	BOOL use_chroot;
 	BOOL write_only;
@@ -218,6 +219,7 @@ static const all_vars Defaults = {
  /* read_only; */		True,
  /* reverse_lookup; */		True,
  /* strict_modes; */		True,
+ /* supplementary_groups; */	False,
  /* transfer_logging; */	False,
  /* use_chroot; */		True,
  /* write_only; */		False,
@@ -349,6 +351,9 @@ static struct parm_struct parm_table[] =
  {"reverse lookup",    P_BOOL,   P_LOCAL, &Vars.l.reverse_lookup,      NULL,0},
  {"secrets file",      P_STRING, P_LOCAL, &Vars.l.secrets_file,        NULL,0},
  {"strict modes",      P_BOOL,   P_LOCAL, &Vars.l.strict_modes,        NULL,0},
+#ifdef HAVE_INITGROUPS
+ {"supplementary groups",P_BOOL, P_LOCAL, &Vars.l.supplementary_groups,NULL,0},
+#endif
  {"syslog facility",   P_ENUM,   P_LOCAL, &Vars.l.syslog_facility,     enum_facilities,0},
  {"temp dir",          P_PATH,   P_LOCAL, &Vars.l.temp_dir,            NULL,0},
  {"timeout",           P_INTEGER,P_LOCAL, &Vars.l.timeout,             NULL,0},
@@ -433,6 +438,7 @@ FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
 FN_LOCAL_BOOL(lp_read_only, read_only)
 FN_LOCAL_BOOL(lp_reverse_lookup, reverse_lookup)
 FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
+FN_LOCAL_BOOL(lp_supplementary_groups, supplementary_groups)
 FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
 FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
 FN_LOCAL_BOOL(lp_write_only, write_only)
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
index 992b7ce..f5767f3 100644
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -324,6 +324,11 @@ file transfers to and from that module should take place as when the daemon
 was run as root. This complements the "uid" parameter. The default is gid -2,
 which is normally the group "nobody".
 
+dit(bf(supplementary groups)) If enabled, the daemon will take on the
+supplementary groups of the specified "uid" in addition to the specified "gid"
+when performing transfers to and from the module.  For this to work, "uid"
+should be a name, not a numeric user ID.  The default is false.
+
 dit(bf(fake super)) Setting "fake super = yes" for a module causes the
 daemon side to behave as if the bf(--fake-user) command-line option had
 been specified.  This allows the full attributes of a file to be stored
-- 
1.6.2.rc0.7.g013dd.dirty

-- 
Please use reply-all for most replies to avoid omitting the mailing list.
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to