summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2015-08-24 11:23:31 -0700
committerWayne Davison <wayned@samba.org>2015-08-24 11:54:00 -0700
commit2a7355fb5661624c248e6269550429296614b5ae (patch)
treea07baf7051c1ef8bf76081a27e8f9010f39f277a
parent3da1dc4d188b108933240dcac72121985e3fea88 (diff)
downloadrsync-2a7355fb5661624c248e6269550429296614b5ae.tar.gz
Change daemon's gid list to use an "item_list".
-rw-r--r--NEWS2
-rw-r--r--authenticate.c9
-rw-r--r--clientserver.c32
-rw-r--r--configure.ac8
-rw-r--r--uidlist.c42
-rw-r--r--util.c2
6 files changed, 54 insertions, 41 deletions
diff --git a/NEWS b/NEWS
index 9a3ddd57..3fe3d3e3 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ Changes since 3.1.1:
right.
- Don't create an empty backup dir for a transferred file that doesn't
exist yet.
+ - Allow more than 32 group IDs per user in the daemon's gid=LIST config.
ENHANCEMENTS:
@@ -31,7 +32,6 @@ Changes since 3.1.1:
DEVELOPER RELATED:
- - Added --with-max-daemon-gid=NUM option to configure.
- Fixed a bug with the Makefile's use of INSTALL_STRIP.
- Improve a test in the suite that could get an erroneous timestamp error.
- Tweaks for newer versions of git in the packaging tools.
diff --git a/authenticate.c b/authenticate.c
index fe1e8390..5f125dea 100644
--- a/authenticate.c
+++ b/authenticate.c
@@ -279,17 +279,18 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
/* See if authorizing user is a real user, and if so, see
* if it is in a group that matches tok+1 wildmat. */
if (auth_uid_groups_cnt < 0) {
- gid_t gid_list[64];
+ item_list gid_list = EMPTY_ITEM_LIST;
uid_t auth_uid;
- auth_uid_groups_cnt = sizeof gid_list / sizeof (gid_t);
if (!user_to_uid(line, &auth_uid, False)
- || getallgroups(auth_uid, gid_list, &auth_uid_groups_cnt) != NULL)
+ || getallgroups(auth_uid, &gid_list) != NULL)
auth_uid_groups_cnt = 0;
else {
+ gid_t *gid_array = gid_list.items;
+ auth_uid_groups_cnt = gid_list.count;
if ((auth_uid_groups = new_array(char *, auth_uid_groups_cnt)) == NULL)
out_of_memory("auth_server");
for (j = 0; j < auth_uid_groups_cnt; j++)
- auth_uid_groups[j] = gid_to_group(gid_list[j]);
+ auth_uid_groups[j] = gid_to_group(gid_array[j]);
}
}
for (j = 0; j < auth_uid_groups_cnt; j++) {
diff --git a/clientserver.c b/clientserver.c
index cf602a17..27f8cd38 100644
--- a/clientserver.c
+++ b/clientserver.c
@@ -79,8 +79,7 @@ static int rl_nulls = 0;
static struct sigaction sigact;
#endif
-static gid_t gid_list[MAX_DAEMON_GID_LIST];
-static int gid_count = 0;
+static item_list gid_list = EMPTY_ITEM_LIST;
/* Used when "reverse lookup" is off. */
const char undetermined_hostname[] = "UNDETERMINED";
@@ -436,18 +435,14 @@ static int path_failure(int f_out, const char *dir, BOOL was_chdir)
static int add_a_group(int f_out, const char *gname)
{
- gid_t gid;
+ gid_t gid, *gid_p;
if (!group_to_gid(gname, &gid, True)) {
rprintf(FLOG, "Invalid gid %s\n", gname);
io_printf(f_out, "@ERROR: invalid gid %s\n", gname);
return -1;
}
- if (gid_count == MAX_DAEMON_GID_LIST) {
- rprintf(FLOG, "Too many groups specified via gid parameter.\n");
- io_printf(f_out, "@ERROR: too many groups\n");
- return -1;
- }
- gid_list[gid_count++] = gid;
+ gid_p = EXPAND_ITEM_LIST(&gid_list, gid_t, -32);
+ *gid_p = gid;
return 0;
}
@@ -455,8 +450,7 @@ static int add_a_group(int f_out, const char *gname)
static int want_all_groups(int f_out, uid_t uid)
{
const char *err;
- gid_count = MAX_DAEMON_GID_LIST;
- if ((err = getallgroups(uid, gid_list, &gid_count)) != NULL) {
+ if ((err = getallgroups(uid, &gid_list)) != NULL) {
rsyserr(FLOG, errno, "%s", err);
io_printf(f_out, "@ERROR: %s\n", err);
return -1;
@@ -467,14 +461,15 @@ static int want_all_groups(int f_out, uid_t uid)
static struct passwd *want_all_groups(int f_out, uid_t uid)
{
struct passwd *pw;
+ gid_t *gid_p;
if ((pw = getpwuid(uid)) == NULL) {
rsyserr(FLOG, errno, "getpwuid failed");
io_printf(f_out, "@ERROR: getpwuid failed\n");
return NULL;
}
- /* Start with the default group and initgroups() will add the reset. */
- gid_count = 1;
- gid_list[0] = pw->pw_gid;
+ /* Start with the default group and initgroups() will add the rest. */
+ gid_p = EXPAND_ITEM_LIST(&gid_list, gid_t, -32);
+ *gid_p = pw->pw_gid;
return pw;
}
#endif
@@ -816,15 +811,16 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
}
}
- if (gid_count) {
- if (setgid(gid_list[0])) {
- rsyserr(FLOG, errno, "setgid %ld failed", (long)gid_list[0]);
+ if (gid_list.count) {
+ gid_t *gid_array = gid_list.items;
+ if (setgid(gid_array[0])) {
+ rsyserr(FLOG, errno, "setgid %ld failed", (long)gid_array[0]);
io_printf(f_out, "@ERROR: setgid failed\n");
return -1;
}
#ifdef HAVE_SETGROUPS
/* Set the group(s) we want to be active. */
- if (setgroups(gid_count, gid_list)) {
+ if (setgroups(gid_list.count, gid_array)) {
rsyserr(FLOG, errno, "setgroups failed");
io_printf(f_out, "@ERROR: setgroups failed\n");
return -1;
diff --git a/configure.ac b/configure.ac
index 89753667..3aca2a10 100644
--- a/configure.ac
+++ b/configure.ac
@@ -98,14 +98,6 @@ AC_ARG_WITH(rsync-path,
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
-AC_ARG_WITH(max-daemon-gid,
- AS_HELP_STRING([--with-max-daemon-gid=NUM],
- [set maximum number of GIDs in the daemon "gid=LIST" config item (default: 32)]),
- [ MAX_DAEMON_GID_LIST=$with_max_daemon_gid ],
- [ MAX_DAEMON_GID_LIST=32 ])
-
-AC_DEFINE_UNQUOTED(MAX_DAEMON_GID_LIST, $MAX_DAEMON_GID_LIST, [maximum GIDs in a daemon module gid list])
-
AC_ARG_WITH(rsyncd-conf,
AS_HELP_STRING([--with-rsyncd-conf=PATH],[set configuration file for rsync server to PATH (default: /etc/rsyncd.conf)]),
[ if test ! -z "$with_rsyncd_conf" ; then
diff --git a/uidlist.c b/uidlist.c
index 879eeebd..1ccdd644 100644
--- a/uidlist.c
+++ b/uidlist.c
@@ -524,25 +524,49 @@ void parse_name_map(char *map, BOOL usernames)
}
#ifdef HAVE_GETGROUPLIST
-const char *getallgroups(uid_t uid, gid_t *gid_list, int *size_ptr)
+const char *getallgroups(uid_t uid, item_list *gid_list)
{
struct passwd *pw;
+ gid_t *gid_array;
+ int size;
+
if ((pw = getpwuid(uid)) == NULL)
return "getpwuid failed";
+
+ gid_list->count = 0; /* We're overwriting any items in the list */
+ EXPAND_ITEM_LIST(gid_list, gid_t, 32);
+ size = gid_list->malloced;
+
/* Get all the process's groups, with the pw_gid group first. */
- if (getgrouplist(pw->pw_name, pw->pw_gid, gid_list, size_ptr) < 0)
- return "getgrouplist failed";
+ if (getgrouplist(pw->pw_name, pw->pw_gid, gid_list->items, &size) < 0) {
+ if (size > (int)gid_list->malloced) {
+ gid_list->count = gid_list->malloced;
+ EXPAND_ITEM_LIST(gid_list, gid_t, size);
+ if (getgrouplist(pw->pw_name, pw->pw_gid, gid_list->items, &size) < 0)
+ size = -1;
+ } else
+ size = -1;
+ if (size < 0)
+ return "getgrouplist failed";
+ }
+ gid_list->count = size;
+ gid_array = gid_list->items;
+
/* Paranoia: is the default group not first in the list? */
- if (gid_list[0] != pw->pw_gid) {
+ if (gid_array[0] != pw->pw_gid) {
int j;
- for (j = 0; j < *size_ptr; j++) {
- if (gid_list[j] == pw->pw_gid) {
- gid_list[j] = gid_list[0];
- gid_list[0] = pw->pw_gid;
+ for (j = 1; j < size; j++) {
+ if (gid_array[j] == pw->pw_gid)
break;
- }
}
+ if (j == size) { /* The default group wasn't found! */
+ EXPAND_ITEM_LIST(gid_list, gid_t, size+1);
+ gid_array = gid_list->items;
+ }
+ gid_array[j] = gid_array[0];
+ gid_array[0] = pw->pw_gid;
}
+
return NULL;
}
#endif
diff --git a/util.c b/util.c
index c0e239d4..41e0c780 100644
--- a/util.c
+++ b/util.c
@@ -1615,7 +1615,7 @@ void *expand_item_list(item_list *lp, size_t item_size,
if (incr < 0)
new_size += -incr; /* increase slowly */
else if (new_size < (size_t)incr)
- new_size += incr;
+ new_size = incr;
else
new_size *= 2;
if (new_size < lp->malloced)