diff options
author | Wayne Davison <wayned@samba.org> | 2015-08-24 11:23:31 -0700 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2015-08-24 11:54:00 -0700 |
commit | 2a7355fb5661624c248e6269550429296614b5ae (patch) | |
tree | a07baf7051c1ef8bf76081a27e8f9010f39f277a | |
parent | 3da1dc4d188b108933240dcac72121985e3fea88 (diff) | |
download | android_external_rsync-2a7355fb5661624c248e6269550429296614b5ae.tar.gz android_external_rsync-2a7355fb5661624c248e6269550429296614b5ae.tar.bz2 android_external_rsync-2a7355fb5661624c248e6269550429296614b5ae.zip |
Change daemon's gid list to use an "item_list".
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | authenticate.c | 9 | ||||
-rw-r--r-- | clientserver.c | 32 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | uidlist.c | 42 | ||||
-rw-r--r-- | util.c | 2 |
6 files changed, 54 insertions, 41 deletions
@@ -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 @@ -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 @@ -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) |