From: Andre Noll Date: Thu, 6 Nov 2008 23:09:50 +0000 (+0100) Subject: Add new select option to specify users by name. X-Git-Tag: v0.0.5~3^2 X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=commitdiff_plain;h=31c4b3e03cdf8412e54d3577cde394f112d1e771;hp=4113e8c585d3da46bfa5326b866621cff854a737 Add new select option to specify users by name. This patch renames the short option -u for --uid to -U and introduces the new --user option (short: -u) to specify admissible users by name. The new option may be given mutltiple times to allow more than one user. --- diff --git a/select.c b/select.c index 46b5372..e66b2dd 100644 --- a/select.c +++ b/select.c @@ -657,7 +657,7 @@ static int setup_format_string(char *fmt, struct format_info **fi) 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; @@ -678,6 +678,11 @@ int parse_select_options(char *string, struct select_cmdline_parser_params *para 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); diff --git a/select.ggo b/select.ggo index a93007a..5ea4e8e 100644 --- a/select.ggo +++ b/select.ggo @@ -1,11 +1,22 @@ +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: @@ -19,6 +30,9 @@ details=" 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 diff --git a/user.c b/user.c index 233764f..1f7e04a 100644 --- a/user.c +++ b/user.c @@ -169,6 +169,54 @@ int parse_uid_arg(const char *orig_arg, struct uid_range **ur) 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) { @@ -304,23 +352,6 @@ static uint32_t double_hash(uint32_t uid, uint32_t probe_num) % 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) { diff --git a/user.h b/user.h index 3eefab1..0eba5bb 100644 --- a/user.h +++ b/user.h @@ -50,4 +50,6 @@ void free_hash_table(void); 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);