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:
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.
/* 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++) {
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";
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;
}
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;
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
}
}
- 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;
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
}
#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
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)