Skip to content

Commit b0c4865

Browse files
committed
Improve the --userspec CLI option and rename it to --user
1 parent e6fa331 commit b0c4865

File tree

3 files changed

+59
-20
lines changed

3 files changed

+59
-20
lines changed

src/cli/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static struct argp usage = {
2828
{NULL, 0, NULL, 0, "Options:", -1},
2929
{"debug", 'd', "FILE", 0, "Log debug information", -1},
3030
{"load-kmods", 'k', NULL, 0, "Load kernel modules", -1},
31-
{"userspec", 'u', "UID:GID", OPTION_ARG_OPTIONAL, "User and group to use for privilege separation", -1},
31+
{"user", 'u', "UID[:GID]", OPTION_ARG_OPTIONAL, "User and group to use for privilege separation", -1},
3232
{NULL, 0, NULL, 0, "Commands:", 0},
3333
{"list", 0, NULL, OPTION_DOC|OPTION_NO_USAGE, "List host driver components", 0},
3434
{"configure", 0, NULL, OPTION_DOC|OPTION_NO_USAGE, "Configure a container with GPU support", 0},

src/utils.c

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <libgen.h>
2121
#undef basename /* Use the GNU version of basename. */
2222
#include <limits.h>
23+
#include <pwd.h>
2324
#include <sched.h>
2425
#include <stdio.h>
2526
#include <stdlib.h>
@@ -213,33 +214,71 @@ strtopid(struct error *err, const char *str, pid_t *pid)
213214
}
214215

215216
int
216-
strtougid(struct error *err, const char *str, uid_t *uid, gid_t *gid)
217+
strtougid(struct error *err, char *str, uid_t *uid, gid_t *gid)
217218
{
218219
char *ptr;
219-
uintmax_t n1, n2;
220+
uintmax_t n;
221+
struct passwd *passwd = NULL;
222+
struct group *group = NULL;
220223

221-
n1 = strtoumax(str, &ptr, 10);
222-
if (ptr == str || *ptr != ':') {
223-
errno = EINVAL;
224-
goto fail;
224+
n = strtoumax(str, &ptr, 10);
225+
if (ptr != str) {
226+
if (*ptr != '\0' && *ptr != ':') {
227+
errno = EINVAL;
228+
goto fail;
229+
}
230+
if (n == UINTMAX_MAX || n != (uid_t)n) {
231+
errno = ERANGE;
232+
goto fail;
233+
}
234+
if (*ptr == ':')
235+
++ptr;
236+
*uid = (uid_t)n;
237+
} else {
238+
/* Not a numeric UID, check for a username. */
239+
if ((ptr = strchr(str, ':')) != NULL)
240+
*ptr++ = '\0';
241+
if ((passwd = getpwnam(str)) == NULL) {
242+
errno = ENOENT;
243+
goto fail;
244+
}
245+
*uid = passwd->pw_uid;
225246
}
226-
str = ptr + 1;
227-
n2 = strtoumax(str, &ptr, 10);
228-
if (ptr == str || *ptr != '\0') {
229-
errno = EINVAL;
230-
goto fail;
247+
248+
str = ptr;
249+
if (str == NULL || *str == '\0') {
250+
/* No group specified, infer it from the UID */
251+
if (passwd == NULL && (passwd = getpwuid(*uid)) == NULL) {
252+
errno = ENOENT;
253+
goto fail;
254+
}
255+
*gid = passwd->pw_gid;
256+
return (0);
231257
}
232-
if (n1 == UINTMAX_MAX || n1 != (uid_t)n1 ||
233-
n2 == UINTMAX_MAX || n2 != (gid_t)n2) {
234-
errno = ERANGE;
235-
goto fail;
258+
259+
n = strtoumax(str, &ptr, 10);
260+
if (ptr != str) {
261+
if (*ptr != '\0') {
262+
errno = EINVAL;
263+
goto fail;
264+
}
265+
if (n == UINTMAX_MAX || n != (gid_t)n) {
266+
errno = ERANGE;
267+
goto fail;
268+
}
269+
*gid = (gid_t)n;
270+
} else {
271+
/* Not a numeric GID, check for a groupname. */
272+
if ((group = getgrnam(str)) == NULL) {
273+
errno = ENOENT;
274+
goto fail;
275+
}
276+
*gid = group->gr_gid;
236277
}
237-
*uid = (uid_t)n1;
238-
*gid = (gid_t)n2;
239278
return (0);
240279

241280
fail:
242-
error_set(err, "parse userspec failed");
281+
error_set(err, "parse user/group failed");
243282
return (-1);
244283
}
245284

src/utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ int strrcmp(const char *, const char *);
4949
bool strempty(const char *);
5050
bool strmatch(const char *, const char * const [], size_t);
5151
int strtopid(struct error *, const char *, pid_t *);
52-
int strtougid(struct error *, const char *, uid_t *, gid_t *);
52+
int strtougid(struct error *, char *, uid_t *, gid_t *);
5353
int strjoin(struct error *, char **, const char *, const char *);
5454

5555
int nsenterat(struct error *, int, int);

0 commit comments

Comments
 (0)