Add new select option to specify users by name.
[adu.git] / user.c
diff --git a/user.c b/user.c
index 233764fe40089e387d03b783f01295b180112636..1f7e04a26f32cae30636c21b04a0092a14f2c3de 100644 (file)
--- 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)
 {