1*1306St.nateldemoura@f5.com /* 2*1306St.nateldemoura@f5.com * Copyright (C) NGINX, Inc. 3*1306St.nateldemoura@f5.com * Copyright (C) Valentin V. Bartenev 4*1306St.nateldemoura@f5.com */ 5*1306St.nateldemoura@f5.com 6*1306St.nateldemoura@f5.com #include <nxt_main.h> 7*1306St.nateldemoura@f5.com #include <nxt_conf.h> 8*1306St.nateldemoura@f5.com #include "nxt_tests.h" 9*1306St.nateldemoura@f5.com 10*1306St.nateldemoura@f5.com 11*1306St.nateldemoura@f5.com #define UIDMAP 1 12*1306St.nateldemoura@f5.com #define GIDMAP 2 13*1306St.nateldemoura@f5.com 14*1306St.nateldemoura@f5.com 15*1306St.nateldemoura@f5.com typedef struct { 16*1306St.nateldemoura@f5.com nxt_int_t map_type; 17*1306St.nateldemoura@f5.com nxt_str_t map_data; 18*1306St.nateldemoura@f5.com nxt_int_t setid; 19*1306St.nateldemoura@f5.com nxt_credential_t creds; 20*1306St.nateldemoura@f5.com nxt_uid_t unit_euid; 21*1306St.nateldemoura@f5.com nxt_gid_t unit_egid; 22*1306St.nateldemoura@f5.com nxt_int_t result; 23*1306St.nateldemoura@f5.com nxt_str_t errmsg; 24*1306St.nateldemoura@f5.com } nxt_clone_creds_testcase_t; 25*1306St.nateldemoura@f5.com 26*1306St.nateldemoura@f5.com typedef struct { 27*1306St.nateldemoura@f5.com nxt_clone_creds_testcase_t *tc; 28*1306St.nateldemoura@f5.com } nxt_clone_creds_ctx_t; 29*1306St.nateldemoura@f5.com 30*1306St.nateldemoura@f5.com 31*1306St.nateldemoura@f5.com nxt_int_t nxt_clone_test_mappings(nxt_task_t *task, nxt_mp_t *mp, 32*1306St.nateldemoura@f5.com nxt_clone_creds_ctx_t *ctx, nxt_clone_creds_testcase_t *tc); 33*1306St.nateldemoura@f5.com void nxt_cdecl nxt_clone_test_log_handler(nxt_uint_t level, nxt_log_t *log, 34*1306St.nateldemoura@f5.com const char *fmt, ...); 35*1306St.nateldemoura@f5.com nxt_int_t nxt_clone_test_map_assert(nxt_task_t *task, 36*1306St.nateldemoura@f5.com nxt_clone_creds_testcase_t *tc, nxt_clone_credential_map_t *map); 37*1306St.nateldemoura@f5.com static nxt_int_t nxt_clone_test_parse_map(nxt_task_t *task, 38*1306St.nateldemoura@f5.com nxt_str_t *map_str, nxt_clone_credential_map_t *map); 39*1306St.nateldemoura@f5.com 40*1306St.nateldemoura@f5.com 41*1306St.nateldemoura@f5.com nxt_log_t *test_log; 42*1306St.nateldemoura@f5.com 43*1306St.nateldemoura@f5.com static nxt_gid_t gids[] = {1000, 10000, 60000}; 44*1306St.nateldemoura@f5.com 45*1306St.nateldemoura@f5.com static nxt_clone_creds_testcase_t testcases[] = { 46*1306St.nateldemoura@f5.com { 47*1306St.nateldemoura@f5.com /* 48*1306St.nateldemoura@f5.com * Unprivileged unit 49*1306St.nateldemoura@f5.com * 50*1306St.nateldemoura@f5.com * if no uid mapping and app creds and unit creds are the same, 51*1306St.nateldemoura@f5.com * then we automatically add a map for the creds->uid. 52*1306St.nateldemoura@f5.com * Then, child process can safely setuid(creds->uid) in 53*1306St.nateldemoura@f5.com * the new namespace. 54*1306St.nateldemoura@f5.com */ 55*1306St.nateldemoura@f5.com UIDMAP, 56*1306St.nateldemoura@f5.com nxt_string(""), 57*1306St.nateldemoura@f5.com 0, 58*1306St.nateldemoura@f5.com {"nobody", 65534, 65534, 0, NULL}, 59*1306St.nateldemoura@f5.com 1000, 1000, 60*1306St.nateldemoura@f5.com NXT_OK, 61*1306St.nateldemoura@f5.com nxt_string("") 62*1306St.nateldemoura@f5.com }, 63*1306St.nateldemoura@f5.com { 64*1306St.nateldemoura@f5.com UIDMAP, 65*1306St.nateldemoura@f5.com nxt_string(""), 66*1306St.nateldemoura@f5.com 0, 67*1306St.nateldemoura@f5.com {"johndoe", 10000, 10000, 0, NULL}, 68*1306St.nateldemoura@f5.com 1000, 1000, 69*1306St.nateldemoura@f5.com NXT_OK, 70*1306St.nateldemoura@f5.com nxt_string("") 71*1306St.nateldemoura@f5.com }, 72*1306St.nateldemoura@f5.com { 73*1306St.nateldemoura@f5.com UIDMAP, 74*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 1000, \"size\": 1}]"), 75*1306St.nateldemoura@f5.com 0, 76*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 0, NULL}, 77*1306St.nateldemoura@f5.com 1000, 1000, 78*1306St.nateldemoura@f5.com NXT_OK, 79*1306St.nateldemoura@f5.com nxt_string("") 80*1306St.nateldemoura@f5.com }, 81*1306St.nateldemoura@f5.com { 82*1306St.nateldemoura@f5.com UIDMAP, 83*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}]"), 84*1306St.nateldemoura@f5.com 0, 85*1306St.nateldemoura@f5.com {"root", 0, 0, 0, NULL}, 86*1306St.nateldemoura@f5.com 1000, 1000, 87*1306St.nateldemoura@f5.com NXT_OK, 88*1306St.nateldemoura@f5.com nxt_string("") 89*1306St.nateldemoura@f5.com }, 90*1306St.nateldemoura@f5.com { 91*1306St.nateldemoura@f5.com UIDMAP, 92*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 65534, \"host\": 1000, \"size\": 1}]"), 93*1306St.nateldemoura@f5.com 0, 94*1306St.nateldemoura@f5.com {"nobody", 65534, 0, 0, NULL}, 95*1306St.nateldemoura@f5.com 1000, 1000, 96*1306St.nateldemoura@f5.com NXT_OK, 97*1306St.nateldemoura@f5.com nxt_string("") 98*1306St.nateldemoura@f5.com }, 99*1306St.nateldemoura@f5.com { 100*1306St.nateldemoura@f5.com UIDMAP, 101*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}," 102*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1}]"), 103*1306St.nateldemoura@f5.com 0, 104*1306St.nateldemoura@f5.com {"root", 0, 0, 0, NULL}, 105*1306St.nateldemoura@f5.com 1000, 1000, 106*1306St.nateldemoura@f5.com NXT_ERROR, 107*1306St.nateldemoura@f5.com nxt_string("\"uidmap\" field has 2 entries but unprivileged unit has " 108*1306St.nateldemoura@f5.com "a maximum of 1 map.") 109*1306St.nateldemoura@f5.com }, 110*1306St.nateldemoura@f5.com { 111*1306St.nateldemoura@f5.com UIDMAP, 112*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}," 113*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1}]"), 114*1306St.nateldemoura@f5.com 1, /* privileged */ 115*1306St.nateldemoura@f5.com {"root", 0, 0, 0, NULL}, 116*1306St.nateldemoura@f5.com 1000, 1000, 117*1306St.nateldemoura@f5.com NXT_OK, 118*1306St.nateldemoura@f5.com nxt_string("") 119*1306St.nateldemoura@f5.com }, 120*1306St.nateldemoura@f5.com { 121*1306St.nateldemoura@f5.com UIDMAP, 122*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000}," 123*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"), 124*1306St.nateldemoura@f5.com 1, /* privileged */ 125*1306St.nateldemoura@f5.com {"johndoe", 500, 0, 0, NULL}, 126*1306St.nateldemoura@f5.com 1000, 1000, 127*1306St.nateldemoura@f5.com NXT_OK, 128*1306St.nateldemoura@f5.com nxt_string("") 129*1306St.nateldemoura@f5.com }, 130*1306St.nateldemoura@f5.com { 131*1306St.nateldemoura@f5.com UIDMAP, 132*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000}," 133*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"), 134*1306St.nateldemoura@f5.com 1, /* privileged */ 135*1306St.nateldemoura@f5.com {"johndoe", 1000, 0, 0, NULL}, 136*1306St.nateldemoura@f5.com 1000, 1000, 137*1306St.nateldemoura@f5.com NXT_OK, 138*1306St.nateldemoura@f5.com nxt_string("") 139*1306St.nateldemoura@f5.com }, 140*1306St.nateldemoura@f5.com { 141*1306St.nateldemoura@f5.com UIDMAP, 142*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000}," 143*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"), 144*1306St.nateldemoura@f5.com 1, /* privileged */ 145*1306St.nateldemoura@f5.com {"johndoe", 1500, 0, 0, NULL}, 146*1306St.nateldemoura@f5.com 1000, 1000, 147*1306St.nateldemoura@f5.com NXT_OK, 148*1306St.nateldemoura@f5.com nxt_string("") 149*1306St.nateldemoura@f5.com }, 150*1306St.nateldemoura@f5.com { 151*1306St.nateldemoura@f5.com UIDMAP, 152*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000}," 153*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"), 154*1306St.nateldemoura@f5.com 1, /* privileged */ 155*1306St.nateldemoura@f5.com {"johndoe", 1999, 0, 0, NULL}, 156*1306St.nateldemoura@f5.com 1000, 1000, 157*1306St.nateldemoura@f5.com NXT_OK, 158*1306St.nateldemoura@f5.com nxt_string("") 159*1306St.nateldemoura@f5.com }, 160*1306St.nateldemoura@f5.com { 161*1306St.nateldemoura@f5.com UIDMAP, 162*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1000}," 163*1306St.nateldemoura@f5.com " {\"container\": 1000, \"host\": 2000, \"size\": 1000}]"), 164*1306St.nateldemoura@f5.com 1, /* privileged */ 165*1306St.nateldemoura@f5.com {"johndoe", 2000, 0, 0, NULL}, 166*1306St.nateldemoura@f5.com 1000, 1000, 167*1306St.nateldemoura@f5.com NXT_ERROR, 168*1306St.nateldemoura@f5.com nxt_string("\"uidmap\" field has no \"container\" entry for user " 169*1306St.nateldemoura@f5.com "\"johndoe\" (uid 2000)") 170*1306St.nateldemoura@f5.com }, 171*1306St.nateldemoura@f5.com { 172*1306St.nateldemoura@f5.com /* 173*1306St.nateldemoura@f5.com * Unprivileged unit 174*1306St.nateldemoura@f5.com * 175*1306St.nateldemoura@f5.com * if no gid mapping and app creds and unit creds are the same, 176*1306St.nateldemoura@f5.com * then we automatically add a map for the creds->base_gid. 177*1306St.nateldemoura@f5.com * Then, child process can safely setgid(creds->base_gid) in 178*1306St.nateldemoura@f5.com * the new namespace. 179*1306St.nateldemoura@f5.com */ 180*1306St.nateldemoura@f5.com GIDMAP, 181*1306St.nateldemoura@f5.com nxt_string("[]"), 182*1306St.nateldemoura@f5.com 0, 183*1306St.nateldemoura@f5.com {"nobody", 65534, 65534, 0, NULL}, 184*1306St.nateldemoura@f5.com 1000, 1000, 185*1306St.nateldemoura@f5.com NXT_OK, 186*1306St.nateldemoura@f5.com nxt_string("") 187*1306St.nateldemoura@f5.com }, 188*1306St.nateldemoura@f5.com { 189*1306St.nateldemoura@f5.com /* 190*1306St.nateldemoura@f5.com * Unprivileged unit 191*1306St.nateldemoura@f5.com * 192*1306St.nateldemoura@f5.com * Inside the new namespace, we can have any gid but it 193*1306St.nateldemoura@f5.com * should map to parent gid (in this case 1000) in parent 194*1306St.nateldemoura@f5.com * namespace. 195*1306St.nateldemoura@f5.com */ 196*1306St.nateldemoura@f5.com GIDMAP, 197*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}]"), 198*1306St.nateldemoura@f5.com 0, 199*1306St.nateldemoura@f5.com {"root", 0, 0, 0, NULL}, 200*1306St.nateldemoura@f5.com 1000, 1000, 201*1306St.nateldemoura@f5.com NXT_OK, 202*1306St.nateldemoura@f5.com nxt_string("") 203*1306St.nateldemoura@f5.com }, 204*1306St.nateldemoura@f5.com { 205*1306St.nateldemoura@f5.com GIDMAP, 206*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 65534, \"host\": 1000, \"size\": 1}]"), 207*1306St.nateldemoura@f5.com 0, 208*1306St.nateldemoura@f5.com {"nobody", 65534, 65534, 0, NULL}, 209*1306St.nateldemoura@f5.com 1000, 1000, 210*1306St.nateldemoura@f5.com NXT_OK, 211*1306St.nateldemoura@f5.com nxt_string("") 212*1306St.nateldemoura@f5.com }, 213*1306St.nateldemoura@f5.com { 214*1306St.nateldemoura@f5.com /* 215*1306St.nateldemoura@f5.com * Unprivileged unit 216*1306St.nateldemoura@f5.com * 217*1306St.nateldemoura@f5.com * There's no mapping for "johndoe" (gid 1000) inside the namespace. 218*1306St.nateldemoura@f5.com */ 219*1306St.nateldemoura@f5.com GIDMAP, 220*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 65535, \"host\": 1000, \"size\": 1}]"), 221*1306St.nateldemoura@f5.com 0, 222*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 0, NULL}, 223*1306St.nateldemoura@f5.com 1000, 1000, 224*1306St.nateldemoura@f5.com NXT_ERROR, 225*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has no \"container\" entry for " 226*1306St.nateldemoura@f5.com "gid 1000.") 227*1306St.nateldemoura@f5.com }, 228*1306St.nateldemoura@f5.com { 229*1306St.nateldemoura@f5.com GIDMAP, 230*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 1000, \"size\": 2}]"), 231*1306St.nateldemoura@f5.com 0, 232*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 0, NULL}, 233*1306St.nateldemoura@f5.com 1000, 1000, 234*1306St.nateldemoura@f5.com NXT_ERROR, 235*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has an entry with \"size\": 2, but " 236*1306St.nateldemoura@f5.com "for unprivileged unit it must be 1.") 237*1306St.nateldemoura@f5.com }, 238*1306St.nateldemoura@f5.com { 239*1306St.nateldemoura@f5.com GIDMAP, 240*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 1001, \"size\": 1}]"), 241*1306St.nateldemoura@f5.com 0, 242*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 0, NULL}, 243*1306St.nateldemoura@f5.com 1000, 1000, 244*1306St.nateldemoura@f5.com NXT_ERROR, 245*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has an entry for host gid 1001 but " 246*1306St.nateldemoura@f5.com "unprivileged unit can only map itself (gid 1000) " 247*1306St.nateldemoura@f5.com "into child namespaces.") 248*1306St.nateldemoura@f5.com }, 249*1306St.nateldemoura@f5.com { 250*1306St.nateldemoura@f5.com GIDMAP, 251*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 1000, \"size\": 1}]"), 252*1306St.nateldemoura@f5.com 0, 253*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 3, gids}, 254*1306St.nateldemoura@f5.com 1000, 1000, 255*1306St.nateldemoura@f5.com NXT_ERROR, 256*1306St.nateldemoura@f5.com nxt_string("unprivileged unit disallow supplementary groups for " 257*1306St.nateldemoura@f5.com "new namespace (user \"johndoe\" has 3 groups).") 258*1306St.nateldemoura@f5.com }, 259*1306St.nateldemoura@f5.com 260*1306St.nateldemoura@f5.com /* privileged unit */ 261*1306St.nateldemoura@f5.com 262*1306St.nateldemoura@f5.com /* not root with capabilities */ 263*1306St.nateldemoura@f5.com { 264*1306St.nateldemoura@f5.com GIDMAP, 265*1306St.nateldemoura@f5.com nxt_string("[]"), 266*1306St.nateldemoura@f5.com 1, 267*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 0, NULL}, 268*1306St.nateldemoura@f5.com 1000, 1000, 269*1306St.nateldemoura@f5.com NXT_OK, 270*1306St.nateldemoura@f5.com nxt_string("") 271*1306St.nateldemoura@f5.com }, 272*1306St.nateldemoura@f5.com { 273*1306St.nateldemoura@f5.com GIDMAP, 274*1306St.nateldemoura@f5.com nxt_string(""), 275*1306St.nateldemoura@f5.com 1, 276*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 0, NULL}, 277*1306St.nateldemoura@f5.com 1000, 1000, 278*1306St.nateldemoura@f5.com NXT_OK, 279*1306St.nateldemoura@f5.com nxt_string("") 280*1306St.nateldemoura@f5.com }, 281*1306St.nateldemoura@f5.com { 282*1306St.nateldemoura@f5.com /* missing gid of {"user": "nobody"} */ 283*1306St.nateldemoura@f5.com GIDMAP, 284*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}]"), 285*1306St.nateldemoura@f5.com 1, 286*1306St.nateldemoura@f5.com {"nobody", 65534, 65534, 0, NULL}, 287*1306St.nateldemoura@f5.com 1000, 1000, 288*1306St.nateldemoura@f5.com NXT_ERROR, 289*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has no \"container\" entry for " 290*1306St.nateldemoura@f5.com "gid 65534.") 291*1306St.nateldemoura@f5.com }, 292*1306St.nateldemoura@f5.com { 293*1306St.nateldemoura@f5.com /* solves the previous by mapping 65534 gids */ 294*1306St.nateldemoura@f5.com GIDMAP, 295*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 65535}]"), 296*1306St.nateldemoura@f5.com 1, 297*1306St.nateldemoura@f5.com {"nobody", 65534, 65534, 0, NULL}, 298*1306St.nateldemoura@f5.com 1000, 1000, 299*1306St.nateldemoura@f5.com NXT_OK, 300*1306St.nateldemoura@f5.com nxt_string("") 301*1306St.nateldemoura@f5.com }, 302*1306St.nateldemoura@f5.com { 303*1306St.nateldemoura@f5.com /* solves by adding a separate mapping */ 304*1306St.nateldemoura@f5.com GIDMAP, 305*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 1000, \"size\": 1}," 306*1306St.nateldemoura@f5.com " {\"container\": 65534, \"host\": 1000, \"size\": 1}]"), 307*1306St.nateldemoura@f5.com 1, 308*1306St.nateldemoura@f5.com {"nobody", 65534, 65534, 0, NULL}, 309*1306St.nateldemoura@f5.com 1000, 1000, 310*1306St.nateldemoura@f5.com NXT_OK, 311*1306St.nateldemoura@f5.com nxt_string("") 312*1306St.nateldemoura@f5.com }, 313*1306St.nateldemoura@f5.com { 314*1306St.nateldemoura@f5.com /* 315*1306St.nateldemoura@f5.com * Map a big range 316*1306St.nateldemoura@f5.com */ 317*1306St.nateldemoura@f5.com GIDMAP, 318*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 0, \"size\": 200000}]"), 319*1306St.nateldemoura@f5.com 1, 320*1306St.nateldemoura@f5.com {"johndoe", 100000, 100000, 0, NULL}, 321*1306St.nateldemoura@f5.com 1000, 1000, 322*1306St.nateldemoura@f5.com NXT_OK, 323*1306St.nateldemoura@f5.com nxt_string("") 324*1306St.nateldemoura@f5.com }, 325*1306St.nateldemoura@f5.com { 326*1306St.nateldemoura@f5.com /* 327*1306St.nateldemoura@f5.com * Validate if supplementary groups are mapped 328*1306St.nateldemoura@f5.com */ 329*1306St.nateldemoura@f5.com GIDMAP, 330*1306St.nateldemoura@f5.com nxt_string("[]"), 331*1306St.nateldemoura@f5.com 1, 332*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 3, gids}, 333*1306St.nateldemoura@f5.com 1000, 1000, 334*1306St.nateldemoura@f5.com NXT_ERROR, 335*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has no entries but user \"johndoe\" " 336*1306St.nateldemoura@f5.com "has 3 suplementary groups."), 337*1306St.nateldemoura@f5.com }, 338*1306St.nateldemoura@f5.com { 339*1306St.nateldemoura@f5.com GIDMAP, 340*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 0, \"host\": 0, \"size\": 1}]"), 341*1306St.nateldemoura@f5.com 1, 342*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 3, gids}, 343*1306St.nateldemoura@f5.com 1000, 1000, 344*1306St.nateldemoura@f5.com NXT_ERROR, 345*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has no \"container\" entry for " 346*1306St.nateldemoura@f5.com "gid 1000."), 347*1306St.nateldemoura@f5.com }, 348*1306St.nateldemoura@f5.com { 349*1306St.nateldemoura@f5.com GIDMAP, 350*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 0, \"size\": 1}]"), 351*1306St.nateldemoura@f5.com 1, 352*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 3, gids}, 353*1306St.nateldemoura@f5.com 1000, 1000, 354*1306St.nateldemoura@f5.com NXT_ERROR, 355*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has missing suplementary gid mappings " 356*1306St.nateldemoura@f5.com "(found 1 out of 3)."), 357*1306St.nateldemoura@f5.com }, 358*1306St.nateldemoura@f5.com { 359*1306St.nateldemoura@f5.com GIDMAP, 360*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 0, \"size\": 1}," 361*1306St.nateldemoura@f5.com " {\"container\": 10000, \"host\": 10000, \"size\": 1}]"), 362*1306St.nateldemoura@f5.com 1, 363*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 3, gids}, 364*1306St.nateldemoura@f5.com 1000, 1000, 365*1306St.nateldemoura@f5.com NXT_ERROR, 366*1306St.nateldemoura@f5.com nxt_string("\"gidmap\" field has missing suplementary gid mappings " 367*1306St.nateldemoura@f5.com "(found 2 out of 3)."), 368*1306St.nateldemoura@f5.com }, 369*1306St.nateldemoura@f5.com { 370*1306St.nateldemoura@f5.com /* 371*1306St.nateldemoura@f5.com * Fix all mappings 372*1306St.nateldemoura@f5.com */ 373*1306St.nateldemoura@f5.com GIDMAP, 374*1306St.nateldemoura@f5.com nxt_string("[{\"container\": 1000, \"host\": 0, \"size\": 1}," 375*1306St.nateldemoura@f5.com "{\"container\": 10000, \"host\": 10000, \"size\": 1}," 376*1306St.nateldemoura@f5.com " {\"container\": 60000, \"host\": 60000, \"size\": 1}]"), 377*1306St.nateldemoura@f5.com 1, 378*1306St.nateldemoura@f5.com {"johndoe", 1000, 1000, 3, gids}, 379*1306St.nateldemoura@f5.com 1000, 1000, 380*1306St.nateldemoura@f5.com NXT_OK, 381*1306St.nateldemoura@f5.com nxt_string(""), 382*1306St.nateldemoura@f5.com }, 383*1306St.nateldemoura@f5.com }; 384*1306St.nateldemoura@f5.com 385*1306St.nateldemoura@f5.com 386*1306St.nateldemoura@f5.com void nxt_cdecl 387*1306St.nateldemoura@f5.com nxt_clone_test_log_handler(nxt_uint_t level, nxt_log_t *log, 388*1306St.nateldemoura@f5.com const char *fmt, ...) 389*1306St.nateldemoura@f5.com { 390*1306St.nateldemoura@f5.com u_char *p, *end; 391*1306St.nateldemoura@f5.com va_list args; 392*1306St.nateldemoura@f5.com nxt_clone_creds_ctx_t *ctx; 393*1306St.nateldemoura@f5.com nxt_clone_creds_testcase_t *tc; 394*1306St.nateldemoura@f5.com u_char msg[NXT_MAX_ERROR_STR]; 395*1306St.nateldemoura@f5.com 396*1306St.nateldemoura@f5.com p = msg; 397*1306St.nateldemoura@f5.com end = msg + NXT_MAX_ERROR_STR; 398*1306St.nateldemoura@f5.com 399*1306St.nateldemoura@f5.com ctx = log->ctx; 400*1306St.nateldemoura@f5.com tc = ctx->tc; 401*1306St.nateldemoura@f5.com 402*1306St.nateldemoura@f5.com va_start(args, fmt); 403*1306St.nateldemoura@f5.com p = nxt_vsprintf(p, end, fmt, args); 404*1306St.nateldemoura@f5.com va_end(args); 405*1306St.nateldemoura@f5.com 406*1306St.nateldemoura@f5.com *p++ = '\0'; 407*1306St.nateldemoura@f5.com 408*1306St.nateldemoura@f5.com if (tc->result == NXT_OK && level == NXT_LOG_DEBUG) { 409*1306St.nateldemoura@f5.com return; 410*1306St.nateldemoura@f5.com } 411*1306St.nateldemoura@f5.com 412*1306St.nateldemoura@f5.com if (tc->errmsg.length == 0) { 413*1306St.nateldemoura@f5.com nxt_log_error(NXT_LOG_ERR, &nxt_main_log, "unexpected log: %s", msg); 414*1306St.nateldemoura@f5.com return; 415*1306St.nateldemoura@f5.com } 416*1306St.nateldemoura@f5.com 417*1306St.nateldemoura@f5.com if (!nxt_str_eq(&tc->errmsg, msg, (nxt_uint_t) (p - msg - 1))) { 418*1306St.nateldemoura@f5.com nxt_log_error(NXT_LOG_ERR, &nxt_main_log, 419*1306St.nateldemoura@f5.com "error log mismatch: got [%s] but wants [%V]", 420*1306St.nateldemoura@f5.com msg, &tc->errmsg); 421*1306St.nateldemoura@f5.com return; 422*1306St.nateldemoura@f5.com } 423*1306St.nateldemoura@f5.com } 424*1306St.nateldemoura@f5.com 425*1306St.nateldemoura@f5.com 426*1306St.nateldemoura@f5.com nxt_int_t 427*1306St.nateldemoura@f5.com nxt_clone_creds_test(nxt_thread_t *thr) 428*1306St.nateldemoura@f5.com { 429*1306St.nateldemoura@f5.com nxt_mp_t *mp; 430*1306St.nateldemoura@f5.com nxt_int_t ret; 431*1306St.nateldemoura@f5.com nxt_uint_t count, i; 432*1306St.nateldemoura@f5.com nxt_task_t *task; 433*1306St.nateldemoura@f5.com nxt_runtime_t rt; 434*1306St.nateldemoura@f5.com nxt_clone_creds_ctx_t ctx; 435*1306St.nateldemoura@f5.com 436*1306St.nateldemoura@f5.com nxt_log_t nxt_clone_creds_log = { 437*1306St.nateldemoura@f5.com NXT_LOG_INFO, 438*1306St.nateldemoura@f5.com 0, 439*1306St.nateldemoura@f5.com nxt_clone_test_log_handler, 440*1306St.nateldemoura@f5.com NULL, 441*1306St.nateldemoura@f5.com &ctx 442*1306St.nateldemoura@f5.com }; 443*1306St.nateldemoura@f5.com 444*1306St.nateldemoura@f5.com nxt_thread_time_update(thr); 445*1306St.nateldemoura@f5.com 446*1306St.nateldemoura@f5.com thr->runtime = &rt; 447*1306St.nateldemoura@f5.com 448*1306St.nateldemoura@f5.com task = thr->task; 449*1306St.nateldemoura@f5.com 450*1306St.nateldemoura@f5.com mp = nxt_mp_create(1024, 128, 256, 32); 451*1306St.nateldemoura@f5.com if (mp == NULL) { 452*1306St.nateldemoura@f5.com return NXT_ERROR; 453*1306St.nateldemoura@f5.com } 454*1306St.nateldemoura@f5.com 455*1306St.nateldemoura@f5.com rt.mem_pool = mp; 456*1306St.nateldemoura@f5.com 457*1306St.nateldemoura@f5.com test_log = task->log; 458*1306St.nateldemoura@f5.com task->log = &nxt_clone_creds_log; 459*1306St.nateldemoura@f5.com task->thread = thr; 460*1306St.nateldemoura@f5.com 461*1306St.nateldemoura@f5.com count = sizeof(testcases)/sizeof(nxt_clone_creds_testcase_t); 462*1306St.nateldemoura@f5.com 463*1306St.nateldemoura@f5.com for (i = 0; i < count; i++) { 464*1306St.nateldemoura@f5.com ret = nxt_clone_test_mappings(task, mp, &ctx, &testcases[i]); 465*1306St.nateldemoura@f5.com 466*1306St.nateldemoura@f5.com if (ret != NXT_OK) { 467*1306St.nateldemoura@f5.com goto fail; 468*1306St.nateldemoura@f5.com } 469*1306St.nateldemoura@f5.com } 470*1306St.nateldemoura@f5.com 471*1306St.nateldemoura@f5.com ret = NXT_OK; 472*1306St.nateldemoura@f5.com 473*1306St.nateldemoura@f5.com nxt_log_error(NXT_LOG_NOTICE, test_log, "clone creds test passed"); 474*1306St.nateldemoura@f5.com 475*1306St.nateldemoura@f5.com fail: 476*1306St.nateldemoura@f5.com task->log = test_log; 477*1306St.nateldemoura@f5.com nxt_mp_destroy(mp); 478*1306St.nateldemoura@f5.com 479*1306St.nateldemoura@f5.com return ret; 480*1306St.nateldemoura@f5.com } 481*1306St.nateldemoura@f5.com 482*1306St.nateldemoura@f5.com 483*1306St.nateldemoura@f5.com nxt_int_t 484*1306St.nateldemoura@f5.com nxt_clone_test_mappings(nxt_task_t *task, nxt_mp_t *mp, 485*1306St.nateldemoura@f5.com nxt_clone_creds_ctx_t *ctx, nxt_clone_creds_testcase_t *tc) 486*1306St.nateldemoura@f5.com { 487*1306St.nateldemoura@f5.com nxt_int_t ret; 488*1306St.nateldemoura@f5.com nxt_runtime_t *rt; 489*1306St.nateldemoura@f5.com nxt_clone_credential_map_t map; 490*1306St.nateldemoura@f5.com 491*1306St.nateldemoura@f5.com rt = task->thread->runtime; 492*1306St.nateldemoura@f5.com 493*1306St.nateldemoura@f5.com map.size = 0; 494*1306St.nateldemoura@f5.com 495*1306St.nateldemoura@f5.com if (tc->map_data.length > 0) { 496*1306St.nateldemoura@f5.com ret = nxt_clone_test_parse_map(task, &tc->map_data, &map); 497*1306St.nateldemoura@f5.com if (ret != NXT_OK) { 498*1306St.nateldemoura@f5.com return NXT_ERROR; 499*1306St.nateldemoura@f5.com } 500*1306St.nateldemoura@f5.com } 501*1306St.nateldemoura@f5.com 502*1306St.nateldemoura@f5.com rt->capabilities.setid = tc->setid; 503*1306St.nateldemoura@f5.com 504*1306St.nateldemoura@f5.com nxt_euid = tc->unit_euid; 505*1306St.nateldemoura@f5.com nxt_egid = tc->unit_egid; 506*1306St.nateldemoura@f5.com 507*1306St.nateldemoura@f5.com ctx->tc = tc; 508*1306St.nateldemoura@f5.com 509*1306St.nateldemoura@f5.com if (nxt_clone_test_map_assert(task, tc, &map) != NXT_OK) { 510*1306St.nateldemoura@f5.com return NXT_ERROR; 511*1306St.nateldemoura@f5.com } 512*1306St.nateldemoura@f5.com 513*1306St.nateldemoura@f5.com if (tc->setid && nxt_euid != 0) { 514*1306St.nateldemoura@f5.com /* 515*1306St.nateldemoura@f5.com * Running as root should have the same behavior as 516*1306St.nateldemoura@f5.com * passing Linux capabilities. 517*1306St.nateldemoura@f5.com */ 518*1306St.nateldemoura@f5.com 519*1306St.nateldemoura@f5.com nxt_euid = 0; 520*1306St.nateldemoura@f5.com nxt_egid = 0; 521*1306St.nateldemoura@f5.com 522*1306St.nateldemoura@f5.com if (nxt_clone_test_map_assert(task, tc, &map) != NXT_OK) { 523*1306St.nateldemoura@f5.com return NXT_ERROR; 524*1306St.nateldemoura@f5.com } 525*1306St.nateldemoura@f5.com } 526*1306St.nateldemoura@f5.com 527*1306St.nateldemoura@f5.com return NXT_OK; 528*1306St.nateldemoura@f5.com } 529*1306St.nateldemoura@f5.com 530*1306St.nateldemoura@f5.com 531*1306St.nateldemoura@f5.com nxt_int_t 532*1306St.nateldemoura@f5.com nxt_clone_test_map_assert(nxt_task_t *task, nxt_clone_creds_testcase_t *tc, 533*1306St.nateldemoura@f5.com nxt_clone_credential_map_t *map) 534*1306St.nateldemoura@f5.com { 535*1306St.nateldemoura@f5.com nxt_int_t ret; 536*1306St.nateldemoura@f5.com 537*1306St.nateldemoura@f5.com if (tc->map_type == UIDMAP) { 538*1306St.nateldemoura@f5.com ret = nxt_clone_vldt_credential_uidmap(task, map, &tc->creds); 539*1306St.nateldemoura@f5.com } else { 540*1306St.nateldemoura@f5.com ret = nxt_clone_vldt_credential_gidmap(task, map, &tc->creds); 541*1306St.nateldemoura@f5.com } 542*1306St.nateldemoura@f5.com 543*1306St.nateldemoura@f5.com if (ret != tc->result) { 544*1306St.nateldemoura@f5.com nxt_log_error(NXT_LOG_ERR, &nxt_main_log, 545*1306St.nateldemoura@f5.com "return %d instead of %d (map: %V)", ret, tc->result, 546*1306St.nateldemoura@f5.com &tc->map_data); 547*1306St.nateldemoura@f5.com 548*1306St.nateldemoura@f5.com return NXT_ERROR; 549*1306St.nateldemoura@f5.com } 550*1306St.nateldemoura@f5.com 551*1306St.nateldemoura@f5.com return NXT_OK; 552*1306St.nateldemoura@f5.com } 553*1306St.nateldemoura@f5.com 554*1306St.nateldemoura@f5.com 555*1306St.nateldemoura@f5.com static nxt_int_t 556*1306St.nateldemoura@f5.com nxt_clone_test_parse_map(nxt_task_t *task, nxt_str_t *map_str, 557*1306St.nateldemoura@f5.com nxt_clone_credential_map_t *map) 558*1306St.nateldemoura@f5.com { 559*1306St.nateldemoura@f5.com nxt_uint_t i; 560*1306St.nateldemoura@f5.com nxt_runtime_t *rt; 561*1306St.nateldemoura@f5.com nxt_conf_value_t *array, *obj, *value; 562*1306St.nateldemoura@f5.com 563*1306St.nateldemoura@f5.com static nxt_str_t host_name = nxt_string("host"); 564*1306St.nateldemoura@f5.com static nxt_str_t cont_name = nxt_string("container"); 565*1306St.nateldemoura@f5.com static nxt_str_t size_name = nxt_string("size"); 566*1306St.nateldemoura@f5.com 567*1306St.nateldemoura@f5.com rt = task->thread->runtime; 568*1306St.nateldemoura@f5.com 569*1306St.nateldemoura@f5.com array = nxt_conf_json_parse_str(rt->mem_pool, map_str); 570*1306St.nateldemoura@f5.com if (array == NULL) { 571*1306St.nateldemoura@f5.com return NXT_ERROR; 572*1306St.nateldemoura@f5.com } 573*1306St.nateldemoura@f5.com 574*1306St.nateldemoura@f5.com map->size = nxt_conf_array_elements_count(array); 575*1306St.nateldemoura@f5.com 576*1306St.nateldemoura@f5.com if (map->size == 0) { 577*1306St.nateldemoura@f5.com return NXT_OK; 578*1306St.nateldemoura@f5.com } 579*1306St.nateldemoura@f5.com 580*1306St.nateldemoura@f5.com map->map = nxt_mp_alloc(rt->mem_pool, 581*1306St.nateldemoura@f5.com map->size * sizeof(nxt_clone_map_entry_t)); 582*1306St.nateldemoura@f5.com 583*1306St.nateldemoura@f5.com if (map->map == NULL) { 584*1306St.nateldemoura@f5.com return NXT_ERROR; 585*1306St.nateldemoura@f5.com } 586*1306St.nateldemoura@f5.com 587*1306St.nateldemoura@f5.com for (i = 0; i < map->size; i++) { 588*1306St.nateldemoura@f5.com obj = nxt_conf_get_array_element(array, i); 589*1306St.nateldemoura@f5.com 590*1306St.nateldemoura@f5.com value = nxt_conf_get_object_member(obj, &host_name, NULL); 591*1306St.nateldemoura@f5.com map->map[i].host = nxt_conf_get_integer(value); 592*1306St.nateldemoura@f5.com 593*1306St.nateldemoura@f5.com value = nxt_conf_get_object_member(obj, &cont_name, NULL); 594*1306St.nateldemoura@f5.com map->map[i].container = nxt_conf_get_integer(value); 595*1306St.nateldemoura@f5.com 596*1306St.nateldemoura@f5.com value = nxt_conf_get_object_member(obj, &size_name, NULL); 597*1306St.nateldemoura@f5.com map->map[i].size = nxt_conf_get_integer(value); 598*1306St.nateldemoura@f5.com } 599*1306St.nateldemoura@f5.com 600*1306St.nateldemoura@f5.com return NXT_OK; 601*1306St.nateldemoura@f5.com } 602