xref: /unit/src/test/nxt_clone_test.c (revision 1439:32578e837322)
11306St.nateldemoura@f5.com /*
21306St.nateldemoura@f5.com  * Copyright (C) NGINX, Inc.
31306St.nateldemoura@f5.com  * Copyright (C) Valentin V. Bartenev
41306St.nateldemoura@f5.com  */
51306St.nateldemoura@f5.com 
61306St.nateldemoura@f5.com #include <nxt_main.h>
71306St.nateldemoura@f5.com #include <nxt_conf.h>
81306St.nateldemoura@f5.com #include "nxt_tests.h"
91306St.nateldemoura@f5.com 
101306St.nateldemoura@f5.com 
111306St.nateldemoura@f5.com #define UIDMAP 1
121306St.nateldemoura@f5.com #define GIDMAP 2
131306St.nateldemoura@f5.com 
141306St.nateldemoura@f5.com 
151306St.nateldemoura@f5.com typedef struct {
161306St.nateldemoura@f5.com     nxt_int_t         map_type;
171306St.nateldemoura@f5.com     nxt_str_t         map_data;
181306St.nateldemoura@f5.com     nxt_int_t         setid;
191306St.nateldemoura@f5.com     nxt_credential_t  creds;
201306St.nateldemoura@f5.com     nxt_uid_t         unit_euid;
211306St.nateldemoura@f5.com     nxt_gid_t         unit_egid;
221306St.nateldemoura@f5.com     nxt_int_t         result;
231306St.nateldemoura@f5.com     nxt_str_t         errmsg;
241306St.nateldemoura@f5.com } nxt_clone_creds_testcase_t;
251306St.nateldemoura@f5.com 
261306St.nateldemoura@f5.com typedef struct {
271306St.nateldemoura@f5.com     nxt_clone_creds_testcase_t  *tc;
281306St.nateldemoura@f5.com } nxt_clone_creds_ctx_t;
291306St.nateldemoura@f5.com 
301306St.nateldemoura@f5.com 
311306St.nateldemoura@f5.com nxt_int_t nxt_clone_test_mappings(nxt_task_t *task, nxt_mp_t *mp,
321306St.nateldemoura@f5.com     nxt_clone_creds_ctx_t *ctx, nxt_clone_creds_testcase_t *tc);
331306St.nateldemoura@f5.com void nxt_cdecl nxt_clone_test_log_handler(nxt_uint_t level, nxt_log_t *log,
341306St.nateldemoura@f5.com     const char *fmt, ...);
351306St.nateldemoura@f5.com nxt_int_t nxt_clone_test_map_assert(nxt_task_t *task,
361306St.nateldemoura@f5.com     nxt_clone_creds_testcase_t *tc, nxt_clone_credential_map_t *map);
371306St.nateldemoura@f5.com static nxt_int_t nxt_clone_test_parse_map(nxt_task_t *task,
381306St.nateldemoura@f5.com     nxt_str_t *map_str, nxt_clone_credential_map_t *map);
391306St.nateldemoura@f5.com 
401306St.nateldemoura@f5.com 
411306St.nateldemoura@f5.com nxt_log_t *test_log;
421306St.nateldemoura@f5.com 
431306St.nateldemoura@f5.com static nxt_gid_t gids[] = {1000, 10000, 60000};
441306St.nateldemoura@f5.com 
451306St.nateldemoura@f5.com static nxt_clone_creds_testcase_t testcases[] = {
461306St.nateldemoura@f5.com     {
471306St.nateldemoura@f5.com         /*
481306St.nateldemoura@f5.com          * Unprivileged unit
491306St.nateldemoura@f5.com          *
501306St.nateldemoura@f5.com          * if no uid mapping and app creds and unit creds are the same,
511306St.nateldemoura@f5.com          * then we automatically add a map for the creds->uid.
521306St.nateldemoura@f5.com          * Then, child process can safely setuid(creds->uid) in
531306St.nateldemoura@f5.com          * the new namespace.
541306St.nateldemoura@f5.com          */
551306St.nateldemoura@f5.com         UIDMAP,
561306St.nateldemoura@f5.com         nxt_string(""),
571306St.nateldemoura@f5.com         0,
581306St.nateldemoura@f5.com         {"nobody", 65534, 65534, 0, NULL},
591306St.nateldemoura@f5.com         1000, 1000,
601306St.nateldemoura@f5.com         NXT_OK,
611306St.nateldemoura@f5.com         nxt_string("")
621306St.nateldemoura@f5.com     },
631306St.nateldemoura@f5.com     {
641306St.nateldemoura@f5.com         UIDMAP,
651306St.nateldemoura@f5.com         nxt_string(""),
661306St.nateldemoura@f5.com         0,
671306St.nateldemoura@f5.com         {"johndoe", 10000, 10000, 0, NULL},
681306St.nateldemoura@f5.com         1000, 1000,
691306St.nateldemoura@f5.com         NXT_OK,
701306St.nateldemoura@f5.com         nxt_string("")
711306St.nateldemoura@f5.com     },
721306St.nateldemoura@f5.com     {
731306St.nateldemoura@f5.com         UIDMAP,
741306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 1000, \"size\": 1}]"),
751306St.nateldemoura@f5.com         0,
761306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 0, NULL},
771306St.nateldemoura@f5.com         1000, 1000,
781306St.nateldemoura@f5.com         NXT_OK,
791306St.nateldemoura@f5.com         nxt_string("")
801306St.nateldemoura@f5.com     },
811306St.nateldemoura@f5.com     {
821306St.nateldemoura@f5.com         UIDMAP,
831306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}]"),
841306St.nateldemoura@f5.com         0,
851306St.nateldemoura@f5.com         {"root", 0, 0, 0, NULL},
861306St.nateldemoura@f5.com         1000, 1000,
871306St.nateldemoura@f5.com         NXT_OK,
881306St.nateldemoura@f5.com         nxt_string("")
891306St.nateldemoura@f5.com     },
901306St.nateldemoura@f5.com     {
911306St.nateldemoura@f5.com         UIDMAP,
921306St.nateldemoura@f5.com         nxt_string("[{\"container\": 65534, \"host\": 1000, \"size\": 1}]"),
931306St.nateldemoura@f5.com         0,
941306St.nateldemoura@f5.com         {"nobody", 65534, 0, 0, NULL},
951306St.nateldemoura@f5.com         1000, 1000,
961306St.nateldemoura@f5.com         NXT_OK,
971306St.nateldemoura@f5.com         nxt_string("")
981306St.nateldemoura@f5.com     },
991306St.nateldemoura@f5.com     {
1001306St.nateldemoura@f5.com         UIDMAP,
1011306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1},"
1021306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1}]"),
1031306St.nateldemoura@f5.com         0,
1041306St.nateldemoura@f5.com         {"root", 0, 0, 0, NULL},
1051306St.nateldemoura@f5.com         1000, 1000,
1061306St.nateldemoura@f5.com         NXT_ERROR,
1071306St.nateldemoura@f5.com         nxt_string("\"uidmap\" field has 2 entries but unprivileged unit has "
1081306St.nateldemoura@f5.com                    "a maximum of 1 map.")
1091306St.nateldemoura@f5.com     },
1101306St.nateldemoura@f5.com     {
1111306St.nateldemoura@f5.com         UIDMAP,
1121306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1},"
1131306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1}]"),
1141306St.nateldemoura@f5.com         1, /* privileged */
1151306St.nateldemoura@f5.com         {"root", 0, 0, 0, NULL},
1161306St.nateldemoura@f5.com         1000, 1000,
1171306St.nateldemoura@f5.com         NXT_OK,
1181306St.nateldemoura@f5.com         nxt_string("")
1191306St.nateldemoura@f5.com     },
1201306St.nateldemoura@f5.com     {
1211306St.nateldemoura@f5.com         UIDMAP,
1221306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000},"
1231306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"),
1241306St.nateldemoura@f5.com         1, /* privileged */
1251306St.nateldemoura@f5.com         {"johndoe", 500, 0, 0, NULL},
1261306St.nateldemoura@f5.com         1000, 1000,
1271306St.nateldemoura@f5.com         NXT_OK,
1281306St.nateldemoura@f5.com         nxt_string("")
1291306St.nateldemoura@f5.com     },
1301306St.nateldemoura@f5.com     {
1311306St.nateldemoura@f5.com         UIDMAP,
1321306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000},"
1331306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"),
1341306St.nateldemoura@f5.com         1, /* privileged */
1351306St.nateldemoura@f5.com         {"johndoe", 1000, 0, 0, NULL},
1361306St.nateldemoura@f5.com         1000, 1000,
1371306St.nateldemoura@f5.com         NXT_OK,
1381306St.nateldemoura@f5.com         nxt_string("")
1391306St.nateldemoura@f5.com     },
1401306St.nateldemoura@f5.com     {
1411306St.nateldemoura@f5.com         UIDMAP,
1421306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000},"
1431306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"),
1441306St.nateldemoura@f5.com         1, /* privileged */
1451306St.nateldemoura@f5.com         {"johndoe", 1500, 0, 0, NULL},
1461306St.nateldemoura@f5.com         1000, 1000,
1471306St.nateldemoura@f5.com         NXT_OK,
1481306St.nateldemoura@f5.com         nxt_string("")
1491306St.nateldemoura@f5.com     },
1501306St.nateldemoura@f5.com     {
1511306St.nateldemoura@f5.com         UIDMAP,
1521306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000},"
1531306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"),
1541306St.nateldemoura@f5.com         1, /* privileged */
1551306St.nateldemoura@f5.com         {"johndoe", 1999, 0, 0, NULL},
1561306St.nateldemoura@f5.com         1000, 1000,
1571306St.nateldemoura@f5.com         NXT_OK,
1581306St.nateldemoura@f5.com         nxt_string("")
1591306St.nateldemoura@f5.com     },
1601306St.nateldemoura@f5.com     {
1611306St.nateldemoura@f5.com         UIDMAP,
1621306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000},"
1631306St.nateldemoura@f5.com                    " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"),
1641306St.nateldemoura@f5.com         1, /* privileged */
1651306St.nateldemoura@f5.com         {"johndoe", 2000, 0, 0, NULL},
1661306St.nateldemoura@f5.com         1000, 1000,
1671306St.nateldemoura@f5.com         NXT_ERROR,
1681306St.nateldemoura@f5.com         nxt_string("\"uidmap\" field has no \"container\" entry for user "
1691306St.nateldemoura@f5.com                    "\"johndoe\" (uid 2000)")
1701306St.nateldemoura@f5.com     },
1711306St.nateldemoura@f5.com     {
1721306St.nateldemoura@f5.com         /*
1731306St.nateldemoura@f5.com          * Unprivileged unit
1741306St.nateldemoura@f5.com          *
1751306St.nateldemoura@f5.com          * if no gid mapping and app creds and unit creds are the same,
1761306St.nateldemoura@f5.com          * then we automatically add a map for the creds->base_gid.
1771306St.nateldemoura@f5.com          * Then, child process can safely setgid(creds->base_gid) in
1781306St.nateldemoura@f5.com          * the new namespace.
1791306St.nateldemoura@f5.com          */
1801306St.nateldemoura@f5.com         GIDMAP,
1811306St.nateldemoura@f5.com         nxt_string("[]"),
1821306St.nateldemoura@f5.com         0,
1831306St.nateldemoura@f5.com         {"nobody", 65534, 65534, 0, NULL},
1841306St.nateldemoura@f5.com         1000, 1000,
1851306St.nateldemoura@f5.com         NXT_OK,
1861306St.nateldemoura@f5.com         nxt_string("")
1871306St.nateldemoura@f5.com     },
1881306St.nateldemoura@f5.com     {
1891306St.nateldemoura@f5.com         /*
1901306St.nateldemoura@f5.com          * Unprivileged unit
1911306St.nateldemoura@f5.com          *
1921306St.nateldemoura@f5.com          * Inside the new namespace, we can have any gid but it
1931306St.nateldemoura@f5.com          * should map to parent gid (in this case 1000) in parent
1941306St.nateldemoura@f5.com          * namespace.
1951306St.nateldemoura@f5.com          */
1961306St.nateldemoura@f5.com         GIDMAP,
1971306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}]"),
1981306St.nateldemoura@f5.com         0,
1991306St.nateldemoura@f5.com         {"root", 0, 0, 0, NULL},
2001306St.nateldemoura@f5.com         1000, 1000,
2011306St.nateldemoura@f5.com         NXT_OK,
2021306St.nateldemoura@f5.com         nxt_string("")
2031306St.nateldemoura@f5.com     },
2041306St.nateldemoura@f5.com     {
2051306St.nateldemoura@f5.com         GIDMAP,
2061306St.nateldemoura@f5.com         nxt_string("[{\"container\": 65534, \"host\": 1000, \"size\": 1}]"),
2071306St.nateldemoura@f5.com         0,
2081306St.nateldemoura@f5.com         {"nobody", 65534, 65534, 0, NULL},
2091306St.nateldemoura@f5.com         1000, 1000,
2101306St.nateldemoura@f5.com         NXT_OK,
2111306St.nateldemoura@f5.com         nxt_string("")
2121306St.nateldemoura@f5.com     },
2131306St.nateldemoura@f5.com     {
2141306St.nateldemoura@f5.com         /*
2151306St.nateldemoura@f5.com          * Unprivileged unit
2161306St.nateldemoura@f5.com          *
2171306St.nateldemoura@f5.com          * There's no mapping for "johndoe" (gid 1000) inside the namespace.
2181306St.nateldemoura@f5.com          */
2191306St.nateldemoura@f5.com         GIDMAP,
2201306St.nateldemoura@f5.com         nxt_string("[{\"container\": 65535, \"host\": 1000, \"size\": 1}]"),
2211306St.nateldemoura@f5.com         0,
2221306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 0, NULL},
2231306St.nateldemoura@f5.com         1000, 1000,
2241306St.nateldemoura@f5.com         NXT_ERROR,
2251306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has no \"container\" entry for "
2261306St.nateldemoura@f5.com                     "gid 1000.")
2271306St.nateldemoura@f5.com     },
2281306St.nateldemoura@f5.com     {
2291306St.nateldemoura@f5.com         GIDMAP,
2301306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 1000, \"size\": 2}]"),
2311306St.nateldemoura@f5.com         0,
2321306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 0, NULL},
2331306St.nateldemoura@f5.com         1000, 1000,
2341306St.nateldemoura@f5.com         NXT_ERROR,
2351306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has an entry with \"size\": 2, but "
2361306St.nateldemoura@f5.com                     "for unprivileged unit it must be 1.")
2371306St.nateldemoura@f5.com     },
2381306St.nateldemoura@f5.com     {
2391306St.nateldemoura@f5.com         GIDMAP,
2401306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 1001, \"size\": 1}]"),
2411306St.nateldemoura@f5.com         0,
2421306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 0, NULL},
2431306St.nateldemoura@f5.com         1000, 1000,
2441306St.nateldemoura@f5.com         NXT_ERROR,
2451306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has an entry for host gid 1001 but "
2461306St.nateldemoura@f5.com                     "unprivileged unit can only map itself (gid 1000) "
2471306St.nateldemoura@f5.com                     "into child namespaces.")
2481306St.nateldemoura@f5.com     },
2491306St.nateldemoura@f5.com     {
2501306St.nateldemoura@f5.com         GIDMAP,
2511306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 1000, \"size\": 1}]"),
2521306St.nateldemoura@f5.com         0,
2531306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 3, gids},
2541306St.nateldemoura@f5.com         1000, 1000,
2551306St.nateldemoura@f5.com         NXT_ERROR,
2561306St.nateldemoura@f5.com         nxt_string("unprivileged unit disallow supplementary groups for "
2571306St.nateldemoura@f5.com                     "new namespace (user \"johndoe\" has 3 groups).")
2581306St.nateldemoura@f5.com     },
2591306St.nateldemoura@f5.com 
2601306St.nateldemoura@f5.com     /* privileged unit */
2611306St.nateldemoura@f5.com 
2621306St.nateldemoura@f5.com     /* not root with capabilities */
2631306St.nateldemoura@f5.com     {
2641306St.nateldemoura@f5.com         GIDMAP,
2651306St.nateldemoura@f5.com         nxt_string("[]"),
2661306St.nateldemoura@f5.com         1,
2671306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 0, NULL},
2681306St.nateldemoura@f5.com         1000, 1000,
2691306St.nateldemoura@f5.com         NXT_OK,
2701306St.nateldemoura@f5.com         nxt_string("")
2711306St.nateldemoura@f5.com     },
2721306St.nateldemoura@f5.com     {
2731306St.nateldemoura@f5.com         GIDMAP,
2741306St.nateldemoura@f5.com         nxt_string(""),
2751306St.nateldemoura@f5.com         1,
2761306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 0, NULL},
2771306St.nateldemoura@f5.com         1000, 1000,
2781306St.nateldemoura@f5.com         NXT_OK,
2791306St.nateldemoura@f5.com         nxt_string("")
2801306St.nateldemoura@f5.com     },
2811306St.nateldemoura@f5.com     {
2821306St.nateldemoura@f5.com         /* missing gid of {"user": "nobody"} */
2831306St.nateldemoura@f5.com         GIDMAP,
2841306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}]"),
2851306St.nateldemoura@f5.com         1,
2861306St.nateldemoura@f5.com         {"nobody", 65534, 65534, 0, NULL},
2871306St.nateldemoura@f5.com         1000, 1000,
2881306St.nateldemoura@f5.com         NXT_ERROR,
2891306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has no \"container\" entry for "
2901306St.nateldemoura@f5.com                     "gid 65534.")
2911306St.nateldemoura@f5.com     },
2921306St.nateldemoura@f5.com     {
2931306St.nateldemoura@f5.com         /* solves the previous by mapping 65534 gids */
2941306St.nateldemoura@f5.com         GIDMAP,
2951306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 65535}]"),
2961306St.nateldemoura@f5.com         1,
2971306St.nateldemoura@f5.com         {"nobody", 65534, 65534, 0, NULL},
2981306St.nateldemoura@f5.com         1000, 1000,
2991306St.nateldemoura@f5.com         NXT_OK,
3001306St.nateldemoura@f5.com         nxt_string("")
3011306St.nateldemoura@f5.com     },
3021306St.nateldemoura@f5.com     {
3031306St.nateldemoura@f5.com         /* solves by adding a separate mapping */
3041306St.nateldemoura@f5.com         GIDMAP,
3051306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1},"
3061306St.nateldemoura@f5.com                    " {\"container\": 65534, \"host\": 1000, \"size\": 1}]"),
3071306St.nateldemoura@f5.com         1,
3081306St.nateldemoura@f5.com         {"nobody", 65534, 65534, 0, NULL},
3091306St.nateldemoura@f5.com         1000, 1000,
3101306St.nateldemoura@f5.com         NXT_OK,
3111306St.nateldemoura@f5.com         nxt_string("")
3121306St.nateldemoura@f5.com     },
3131306St.nateldemoura@f5.com     {
3141306St.nateldemoura@f5.com         /*
3151306St.nateldemoura@f5.com          * Map a big range
3161306St.nateldemoura@f5.com          */
3171306St.nateldemoura@f5.com         GIDMAP,
3181306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 0, \"size\": 200000}]"),
3191306St.nateldemoura@f5.com         1,
3201306St.nateldemoura@f5.com         {"johndoe", 100000, 100000, 0, NULL},
3211306St.nateldemoura@f5.com         1000, 1000,
3221306St.nateldemoura@f5.com         NXT_OK,
3231306St.nateldemoura@f5.com         nxt_string("")
3241306St.nateldemoura@f5.com     },
3251306St.nateldemoura@f5.com     {
3261306St.nateldemoura@f5.com         /*
3271306St.nateldemoura@f5.com          * Validate if supplementary groups are mapped
3281306St.nateldemoura@f5.com          */
3291306St.nateldemoura@f5.com         GIDMAP,
3301306St.nateldemoura@f5.com         nxt_string("[]"),
3311306St.nateldemoura@f5.com         1,
3321306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 3, gids},
3331306St.nateldemoura@f5.com         1000, 1000,
3341306St.nateldemoura@f5.com         NXT_ERROR,
3351306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has no entries but user \"johndoe\" "
3361306St.nateldemoura@f5.com                    "has 3 suplementary groups."),
3371306St.nateldemoura@f5.com     },
3381306St.nateldemoura@f5.com     {
3391306St.nateldemoura@f5.com         GIDMAP,
3401306St.nateldemoura@f5.com         nxt_string("[{\"container\": 0, \"host\": 0, \"size\": 1}]"),
3411306St.nateldemoura@f5.com         1,
3421306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 3, gids},
3431306St.nateldemoura@f5.com         1000, 1000,
3441306St.nateldemoura@f5.com         NXT_ERROR,
3451306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has no \"container\" entry for "
3461306St.nateldemoura@f5.com                    "gid 1000."),
3471306St.nateldemoura@f5.com     },
3481306St.nateldemoura@f5.com     {
3491306St.nateldemoura@f5.com         GIDMAP,
3501306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 0, \"size\": 1}]"),
3511306St.nateldemoura@f5.com         1,
3521306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 3, gids},
3531306St.nateldemoura@f5.com         1000, 1000,
3541306St.nateldemoura@f5.com         NXT_ERROR,
3551306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has missing suplementary gid mappings "
3561306St.nateldemoura@f5.com                    "(found 1 out of 3)."),
3571306St.nateldemoura@f5.com     },
3581306St.nateldemoura@f5.com     {
3591306St.nateldemoura@f5.com         GIDMAP,
3601306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 0, \"size\": 1},"
3611306St.nateldemoura@f5.com                    " {\"container\": 10000, \"host\": 10000, \"size\": 1}]"),
3621306St.nateldemoura@f5.com         1,
3631306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 3, gids},
3641306St.nateldemoura@f5.com         1000, 1000,
3651306St.nateldemoura@f5.com         NXT_ERROR,
3661306St.nateldemoura@f5.com         nxt_string("\"gidmap\" field has missing suplementary gid mappings "
3671306St.nateldemoura@f5.com                    "(found 2 out of 3)."),
3681306St.nateldemoura@f5.com     },
3691306St.nateldemoura@f5.com     {
3701306St.nateldemoura@f5.com         /*
3711306St.nateldemoura@f5.com          * Fix all mappings
3721306St.nateldemoura@f5.com          */
3731306St.nateldemoura@f5.com         GIDMAP,
3741306St.nateldemoura@f5.com         nxt_string("[{\"container\": 1000, \"host\": 0, \"size\": 1},"
3751306St.nateldemoura@f5.com                    "{\"container\": 10000, \"host\": 10000, \"size\": 1},"
3761306St.nateldemoura@f5.com                    " {\"container\": 60000, \"host\": 60000, \"size\": 1}]"),
3771306St.nateldemoura@f5.com         1,
3781306St.nateldemoura@f5.com         {"johndoe", 1000, 1000, 3, gids},
3791306St.nateldemoura@f5.com         1000, 1000,
3801306St.nateldemoura@f5.com         NXT_OK,
3811306St.nateldemoura@f5.com         nxt_string(""),
3821306St.nateldemoura@f5.com     },
3831306St.nateldemoura@f5.com };
3841306St.nateldemoura@f5.com 
3851306St.nateldemoura@f5.com 
3861306St.nateldemoura@f5.com void nxt_cdecl
nxt_clone_test_log_handler(nxt_uint_t level,nxt_log_t * log,const char * fmt,...)3871306St.nateldemoura@f5.com nxt_clone_test_log_handler(nxt_uint_t level, nxt_log_t *log,
3881306St.nateldemoura@f5.com     const char *fmt, ...)
3891306St.nateldemoura@f5.com {
3901306St.nateldemoura@f5.com     u_char                      *p, *end;
3911306St.nateldemoura@f5.com     va_list                     args;
3921306St.nateldemoura@f5.com     nxt_clone_creds_ctx_t       *ctx;
3931306St.nateldemoura@f5.com     nxt_clone_creds_testcase_t  *tc;
3941306St.nateldemoura@f5.com     u_char                      msg[NXT_MAX_ERROR_STR];
3951306St.nateldemoura@f5.com 
3961306St.nateldemoura@f5.com     p = msg;
3971306St.nateldemoura@f5.com     end = msg + NXT_MAX_ERROR_STR;
3981306St.nateldemoura@f5.com 
3991306St.nateldemoura@f5.com     ctx = log->ctx;
4001306St.nateldemoura@f5.com     tc = ctx->tc;
4011306St.nateldemoura@f5.com 
4021306St.nateldemoura@f5.com     va_start(args, fmt);
4031306St.nateldemoura@f5.com     p = nxt_vsprintf(p, end, fmt, args);
4041306St.nateldemoura@f5.com     va_end(args);
4051306St.nateldemoura@f5.com 
4061306St.nateldemoura@f5.com     *p++ = '\0';
4071306St.nateldemoura@f5.com 
4081306St.nateldemoura@f5.com     if (tc->result == NXT_OK && level == NXT_LOG_DEBUG) {
4091306St.nateldemoura@f5.com         return;
4101306St.nateldemoura@f5.com     }
4111306St.nateldemoura@f5.com 
4121306St.nateldemoura@f5.com     if (tc->errmsg.length == 0) {
4131306St.nateldemoura@f5.com         nxt_log_error(NXT_LOG_ERR, &nxt_main_log, "unexpected log: %s", msg);
4141306St.nateldemoura@f5.com         return;
4151306St.nateldemoura@f5.com     }
4161306St.nateldemoura@f5.com 
4171306St.nateldemoura@f5.com     if (!nxt_str_eq(&tc->errmsg, msg, (nxt_uint_t) (p - msg - 1))) {
4181306St.nateldemoura@f5.com         nxt_log_error(NXT_LOG_ERR, &nxt_main_log,
4191306St.nateldemoura@f5.com                       "error log mismatch: got [%s] but wants [%V]",
4201306St.nateldemoura@f5.com                       msg, &tc->errmsg);
4211306St.nateldemoura@f5.com         return;
4221306St.nateldemoura@f5.com     }
4231306St.nateldemoura@f5.com }
4241306St.nateldemoura@f5.com 
4251306St.nateldemoura@f5.com 
4261306St.nateldemoura@f5.com nxt_int_t
nxt_clone_creds_test(nxt_thread_t * thr)4271306St.nateldemoura@f5.com nxt_clone_creds_test(nxt_thread_t *thr)
4281306St.nateldemoura@f5.com {
4291306St.nateldemoura@f5.com     nxt_mp_t               *mp;
4301306St.nateldemoura@f5.com     nxt_int_t              ret;
4311306St.nateldemoura@f5.com     nxt_uint_t             count, i;
4321306St.nateldemoura@f5.com     nxt_task_t             *task;
4331306St.nateldemoura@f5.com     nxt_runtime_t          rt;
4341306St.nateldemoura@f5.com     nxt_clone_creds_ctx_t  ctx;
4351306St.nateldemoura@f5.com 
4361306St.nateldemoura@f5.com     nxt_log_t nxt_clone_creds_log = {
4371306St.nateldemoura@f5.com         NXT_LOG_INFO,
4381306St.nateldemoura@f5.com         0,
4391306St.nateldemoura@f5.com         nxt_clone_test_log_handler,
4401306St.nateldemoura@f5.com         NULL,
4411306St.nateldemoura@f5.com         &ctx
4421306St.nateldemoura@f5.com     };
4431306St.nateldemoura@f5.com 
4441306St.nateldemoura@f5.com     nxt_thread_time_update(thr);
4451306St.nateldemoura@f5.com 
4461306St.nateldemoura@f5.com     thr->runtime = &rt;
4471306St.nateldemoura@f5.com 
4481306St.nateldemoura@f5.com     task = thr->task;
4491306St.nateldemoura@f5.com 
4501306St.nateldemoura@f5.com     mp = nxt_mp_create(1024, 128, 256, 32);
4511306St.nateldemoura@f5.com     if (mp == NULL) {
4521306St.nateldemoura@f5.com         return NXT_ERROR;
4531306St.nateldemoura@f5.com     }
4541306St.nateldemoura@f5.com 
4551306St.nateldemoura@f5.com     rt.mem_pool = mp;
4561306St.nateldemoura@f5.com 
4571306St.nateldemoura@f5.com     test_log = task->log;
4581306St.nateldemoura@f5.com     task->log = &nxt_clone_creds_log;
4591306St.nateldemoura@f5.com     task->thread = thr;
4601306St.nateldemoura@f5.com 
4611306St.nateldemoura@f5.com     count = sizeof(testcases)/sizeof(nxt_clone_creds_testcase_t);
4621306St.nateldemoura@f5.com 
4631306St.nateldemoura@f5.com     for (i = 0; i < count; i++) {
4641306St.nateldemoura@f5.com         ret = nxt_clone_test_mappings(task, mp, &ctx, &testcases[i]);
4651306St.nateldemoura@f5.com 
4661306St.nateldemoura@f5.com         if (ret != NXT_OK) {
4671306St.nateldemoura@f5.com             goto fail;
4681306St.nateldemoura@f5.com         }
4691306St.nateldemoura@f5.com     }
4701306St.nateldemoura@f5.com 
4711306St.nateldemoura@f5.com     ret = NXT_OK;
4721306St.nateldemoura@f5.com 
4731306St.nateldemoura@f5.com     nxt_log_error(NXT_LOG_NOTICE, test_log, "clone creds test passed");
4741306St.nateldemoura@f5.com 
4751306St.nateldemoura@f5.com fail:
4761306St.nateldemoura@f5.com     task->log = test_log;
4771306St.nateldemoura@f5.com     nxt_mp_destroy(mp);
4781306St.nateldemoura@f5.com 
4791306St.nateldemoura@f5.com     return ret;
4801306St.nateldemoura@f5.com }
4811306St.nateldemoura@f5.com 
4821306St.nateldemoura@f5.com 
4831306St.nateldemoura@f5.com nxt_int_t
nxt_clone_test_mappings(nxt_task_t * task,nxt_mp_t * mp,nxt_clone_creds_ctx_t * ctx,nxt_clone_creds_testcase_t * tc)4841306St.nateldemoura@f5.com nxt_clone_test_mappings(nxt_task_t *task, nxt_mp_t *mp,
4851306St.nateldemoura@f5.com     nxt_clone_creds_ctx_t *ctx, nxt_clone_creds_testcase_t *tc)
4861306St.nateldemoura@f5.com {
4871306St.nateldemoura@f5.com     nxt_int_t                   ret;
4881306St.nateldemoura@f5.com     nxt_runtime_t               *rt;
4891306St.nateldemoura@f5.com     nxt_clone_credential_map_t  map;
4901306St.nateldemoura@f5.com 
4911306St.nateldemoura@f5.com     rt = task->thread->runtime;
4921306St.nateldemoura@f5.com 
4931306St.nateldemoura@f5.com     map.size = 0;
4941306St.nateldemoura@f5.com 
4951306St.nateldemoura@f5.com     if (tc->map_data.length > 0) {
4961306St.nateldemoura@f5.com         ret = nxt_clone_test_parse_map(task, &tc->map_data, &map);
4971306St.nateldemoura@f5.com         if (ret != NXT_OK) {
4981306St.nateldemoura@f5.com             return NXT_ERROR;
4991306St.nateldemoura@f5.com         }
5001306St.nateldemoura@f5.com     }
5011306St.nateldemoura@f5.com 
5021306St.nateldemoura@f5.com     rt->capabilities.setid = tc->setid;
5031306St.nateldemoura@f5.com 
5041306St.nateldemoura@f5.com     nxt_euid = tc->unit_euid;
5051306St.nateldemoura@f5.com     nxt_egid = tc->unit_egid;
5061306St.nateldemoura@f5.com 
5071306St.nateldemoura@f5.com     ctx->tc = tc;
5081306St.nateldemoura@f5.com 
5091306St.nateldemoura@f5.com     if (nxt_clone_test_map_assert(task, tc, &map) != NXT_OK) {
5101306St.nateldemoura@f5.com         return NXT_ERROR;
5111306St.nateldemoura@f5.com     }
5121306St.nateldemoura@f5.com 
5131306St.nateldemoura@f5.com     if (tc->setid && nxt_euid != 0) {
5141306St.nateldemoura@f5.com         /*
5151306St.nateldemoura@f5.com          * Running as root should have the same behavior as
5161306St.nateldemoura@f5.com          * passing Linux capabilities.
5171306St.nateldemoura@f5.com          */
5181306St.nateldemoura@f5.com 
5191306St.nateldemoura@f5.com         nxt_euid = 0;
5201306St.nateldemoura@f5.com         nxt_egid = 0;
5211306St.nateldemoura@f5.com 
5221306St.nateldemoura@f5.com         if (nxt_clone_test_map_assert(task, tc, &map) != NXT_OK) {
5231306St.nateldemoura@f5.com             return NXT_ERROR;
5241306St.nateldemoura@f5.com         }
5251306St.nateldemoura@f5.com     }
5261306St.nateldemoura@f5.com 
5271306St.nateldemoura@f5.com     return NXT_OK;
5281306St.nateldemoura@f5.com }
5291306St.nateldemoura@f5.com 
5301306St.nateldemoura@f5.com 
5311306St.nateldemoura@f5.com nxt_int_t
nxt_clone_test_map_assert(nxt_task_t * task,nxt_clone_creds_testcase_t * tc,nxt_clone_credential_map_t * map)5321306St.nateldemoura@f5.com nxt_clone_test_map_assert(nxt_task_t *task, nxt_clone_creds_testcase_t *tc,
5331306St.nateldemoura@f5.com     nxt_clone_credential_map_t *map)
5341306St.nateldemoura@f5.com {
5351306St.nateldemoura@f5.com     nxt_int_t ret;
5361306St.nateldemoura@f5.com 
5371306St.nateldemoura@f5.com     if (tc->map_type == UIDMAP) {
5381306St.nateldemoura@f5.com         ret = nxt_clone_vldt_credential_uidmap(task, map, &tc->creds);
5391306St.nateldemoura@f5.com     } else {
5401306St.nateldemoura@f5.com         ret = nxt_clone_vldt_credential_gidmap(task, map, &tc->creds);
5411306St.nateldemoura@f5.com     }
5421306St.nateldemoura@f5.com 
5431306St.nateldemoura@f5.com     if (ret != tc->result) {
5441306St.nateldemoura@f5.com         nxt_log_error(NXT_LOG_ERR, &nxt_main_log,
5451306St.nateldemoura@f5.com                       "return %d instead of %d (map: %V)", ret, tc->result,
5461306St.nateldemoura@f5.com                       &tc->map_data);
5471306St.nateldemoura@f5.com 
5481306St.nateldemoura@f5.com         return NXT_ERROR;
5491306St.nateldemoura@f5.com     }
5501306St.nateldemoura@f5.com 
5511306St.nateldemoura@f5.com     return NXT_OK;
5521306St.nateldemoura@f5.com }
5531306St.nateldemoura@f5.com 
5541306St.nateldemoura@f5.com 
5551306St.nateldemoura@f5.com static nxt_int_t
nxt_clone_test_parse_map(nxt_task_t * task,nxt_str_t * map_str,nxt_clone_credential_map_t * map)5561306St.nateldemoura@f5.com nxt_clone_test_parse_map(nxt_task_t *task, nxt_str_t *map_str,
5571306St.nateldemoura@f5.com     nxt_clone_credential_map_t *map)
5581306St.nateldemoura@f5.com {
5591306St.nateldemoura@f5.com     nxt_uint_t        i;
5601306St.nateldemoura@f5.com     nxt_runtime_t     *rt;
5611306St.nateldemoura@f5.com     nxt_conf_value_t  *array, *obj, *value;
5621306St.nateldemoura@f5.com 
5631306St.nateldemoura@f5.com     static nxt_str_t  host_name = nxt_string("host");
5641306St.nateldemoura@f5.com     static nxt_str_t  cont_name = nxt_string("container");
5651306St.nateldemoura@f5.com     static nxt_str_t  size_name = nxt_string("size");
5661306St.nateldemoura@f5.com 
5671306St.nateldemoura@f5.com     rt = task->thread->runtime;
5681306St.nateldemoura@f5.com 
5691306St.nateldemoura@f5.com     array = nxt_conf_json_parse_str(rt->mem_pool, map_str);
5701306St.nateldemoura@f5.com     if (array == NULL) {
5711306St.nateldemoura@f5.com         return NXT_ERROR;
5721306St.nateldemoura@f5.com     }
5731306St.nateldemoura@f5.com 
5741306St.nateldemoura@f5.com     map->size = nxt_conf_array_elements_count(array);
5751306St.nateldemoura@f5.com 
5761306St.nateldemoura@f5.com     if (map->size == 0) {
5771306St.nateldemoura@f5.com         return NXT_OK;
5781306St.nateldemoura@f5.com     }
5791306St.nateldemoura@f5.com 
5801306St.nateldemoura@f5.com     map->map = nxt_mp_alloc(rt->mem_pool,
5811306St.nateldemoura@f5.com                             map->size * sizeof(nxt_clone_map_entry_t));
5821306St.nateldemoura@f5.com 
5831306St.nateldemoura@f5.com     if (map->map == NULL) {
5841306St.nateldemoura@f5.com         return NXT_ERROR;
5851306St.nateldemoura@f5.com     }
5861306St.nateldemoura@f5.com 
5871306St.nateldemoura@f5.com     for (i = 0; i < map->size; i++) {
5881306St.nateldemoura@f5.com         obj = nxt_conf_get_array_element(array, i);
5891306St.nateldemoura@f5.com 
5901306St.nateldemoura@f5.com         value = nxt_conf_get_object_member(obj, &host_name, NULL);
591*1439Svbart@nginx.com         map->map[i].host = nxt_conf_get_number(value);
5921306St.nateldemoura@f5.com 
5931306St.nateldemoura@f5.com         value = nxt_conf_get_object_member(obj, &cont_name, NULL);
594*1439Svbart@nginx.com         map->map[i].container = nxt_conf_get_number(value);
5951306St.nateldemoura@f5.com 
5961306St.nateldemoura@f5.com         value = nxt_conf_get_object_member(obj, &size_name, NULL);
597*1439Svbart@nginx.com         map->map[i].size = nxt_conf_get_number(value);
5981306St.nateldemoura@f5.com     }
5991306St.nateldemoura@f5.com 
6001306St.nateldemoura@f5.com     return NXT_OK;
6011306St.nateldemoura@f5.com }
602