11182St.nateldemoura@f5.com /*
21182St.nateldemoura@f5.com * Copyright (C) Igor Sysoev
31182St.nateldemoura@f5.com * Copyright (C) NGINX, Inc.
41182St.nateldemoura@f5.com */
51182St.nateldemoura@f5.com
61182St.nateldemoura@f5.com #include <nxt_main.h>
71182St.nateldemoura@f5.com #include <sys/types.h>
81182St.nateldemoura@f5.com #include <nxt_conf.h>
91182St.nateldemoura@f5.com #include <nxt_clone.h>
101182St.nateldemoura@f5.com
111182St.nateldemoura@f5.com #if (NXT_HAVE_CLONE)
121182St.nateldemoura@f5.com
131182St.nateldemoura@f5.com pid_t
nxt_clone(nxt_int_t flags)141182St.nateldemoura@f5.com nxt_clone(nxt_int_t flags)
151182St.nateldemoura@f5.com {
161182St.nateldemoura@f5.com #if defined(__s390x__) || defined(__s390__) || defined(__CRIS__)
171182St.nateldemoura@f5.com return syscall(__NR_clone, NULL, flags);
181182St.nateldemoura@f5.com #else
191182St.nateldemoura@f5.com return syscall(__NR_clone, flags, NULL);
201182St.nateldemoura@f5.com #endif
211182St.nateldemoura@f5.com }
221182St.nateldemoura@f5.com
231182St.nateldemoura@f5.com #endif
241182St.nateldemoura@f5.com
251182St.nateldemoura@f5.com
261182St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
271182St.nateldemoura@f5.com
281306St.nateldemoura@f5.com nxt_int_t nxt_clone_credential_setgroups(nxt_task_t *task, pid_t child_pid,
291182St.nateldemoura@f5.com const char *str);
301306St.nateldemoura@f5.com nxt_int_t nxt_clone_credential_map_set(nxt_task_t *task, const char* mapfile,
311306St.nateldemoura@f5.com pid_t pid, nxt_int_t default_container, nxt_int_t default_host,
321306St.nateldemoura@f5.com nxt_clone_credential_map_t *map);
331306St.nateldemoura@f5.com nxt_int_t nxt_clone_credential_map_write(nxt_task_t *task, const char *mapfile,
341182St.nateldemoura@f5.com pid_t pid, u_char *mapinfo);
351182St.nateldemoura@f5.com
361182St.nateldemoura@f5.com
371182St.nateldemoura@f5.com nxt_int_t
nxt_clone_credential_setgroups(nxt_task_t * task,pid_t child_pid,const char * str)381306St.nateldemoura@f5.com nxt_clone_credential_setgroups(nxt_task_t *task, pid_t child_pid,
391306St.nateldemoura@f5.com const char *str)
401182St.nateldemoura@f5.com {
411182St.nateldemoura@f5.com int fd, n;
421182St.nateldemoura@f5.com u_char *p, *end;
431182St.nateldemoura@f5.com u_char path[PATH_MAX];
441182St.nateldemoura@f5.com
451182St.nateldemoura@f5.com end = path + PATH_MAX;
461182St.nateldemoura@f5.com p = nxt_sprintf(path, end, "/proc/%d/setgroups", child_pid);
471182St.nateldemoura@f5.com *p = '\0';
481182St.nateldemoura@f5.com
491182St.nateldemoura@f5.com if (nxt_slow_path(p == end)) {
501182St.nateldemoura@f5.com nxt_alert(task, "error write past the buffer: %s", path);
511182St.nateldemoura@f5.com return NXT_ERROR;
521182St.nateldemoura@f5.com }
531182St.nateldemoura@f5.com
541182St.nateldemoura@f5.com fd = open((char *)path, O_RDWR);
551182St.nateldemoura@f5.com
561182St.nateldemoura@f5.com if (fd == -1) {
571182St.nateldemoura@f5.com /*
581182St.nateldemoura@f5.com * If the /proc/pid/setgroups doesn't exists, we are
591182St.nateldemoura@f5.com * safe to set uid/gid maps. But if the error is anything
601182St.nateldemoura@f5.com * other than ENOENT, then we should abort and let user know.
611182St.nateldemoura@f5.com */
621182St.nateldemoura@f5.com
631182St.nateldemoura@f5.com if (errno != ENOENT) {
641182St.nateldemoura@f5.com nxt_alert(task, "open(%s): %E", path, nxt_errno);
651182St.nateldemoura@f5.com return NXT_ERROR;
661182St.nateldemoura@f5.com }
671182St.nateldemoura@f5.com
681182St.nateldemoura@f5.com return NXT_OK;
691182St.nateldemoura@f5.com }
701182St.nateldemoura@f5.com
711182St.nateldemoura@f5.com n = write(fd, str, strlen(str));
721182St.nateldemoura@f5.com close(fd);
731182St.nateldemoura@f5.com
741182St.nateldemoura@f5.com if (nxt_slow_path(n == -1)) {
751182St.nateldemoura@f5.com nxt_alert(task, "write(%s): %E", path, nxt_errno);
761182St.nateldemoura@f5.com return NXT_ERROR;
771182St.nateldemoura@f5.com }
781182St.nateldemoura@f5.com
791182St.nateldemoura@f5.com return NXT_OK;
801182St.nateldemoura@f5.com }
811182St.nateldemoura@f5.com
821182St.nateldemoura@f5.com
831182St.nateldemoura@f5.com nxt_int_t
nxt_clone_credential_map_write(nxt_task_t * task,const char * mapfile,pid_t pid,u_char * mapinfo)841306St.nateldemoura@f5.com nxt_clone_credential_map_write(nxt_task_t *task, const char *mapfile,
851306St.nateldemoura@f5.com pid_t pid, u_char *mapinfo)
861182St.nateldemoura@f5.com {
871182St.nateldemoura@f5.com int len, mapfd;
881182St.nateldemoura@f5.com u_char *p, *end;
891182St.nateldemoura@f5.com ssize_t n;
901182St.nateldemoura@f5.com u_char buf[256];
911182St.nateldemoura@f5.com
921182St.nateldemoura@f5.com end = buf + sizeof(buf);
931182St.nateldemoura@f5.com
941182St.nateldemoura@f5.com p = nxt_sprintf(buf, end, "/proc/%d/%s", pid, mapfile);
951182St.nateldemoura@f5.com if (nxt_slow_path(p == end)) {
961182St.nateldemoura@f5.com nxt_alert(task, "writing past the buffer");
971182St.nateldemoura@f5.com return NXT_ERROR;
981182St.nateldemoura@f5.com }
991182St.nateldemoura@f5.com
1001182St.nateldemoura@f5.com *p = '\0';
1011182St.nateldemoura@f5.com
1021182St.nateldemoura@f5.com mapfd = open((char*)buf, O_RDWR);
1031182St.nateldemoura@f5.com if (nxt_slow_path(mapfd == -1)) {
1041182St.nateldemoura@f5.com nxt_alert(task, "failed to open proc map (%s) %E", buf, nxt_errno);
1051182St.nateldemoura@f5.com return NXT_ERROR;
1061182St.nateldemoura@f5.com }
1071182St.nateldemoura@f5.com
1081182St.nateldemoura@f5.com len = nxt_strlen(mapinfo);
1091182St.nateldemoura@f5.com
1101182St.nateldemoura@f5.com n = write(mapfd, (char *)mapinfo, len);
1111182St.nateldemoura@f5.com if (nxt_slow_path(n != len)) {
1121182St.nateldemoura@f5.com
1131182St.nateldemoura@f5.com if (n == -1 && nxt_errno == EINVAL) {
1141182St.nateldemoura@f5.com nxt_alert(task, "failed to write %s: Check kernel maximum " \
1151182St.nateldemoura@f5.com "allowed lines %E", buf, nxt_errno);
1161182St.nateldemoura@f5.com
1171182St.nateldemoura@f5.com } else {
1181182St.nateldemoura@f5.com nxt_alert(task, "failed to write proc map (%s) %E", buf,
1191182St.nateldemoura@f5.com nxt_errno);
1201182St.nateldemoura@f5.com }
1211182St.nateldemoura@f5.com
1221201St.nateldemoura@f5.com close(mapfd);
1231201St.nateldemoura@f5.com
1241182St.nateldemoura@f5.com return NXT_ERROR;
1251182St.nateldemoura@f5.com }
1261182St.nateldemoura@f5.com
1271201St.nateldemoura@f5.com close(mapfd);
1281201St.nateldemoura@f5.com
1291182St.nateldemoura@f5.com return NXT_OK;
1301182St.nateldemoura@f5.com }
1311182St.nateldemoura@f5.com
1321182St.nateldemoura@f5.com
1331182St.nateldemoura@f5.com nxt_int_t
nxt_clone_credential_map_set(nxt_task_t * task,const char * mapfile,pid_t pid,nxt_int_t default_container,nxt_int_t default_host,nxt_clone_credential_map_t * map)1341306St.nateldemoura@f5.com nxt_clone_credential_map_set(nxt_task_t *task, const char* mapfile, pid_t pid,
1351306St.nateldemoura@f5.com nxt_int_t default_container, nxt_int_t default_host,
1361306St.nateldemoura@f5.com nxt_clone_credential_map_t *map)
1371182St.nateldemoura@f5.com {
1381306St.nateldemoura@f5.com u_char *p, *end, *mapinfo;
1391306St.nateldemoura@f5.com nxt_int_t ret, len;
1401306St.nateldemoura@f5.com nxt_uint_t i;
1411182St.nateldemoura@f5.com
1421182St.nateldemoura@f5.com /*
1431182St.nateldemoura@f5.com * uid_map one-entry size:
1441182St.nateldemoura@f5.com * alloc space for 3 numbers (32bit) plus 2 spaces and \n.
1451182St.nateldemoura@f5.com */
1461182St.nateldemoura@f5.com len = sizeof(u_char) * (10 + 10 + 10 + 2 + 1);
1471182St.nateldemoura@f5.com
1481306St.nateldemoura@f5.com if (map->size > 0) {
1491306St.nateldemoura@f5.com len = len * map->size + 1;
1501182St.nateldemoura@f5.com
1511182St.nateldemoura@f5.com mapinfo = nxt_malloc(len);
1521182St.nateldemoura@f5.com if (nxt_slow_path(mapinfo == NULL)) {
1531182St.nateldemoura@f5.com return NXT_ERROR;
1541182St.nateldemoura@f5.com }
1551182St.nateldemoura@f5.com
1561182St.nateldemoura@f5.com p = mapinfo;
1571182St.nateldemoura@f5.com end = mapinfo + len;
1581182St.nateldemoura@f5.com
1591306St.nateldemoura@f5.com for (i = 0; i < map->size; i++) {
1601306St.nateldemoura@f5.com p = nxt_sprintf(p, end, "%d %d %d", map->map[i].container,
1611306St.nateldemoura@f5.com map->map[i].host, map->map[i].size);
1621182St.nateldemoura@f5.com
1631182St.nateldemoura@f5.com if (nxt_slow_path(p == end)) {
1641306St.nateldemoura@f5.com nxt_alert(task, "write past the mapinfo buffer");
1651182St.nateldemoura@f5.com nxt_free(mapinfo);
1661182St.nateldemoura@f5.com return NXT_ERROR;
1671182St.nateldemoura@f5.com }
1681182St.nateldemoura@f5.com
1691306St.nateldemoura@f5.com if (i+1 < map->size) {
1701182St.nateldemoura@f5.com *p++ = '\n';
1711182St.nateldemoura@f5.com
1721182St.nateldemoura@f5.com } else {
1731182St.nateldemoura@f5.com *p = '\0';
1741182St.nateldemoura@f5.com }
1751182St.nateldemoura@f5.com }
1761182St.nateldemoura@f5.com
1771182St.nateldemoura@f5.com } else {
1781182St.nateldemoura@f5.com mapinfo = nxt_malloc(len);
1791182St.nateldemoura@f5.com if (nxt_slow_path(mapinfo == NULL)) {
1801182St.nateldemoura@f5.com return NXT_ERROR;
1811182St.nateldemoura@f5.com }
1821182St.nateldemoura@f5.com
1831182St.nateldemoura@f5.com end = mapinfo + len;
1841306St.nateldemoura@f5.com p = nxt_sprintf(mapinfo, end, "%d %d 1",
1851306St.nateldemoura@f5.com default_container, default_host);
1861182St.nateldemoura@f5.com *p = '\0';
1871182St.nateldemoura@f5.com
1881182St.nateldemoura@f5.com if (nxt_slow_path(p == end)) {
1891306St.nateldemoura@f5.com nxt_alert(task, "write past mapinfo buffer");
1901182St.nateldemoura@f5.com nxt_free(mapinfo);
1911182St.nateldemoura@f5.com return NXT_ERROR;
1921182St.nateldemoura@f5.com }
1931182St.nateldemoura@f5.com }
1941182St.nateldemoura@f5.com
1951306St.nateldemoura@f5.com ret = nxt_clone_credential_map_write(task, mapfile, pid, mapinfo);
1961182St.nateldemoura@f5.com
1971182St.nateldemoura@f5.com nxt_free(mapinfo);
1981182St.nateldemoura@f5.com
1991182St.nateldemoura@f5.com return ret;
2001182St.nateldemoura@f5.com }
2011182St.nateldemoura@f5.com
2021182St.nateldemoura@f5.com
2031182St.nateldemoura@f5.com nxt_int_t
nxt_clone_credential_map(nxt_task_t * task,pid_t pid,nxt_credential_t * app_creds,nxt_clone_t * clone)2041306St.nateldemoura@f5.com nxt_clone_credential_map(nxt_task_t *task, pid_t pid,
2051306St.nateldemoura@f5.com nxt_credential_t *app_creds, nxt_clone_t *clone)
2061182St.nateldemoura@f5.com {
2071182St.nateldemoura@f5.com nxt_int_t ret;
2081306St.nateldemoura@f5.com nxt_int_t default_host_uid;
2091306St.nateldemoura@f5.com nxt_int_t default_host_gid;
2101182St.nateldemoura@f5.com const char *rule;
2111182St.nateldemoura@f5.com nxt_runtime_t *rt;
2121182St.nateldemoura@f5.com
2131182St.nateldemoura@f5.com rt = task->thread->runtime;
2141306St.nateldemoura@f5.com
2151306St.nateldemoura@f5.com if (rt->capabilities.setid) {
2161306St.nateldemoura@f5.com rule = "allow";
2171182St.nateldemoura@f5.com
2181306St.nateldemoura@f5.com /*
2191306St.nateldemoura@f5.com * By default we don't map a privileged user
2201306St.nateldemoura@f5.com */
2211306St.nateldemoura@f5.com default_host_uid = app_creds->uid;
2221306St.nateldemoura@f5.com default_host_gid = app_creds->base_gid;
2231306St.nateldemoura@f5.com } else {
2241306St.nateldemoura@f5.com rule = "deny";
2251182St.nateldemoura@f5.com
2261306St.nateldemoura@f5.com default_host_uid = nxt_euid;
2271306St.nateldemoura@f5.com default_host_gid = nxt_egid;
2281306St.nateldemoura@f5.com }
2291306St.nateldemoura@f5.com
2301306St.nateldemoura@f5.com ret = nxt_clone_credential_map_set(task, "uid_map", pid, app_creds->uid,
2311306St.nateldemoura@f5.com default_host_uid,
2321306St.nateldemoura@f5.com &clone->uidmap);
2331306St.nateldemoura@f5.com
2341182St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
2351182St.nateldemoura@f5.com return NXT_ERROR;
2361182St.nateldemoura@f5.com }
2371182St.nateldemoura@f5.com
2381306St.nateldemoura@f5.com ret = nxt_clone_credential_setgroups(task, pid, rule);
2391182St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
2401182St.nateldemoura@f5.com nxt_alert(task, "failed to write /proc/%d/setgroups", pid);
2411182St.nateldemoura@f5.com return NXT_ERROR;
2421182St.nateldemoura@f5.com }
2431182St.nateldemoura@f5.com
2441306St.nateldemoura@f5.com ret = nxt_clone_credential_map_set(task, "gid_map", pid, app_creds->base_gid,
2451306St.nateldemoura@f5.com default_host_gid,
2461306St.nateldemoura@f5.com &clone->gidmap);
2471306St.nateldemoura@f5.com
2481182St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
2491182St.nateldemoura@f5.com return NXT_ERROR;
2501182St.nateldemoura@f5.com }
2511182St.nateldemoura@f5.com
2521182St.nateldemoura@f5.com return NXT_OK;
2531182St.nateldemoura@f5.com }
2541182St.nateldemoura@f5.com
2551306St.nateldemoura@f5.com
2561306St.nateldemoura@f5.com nxt_int_t
nxt_clone_vldt_credential_uidmap(nxt_task_t * task,nxt_clone_credential_map_t * map,nxt_credential_t * creds)2571306St.nateldemoura@f5.com nxt_clone_vldt_credential_uidmap(nxt_task_t *task,
2581306St.nateldemoura@f5.com nxt_clone_credential_map_t *map, nxt_credential_t *creds)
2591306St.nateldemoura@f5.com {
2601306St.nateldemoura@f5.com nxt_int_t id;
2611306St.nateldemoura@f5.com nxt_uint_t i;
2621306St.nateldemoura@f5.com nxt_runtime_t *rt;
2631306St.nateldemoura@f5.com nxt_clone_map_entry_t m;
2641306St.nateldemoura@f5.com
2651306St.nateldemoura@f5.com if (map->size == 0) {
2661306St.nateldemoura@f5.com return NXT_OK;
2671306St.nateldemoura@f5.com }
2681306St.nateldemoura@f5.com
2691306St.nateldemoura@f5.com rt = task->thread->runtime;
2701306St.nateldemoura@f5.com
2711306St.nateldemoura@f5.com if (!rt->capabilities.setid) {
2721306St.nateldemoura@f5.com if (nxt_slow_path(map->size > 1)) {
2731306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_NOTICE, "\"uidmap\" field has %d entries "
2741306St.nateldemoura@f5.com "but unprivileged unit has a maximum of 1 map.",
2751306St.nateldemoura@f5.com map->size);
2761306St.nateldemoura@f5.com
2771306St.nateldemoura@f5.com return NXT_ERROR;
2781306St.nateldemoura@f5.com }
2791306St.nateldemoura@f5.com
2801306St.nateldemoura@f5.com id = map->map[0].host;
2811306St.nateldemoura@f5.com
2821306St.nateldemoura@f5.com if (nxt_slow_path((nxt_uid_t) id != nxt_euid)) {
2831306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_NOTICE, "\"uidmap\" field has an entry for "
2841306St.nateldemoura@f5.com "host uid %d but unprivileged unit can only map itself "
2851306St.nateldemoura@f5.com "(uid %d) into child namespaces.", id, nxt_euid);
2861306St.nateldemoura@f5.com
2871306St.nateldemoura@f5.com return NXT_ERROR;
2881306St.nateldemoura@f5.com }
2891306St.nateldemoura@f5.com
2901306St.nateldemoura@f5.com return NXT_OK;
2911306St.nateldemoura@f5.com }
2921306St.nateldemoura@f5.com
2931306St.nateldemoura@f5.com for (i = 0; i < map->size; i++) {
2941306St.nateldemoura@f5.com m = map->map[i];
2951306St.nateldemoura@f5.com
2961306St.nateldemoura@f5.com if (creds->uid >= (nxt_uid_t) m.container
2971306St.nateldemoura@f5.com && creds->uid < (nxt_uid_t) (m.container + m.size))
2981306St.nateldemoura@f5.com {
2991306St.nateldemoura@f5.com return NXT_OK;
3001306St.nateldemoura@f5.com }
3011306St.nateldemoura@f5.com }
3021306St.nateldemoura@f5.com
3031306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_NOTICE, "\"uidmap\" field has no \"container\" "
3041306St.nateldemoura@f5.com "entry for user \"%s\" (uid %d)", creds->user, creds->uid);
3051306St.nateldemoura@f5.com
3061306St.nateldemoura@f5.com return NXT_ERROR;
3071306St.nateldemoura@f5.com }
3081306St.nateldemoura@f5.com
3091306St.nateldemoura@f5.com
3101306St.nateldemoura@f5.com nxt_int_t
nxt_clone_vldt_credential_gidmap(nxt_task_t * task,nxt_clone_credential_map_t * map,nxt_credential_t * creds)3111306St.nateldemoura@f5.com nxt_clone_vldt_credential_gidmap(nxt_task_t *task,
3121306St.nateldemoura@f5.com nxt_clone_credential_map_t *map, nxt_credential_t *creds)
3131306St.nateldemoura@f5.com {
3141306St.nateldemoura@f5.com nxt_uint_t base_ok, gid_ok, gids_ok;
3151306St.nateldemoura@f5.com nxt_uint_t i, j;
3161306St.nateldemoura@f5.com nxt_runtime_t *rt;
3171306St.nateldemoura@f5.com nxt_clone_map_entry_t m;
3181306St.nateldemoura@f5.com
3191306St.nateldemoura@f5.com rt = task->thread->runtime;
3201306St.nateldemoura@f5.com
3211306St.nateldemoura@f5.com if (!rt->capabilities.setid) {
3221306St.nateldemoura@f5.com if (creds->ngroups > 0
3231306St.nateldemoura@f5.com && !(creds->ngroups == 1 && creds->gids[0] == creds->base_gid)) {
3241306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_NOTICE,
3251306St.nateldemoura@f5.com "unprivileged unit disallow supplementary groups for "
3261306St.nateldemoura@f5.com "new namespace (user \"%s\" has %d group%s).",
3271306St.nateldemoura@f5.com creds->user, creds->ngroups,
3281306St.nateldemoura@f5.com creds->ngroups > 1 ? "s" : "");
3291306St.nateldemoura@f5.com
3301306St.nateldemoura@f5.com return NXT_ERROR;
3311306St.nateldemoura@f5.com }
3321306St.nateldemoura@f5.com
3331306St.nateldemoura@f5.com if (map->size == 0) {
3341306St.nateldemoura@f5.com return NXT_OK;
3351306St.nateldemoura@f5.com }
3361306St.nateldemoura@f5.com
3371306St.nateldemoura@f5.com if (nxt_slow_path(map->size > 1)) {
3381306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_NOTICE, "\"gidmap\" field has %d entries "
3391306St.nateldemoura@f5.com "but unprivileged unit has a maximum of 1 map.",
3401306St.nateldemoura@f5.com map->size);
3411306St.nateldemoura@f5.com
3421306St.nateldemoura@f5.com return NXT_ERROR;
3431306St.nateldemoura@f5.com }
3441306St.nateldemoura@f5.com
3451306St.nateldemoura@f5.com m = map->map[0];
3461306St.nateldemoura@f5.com
3471306St.nateldemoura@f5.com if (nxt_slow_path((nxt_gid_t) m.host != nxt_egid)) {
3481306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has an entry for "
3491306St.nateldemoura@f5.com "host gid %d but unprivileged unit can only map itself "
3501306St.nateldemoura@f5.com "(gid %d) into child namespaces.", m.host, nxt_egid);
3511306St.nateldemoura@f5.com
3521306St.nateldemoura@f5.com return NXT_ERROR;
3531306St.nateldemoura@f5.com }
3541306St.nateldemoura@f5.com
3551306St.nateldemoura@f5.com if (nxt_slow_path(m.size > 1)) {
3561306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has an entry with "
3571306St.nateldemoura@f5.com "\"size\": %d, but for unprivileged unit it must be 1.",
3581306St.nateldemoura@f5.com m.size);
3591306St.nateldemoura@f5.com
3601306St.nateldemoura@f5.com return NXT_ERROR;
3611306St.nateldemoura@f5.com }
3621306St.nateldemoura@f5.com
3631306St.nateldemoura@f5.com if (nxt_slow_path((nxt_gid_t) m.container != creds->base_gid)) {
3641306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR,
3651306St.nateldemoura@f5.com "\"gidmap\" field has no \"container\" entry for gid %d.",
3661306St.nateldemoura@f5.com creds->base_gid);
3671306St.nateldemoura@f5.com
3681306St.nateldemoura@f5.com return NXT_ERROR;
3691306St.nateldemoura@f5.com }
3701306St.nateldemoura@f5.com
3711306St.nateldemoura@f5.com return NXT_OK;
3721306St.nateldemoura@f5.com }
3731306St.nateldemoura@f5.com
3741306St.nateldemoura@f5.com if (map->size == 0) {
3751306St.nateldemoura@f5.com if (creds->ngroups > 0
3761306St.nateldemoura@f5.com && !(creds->ngroups == 1 && creds->gids[0] == creds->base_gid))
3771306St.nateldemoura@f5.com {
3781306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has no entries "
3791306St.nateldemoura@f5.com "but user \"%s\" has %d suplementary group%s.",
3801306St.nateldemoura@f5.com creds->user, creds->ngroups,
3811306St.nateldemoura@f5.com creds->ngroups > 1 ? "s" : "");
3821306St.nateldemoura@f5.com
3831306St.nateldemoura@f5.com return NXT_ERROR;
3841306St.nateldemoura@f5.com }
3851306St.nateldemoura@f5.com
3861306St.nateldemoura@f5.com return NXT_OK;
387*2078Salx.manpages@gmail.com }
3881306St.nateldemoura@f5.com
3891306St.nateldemoura@f5.com base_ok = 0;
3901306St.nateldemoura@f5.com gids_ok = 0;
3911306St.nateldemoura@f5.com
3921306St.nateldemoura@f5.com for (i = 0; i < creds->ngroups; i++) {
3931306St.nateldemoura@f5.com gid_ok = 0;
3941306St.nateldemoura@f5.com
3951306St.nateldemoura@f5.com for (j = 0; j < map->size; j++) {
3961306St.nateldemoura@f5.com m = map->map[j];
3971306St.nateldemoura@f5.com
3981306St.nateldemoura@f5.com if (!base_ok && creds->base_gid >= (nxt_gid_t) m.container
3991306St.nateldemoura@f5.com && creds->base_gid < (nxt_gid_t) (m.container+m.size))
4001306St.nateldemoura@f5.com {
4011306St.nateldemoura@f5.com base_ok = 1;
4021306St.nateldemoura@f5.com }
4031306St.nateldemoura@f5.com
4041306St.nateldemoura@f5.com if (creds->gids[i] >= (nxt_gid_t) m.container
4051306St.nateldemoura@f5.com && creds->gids[i] < (nxt_gid_t) (m.container+m.size))
4061306St.nateldemoura@f5.com {
4071306St.nateldemoura@f5.com gid_ok = 1;
4081306St.nateldemoura@f5.com break;
4091306St.nateldemoura@f5.com }
4101306St.nateldemoura@f5.com }
4111306St.nateldemoura@f5.com
4121306St.nateldemoura@f5.com if (nxt_fast_path(gid_ok)) {
4131306St.nateldemoura@f5.com gids_ok++;
4141306St.nateldemoura@f5.com }
4151306St.nateldemoura@f5.com }
4161306St.nateldemoura@f5.com
4171306St.nateldemoura@f5.com if (!base_ok) {
4181306St.nateldemoura@f5.com for (i = 0; i < map->size; i++) {
4191306St.nateldemoura@f5.com m = map->map[i];
4201306St.nateldemoura@f5.com
4211306St.nateldemoura@f5.com if (creds->base_gid >= (nxt_gid_t) m.container
4221306St.nateldemoura@f5.com && creds->base_gid < (nxt_gid_t) (m.container+m.size))
4231306St.nateldemoura@f5.com {
4241306St.nateldemoura@f5.com base_ok = 1;
4251306St.nateldemoura@f5.com break;
4261306St.nateldemoura@f5.com }
4271306St.nateldemoura@f5.com }
4281306St.nateldemoura@f5.com }
4291306St.nateldemoura@f5.com
4301306St.nateldemoura@f5.com if (nxt_slow_path(!base_ok)) {
4311306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has no \"container\" "
4321306St.nateldemoura@f5.com "entry for gid %d.", creds->base_gid);
4331306St.nateldemoura@f5.com
4341306St.nateldemoura@f5.com return NXT_ERROR;
4351306St.nateldemoura@f5.com }
4361306St.nateldemoura@f5.com
4371306St.nateldemoura@f5.com if (nxt_slow_path(gids_ok < creds->ngroups)) {
4381306St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"gidmap\" field has missing "
4391306St.nateldemoura@f5.com "suplementary gid mappings (found %d out of %d).", gids_ok,
4401306St.nateldemoura@f5.com creds->ngroups);
4411306St.nateldemoura@f5.com
4421306St.nateldemoura@f5.com return NXT_ERROR;
4431306St.nateldemoura@f5.com }
4441306St.nateldemoura@f5.com
4451306St.nateldemoura@f5.com return NXT_OK;
4461306St.nateldemoura@f5.com }
4471306St.nateldemoura@f5.com
4481182St.nateldemoura@f5.com #endif
449