Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/find_new_sub_gids.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
*
* Return 0 on success, -1 if no unused GIDs are available.
*/
int find_new_sub_gids (gid_t *range_start, unsigned long *range_count)
int find_new_sub_gids (id_t *range_start, unsigned long *range_count)
{
unsigned long min, max;
unsigned long count;
gid_t start;
id_t start;

assert (range_start != NULL);
assert (range_count != NULL);
Expand All @@ -47,7 +47,7 @@ int find_new_sub_gids (gid_t *range_start, unsigned long *range_count)
}

start = sub_gid_find_free_range(min, max, count);
if (start == (gid_t)-1) {
if (start == (id_t)-1) {
fprintf (log_get_logfd(),
_("%s: Can't get unique subordinate GID range\n"),
log_get_progname());
Expand Down
6 changes: 3 additions & 3 deletions lib/find_new_sub_uids.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
*
* Return 0 on success, -1 if no unused UIDs are available.
*/
int find_new_sub_uids (uid_t *range_start, unsigned long *range_count)
int find_new_sub_uids (id_t *range_start, unsigned long *range_count)
{
unsigned long min, max;
unsigned long count;
uid_t start;
id_t start;

assert (range_start != NULL);
assert (range_count != NULL);
Expand All @@ -47,7 +47,7 @@ int find_new_sub_uids (uid_t *range_start, unsigned long *range_count)
}

start = sub_uid_find_free_range(min, max, count);
if (start == (uid_t)-1) {
if (start == (id_t)-1) {
fprintf (log_get_logfd(),
_("%s: Can't get unique subordinate UID range\n"),
log_get_progname());
Expand Down
4 changes: 2 additions & 2 deletions lib/prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ extern int find_new_uid (bool sys_user,

#ifdef ENABLE_SUBIDS
/* find_new_sub_gids.c */
extern int find_new_sub_gids (gid_t *range_start, unsigned long *range_count);
extern int find_new_sub_gids (id_t *range_start, unsigned long *range_count);

/* find_new_sub_uids.c */
extern int find_new_sub_uids (uid_t *range_start, unsigned long *range_count);
extern int find_new_sub_uids (id_t *range_start, unsigned long *range_count);
#endif /* ENABLE_SUBIDS */

/* getgr_nam_gid.c */
Expand Down
13 changes: 13 additions & 0 deletions man/usermod.8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,19 @@
</para>
</listitem>
</varlistentry>
<varlistentry condition="subids">
<term>
<option>-S</option>, <option>--add-subids</option>
</term>
<listitem>
<para>
Add subordinate uids and gids to the user's account.
</para>
<para>
An appropriate uid and gid range is automatically selected from /etc/login.defs defaults.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-Z</option>, <option>--selinux-user</option>&nbsp;<replaceable>SEUSER</replaceable>
Expand Down
52 changes: 51 additions & 1 deletion src/usermod.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static bool
Vflg = false, /* delete subordinate uids */
wflg = false, /* add subordinate gids */
Wflg = false, /* delete subordinate gids */
Sflg = false, /* auto add subordinate ids */
#endif /* ENABLE_SUBIDS */
uflg = false, /* specify new user ID */
Uflg = false; /* unlock the password */
Expand Down Expand Up @@ -375,6 +376,32 @@ prepend_range(const char *str, struct id_range_list_entry **head)
*head = entry;
return 1;
}

static int
find_range(struct id_range_list_entry **head,
int (*find_fn)(id_t *range_start, unsigned long *range_count))
{
struct id_range_list_entry *entry;
struct id_range range;
unsigned long count;

if (find_fn(&range.first, &count) != 0)
return 0;

range.last = range.first + count;

entry = malloc_T(1, struct id_range_list_entry);
if (entry == NULL) {
fprintf(stderr, "%s: malloc: %s\n", Prog, strerrno());
return 0;
}

entry->next = *head;
entry->range = range;
*head = entry;

return 1;
}
#endif /* ENABLE_SUBIDS */

/*
Expand Down Expand Up @@ -421,6 +448,7 @@ usage (int status)
(void) fputs (_(" -V, --del-subuids FIRST-LAST remove range of subordinate uids\n"), usageout);
(void) fputs (_(" -w, --add-subgids FIRST-LAST add range of subordinate gids\n"), usageout);
(void) fputs (_(" -W, --del-subgids FIRST-LAST remove range of subordinate gids\n"), usageout);
(void) fputs (_(" -S, --add-subids add entries to sub[ud]id based on system defaults\n"), usageout);
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
(void) fputs (_(" -Z, --selinux-user SEUSER new SELinux user mapping for the user account\n"), usageout);
Expand Down Expand Up @@ -1038,6 +1066,7 @@ process_flags(int argc, char **argv, struct option_flags *flags)
{"del-subuids", required_argument, NULL, 'V'},
{"add-subgids", required_argument, NULL, 'w'},
{"del-subgids", required_argument, NULL, 'W'},
{"add-subids", no_argument, NULL, 'S'},
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
{"selinux-user", required_argument, NULL, 'Z'},
Expand All @@ -1048,7 +1077,7 @@ process_flags(int argc, char **argv, struct option_flags *flags)
while ((c = getopt_long (argc, argv,
"abc:d:e:f:g:G:hl:Lmop:rR:s:u:UP:"
#ifdef ENABLE_SUBIDS
"v:w:V:W:"
"v:w:V:W:S"
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
"Z:"
Expand Down Expand Up @@ -1245,6 +1274,12 @@ process_flags(int argc, char **argv, struct option_flags *flags)
}
Wflg = true;
break;
case 'S':
Sflg = true;
/* -S implies vflg and wflg */
vflg = true;
wflg = true;
break;
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
case 'Z':
Expand Down Expand Up @@ -2234,6 +2269,21 @@ int main (int argc, char **argv)
grp_update (process_selinux);
}
#ifdef ENABLE_SUBIDS
if (Sflg) {
if (find_range (&add_sub_uids, find_new_sub_uids) == 0) {
fprintf (stderr,
_("%s: unable to find new subordinate uid range\n"),
Prog);
fail_exit (E_SUB_UID_UPDATE, process_selinux);
}
if (find_range (&add_sub_gids, find_new_sub_gids) == 0) {
fprintf (stderr,
_("%s: unable to find new subordinate gid range\n"),
Prog);
fail_exit (E_SUB_GID_UPDATE, process_selinux);
}
}

if (Vflg) {
struct id_range_list_entry *ptr;

Expand Down
Loading