+ *pass++ = '\0';
+
+ if (!(users = strdup(users)))
+ out_of_memory("auth_server");
+
+ for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
+ char *opts;
+ /* See if the user appended :deny, :ro, or :rw. */
+ if ((opts = strchr(tok, ':')) != NULL) {
+ *opts++ = '\0';
+ opt_ch = isUpper(opts) ? toLower(opts) : *opts;
+ if (opt_ch == 'r') { /* handle ro and rw */
+ opt_ch = isUpper(opts+1) ? toLower(opts+1) : opts[1];
+ if (opt_ch == 'o')
+ opt_ch = 'r';
+ else if (opt_ch != 'w')
+ opt_ch = '\0';
+ } else if (opt_ch != 'd') /* if it's not deny, ignore it */
+ opt_ch = '\0';
+ } else
+ opt_ch = '\0';
+ if (*tok != '@') {
+ /* Match the username */
+ if (wildmatch(tok, line))
+ break;
+ } else {
+#ifdef HAVE_GETGROUPLIST
+ int j;
+ /* 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];
+ 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)
+ auth_uid_groups_cnt = 0;
+ else {
+ 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]);
+ }
+ }
+ for (j = 0; j < auth_uid_groups_cnt; j++) {
+ if (auth_uid_groups[j] && wildmatch(tok+1, auth_uid_groups[j])) {
+ group_match = j;
+ break;
+ }
+ }
+ if (group_match >= 0)
+ break;
+#else
+ rprintf(FLOG, "your computer doesn't support getgrouplist(), so no @group authorization is possible.\n");
+#endif
+ }
+ }