int parse_select_options(char *string, struct select_cmdline_parser_params *params,
struct uid_range **admissible_uids, struct format_info **fi)
{
- int ret;
+ int ret, num_uid_ranges;
const char **line;
char *fmt = NULL;
fmt = select_conf.format_arg;
}
ret = parse_uid_arg(select_conf.uid_arg, admissible_uids);
+ if (ret < 0)
+ return ret;
+ num_uid_ranges = ret;
+ ret = append_users(select_conf.user_arg, select_conf.user_given,
+ admissible_uids, num_uid_ranges);
if (ret < 0)
return ret;
return setup_format_string(fmt, fi);
+option "user" u
+#~~~~~~~~~~~~~~
+"users to take into account"
+string typestr="user_name"
+optional
+multiple
+details="
+ This option may be given multiple times in which case all given
+ user names are considered admissible. See also --uid below.
+"
-option "uid" u
+option "uid" U
#~~~~~~~~~~~~~
"user id(s) to take into account"
string typestr="uid_spec"
optional
details="
- An uid specifier may be a single number, or a range of uids.
+ An uid specifier may be a single uid, a range of uids,
+ or a comma-separated list of single uids or ranges.
Example:
Only consider uid 42:
Consider uids 23-42, 666-777 and 88:
--uid 23-42,666-777,88
+
+ If no --user option is given and also --uid option is not given
+ (the default), all users are taken into account.
"
option "limit" L
return n;
}
+static int uid_is_admissible(uint32_t uid, struct uid_range *urs)
+{
+ struct uid_range *ur;
+ int ret = 1;
+
+ if (!urs) /* empty array means all uids are allowed */
+ return 1;
+ FOR_EACH_UID_RANGE(ur, urs)
+ if (ur->low <= uid && ur->high >= uid)
+ goto out;
+ ret = 0;
+out:
+ DEBUG_LOG("uid %u is %sadmissible\n", (unsigned)uid,
+ ret? "" : "not ");
+ return ret;
+}
+
+int append_users(char **users, int num_users,
+ struct uid_range **admissible_uids, int num_uid_ranges)
+{
+ int i;
+ struct uid_range *au = *admissible_uids;
+
+ for (i = 0; i < num_users; i++) {
+ char *u = users[i];
+ struct uid_range *ur;
+ struct passwd *pw = getpwnam(u);
+
+ if (!pw) {
+ ERROR_LOG("user %s not found\n", u);
+ return -ERRNO_TO_ERROR(EINVAL);
+ }
+ if (au && uid_is_admissible(pw->pw_uid, au))
+ continue; /* nothing to do */
+ /* add a range consisting of this uid only */
+ num_uid_ranges++;
+ au = adu_realloc(au, (num_uid_ranges + 1) *
+ sizeof(struct uid_range));
+ *admissible_uids = au;
+ ur = au + num_uid_ranges - 1; /* the new uid range */
+ ur->low = ur->high = pw->pw_uid;
+ /* terminate the list */
+ ur++;
+ ur->low = 1;
+ ur->high = 0;
+ }
+ return num_uid_ranges;
+}
static inline int ui_used(struct user_info *ui)
{
% uid_hash_table_size;
}
-static int uid_is_admissible(uint32_t uid, struct uid_range *urs)
-{
- struct uid_range *ur;
- int ret = 1;
-
- if (!urs) /* empty array means all uids are allowed */
- return 1;
- FOR_EACH_UID_RANGE(ur, urs)
- if (ur->low <= uid && ur->high >= uid)
- goto out;
- ret = 0;
-out:
- DEBUG_LOG("uid %u is %sadmissible\n", (unsigned)uid,
- ret? "" : "not ");
- return ret;
-}
-
int search_uid(uint32_t uid, struct uid_range *urs,
enum search_uid_flags flags, struct user_info **ui_ptr)
{
int for_each_admissible_user(int (*func)(struct user_info *, void *),
void *data);
int parse_uid_arg(const char *orig_arg, struct uid_range **ur);
+int append_users(char **users, int num_users,
+ struct uid_range **admissible_uids, int num_uid_ranges);
void close_user_tables(void);