1 /*- 2 * Copyright (c) 2013 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/capsicum.h> 34 35 #include <assert.h> 36 #include <err.h> 37 #include <errno.h> 38 #include <pwd.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 #include <libcasper.h> 45 46 #include <casper/cap_pwd.h> 47 48 static int ntest = 1; 49 50 #define CHECK(expr) do { \ 51 if ((expr)) \ 52 printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ 53 else \ 54 printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__);\ 55 ntest++; \ 56 } while (0) 57 #define CHECKX(expr) do { \ 58 if ((expr)) { \ 59 printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ 60 } else { \ 61 printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__);\ 62 exit(1); \ 63 } \ 64 ntest++; \ 65 } while (0) 66 67 #define UID_ROOT 0 68 #define UID_OPERATOR 2 69 70 #define GETPWENT0 0x0001 71 #define GETPWENT1 0x0002 72 #define GETPWENT2 0x0004 73 #define GETPWENT (GETPWENT0 | GETPWENT1 | GETPWENT2) 74 #define GETPWENT_R0 0x0008 75 #define GETPWENT_R1 0x0010 76 #define GETPWENT_R2 0x0020 77 #define GETPWENT_R (GETPWENT_R0 | GETPWENT_R1 | GETPWENT_R2) 78 #define GETPWNAM 0x0040 79 #define GETPWNAM_R 0x0080 80 #define GETPWUID 0x0100 81 #define GETPWUID_R 0x0200 82 83 static bool 84 passwd_compare(const struct passwd *pwd0, const struct passwd *pwd1) 85 { 86 87 if (pwd0 == NULL && pwd1 == NULL) 88 return (true); 89 if (pwd0 == NULL || pwd1 == NULL) 90 return (false); 91 92 if (strcmp(pwd0->pw_name, pwd1->pw_name) != 0) 93 return (false); 94 95 if (pwd0->pw_passwd != NULL || pwd1->pw_passwd != NULL) { 96 if (pwd0->pw_passwd == NULL || pwd1->pw_passwd == NULL) 97 return (false); 98 if (strcmp(pwd0->pw_passwd, pwd1->pw_passwd) != 0) 99 return (false); 100 } 101 102 if (pwd0->pw_uid != pwd1->pw_uid) 103 return (false); 104 105 if (pwd0->pw_gid != pwd1->pw_gid) 106 return (false); 107 108 if (pwd0->pw_change != pwd1->pw_change) 109 return (false); 110 111 if (pwd0->pw_class != NULL || pwd1->pw_class != NULL) { 112 if (pwd0->pw_class == NULL || pwd1->pw_class == NULL) 113 return (false); 114 if (strcmp(pwd0->pw_class, pwd1->pw_class) != 0) 115 return (false); 116 } 117 118 if (pwd0->pw_gecos != NULL || pwd1->pw_gecos != NULL) { 119 if (pwd0->pw_gecos == NULL || pwd1->pw_gecos == NULL) 120 return (false); 121 if (strcmp(pwd0->pw_gecos, pwd1->pw_gecos) != 0) 122 return (false); 123 } 124 125 if (pwd0->pw_dir != NULL || pwd1->pw_dir != NULL) { 126 if (pwd0->pw_dir == NULL || pwd1->pw_dir == NULL) 127 return (false); 128 if (strcmp(pwd0->pw_dir, pwd1->pw_dir) != 0) 129 return (false); 130 } 131 132 if (pwd0->pw_shell != NULL || pwd1->pw_shell != NULL) { 133 if (pwd0->pw_shell == NULL || pwd1->pw_shell == NULL) 134 return (false); 135 if (strcmp(pwd0->pw_shell, pwd1->pw_shell) != 0) 136 return (false); 137 } 138 139 if (pwd0->pw_expire != pwd1->pw_expire) 140 return (false); 141 142 if (pwd0->pw_fields != pwd1->pw_fields) 143 return (false); 144 145 return (true); 146 } 147 148 static unsigned int 149 runtest_cmds(cap_channel_t *cappwd) 150 { 151 char bufs[1024], bufc[1024]; 152 unsigned int result; 153 struct passwd *pwds, *pwdc; 154 struct passwd sts, stc; 155 156 result = 0; 157 158 setpwent(); 159 cap_setpwent(cappwd); 160 161 pwds = getpwent(); 162 pwdc = cap_getpwent(cappwd); 163 if (passwd_compare(pwds, pwdc)) { 164 result |= GETPWENT0; 165 pwds = getpwent(); 166 pwdc = cap_getpwent(cappwd); 167 if (passwd_compare(pwds, pwdc)) 168 result |= GETPWENT1; 169 } 170 171 getpwent_r(&sts, bufs, sizeof(bufs), &pwds); 172 cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc); 173 if (passwd_compare(pwds, pwdc)) { 174 result |= GETPWENT_R0; 175 getpwent_r(&sts, bufs, sizeof(bufs), &pwds); 176 cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc); 177 if (passwd_compare(pwds, pwdc)) 178 result |= GETPWENT_R1; 179 } 180 181 setpwent(); 182 cap_setpwent(cappwd); 183 184 getpwent_r(&sts, bufs, sizeof(bufs), &pwds); 185 cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc); 186 if (passwd_compare(pwds, pwdc)) 187 result |= GETPWENT_R2; 188 189 pwds = getpwent(); 190 pwdc = cap_getpwent(cappwd); 191 if (passwd_compare(pwds, pwdc)) 192 result |= GETPWENT2; 193 194 pwds = getpwnam("root"); 195 pwdc = cap_getpwnam(cappwd, "root"); 196 if (passwd_compare(pwds, pwdc)) { 197 pwds = getpwnam("operator"); 198 pwdc = cap_getpwnam(cappwd, "operator"); 199 if (passwd_compare(pwds, pwdc)) 200 result |= GETPWNAM; 201 } 202 203 getpwnam_r("root", &sts, bufs, sizeof(bufs), &pwds); 204 cap_getpwnam_r(cappwd, "root", &stc, bufc, sizeof(bufc), &pwdc); 205 if (passwd_compare(pwds, pwdc)) { 206 getpwnam_r("operator", &sts, bufs, sizeof(bufs), &pwds); 207 cap_getpwnam_r(cappwd, "operator", &stc, bufc, sizeof(bufc), 208 &pwdc); 209 if (passwd_compare(pwds, pwdc)) 210 result |= GETPWNAM_R; 211 } 212 213 pwds = getpwuid(UID_ROOT); 214 pwdc = cap_getpwuid(cappwd, UID_ROOT); 215 if (passwd_compare(pwds, pwdc)) { 216 pwds = getpwuid(UID_OPERATOR); 217 pwdc = cap_getpwuid(cappwd, UID_OPERATOR); 218 if (passwd_compare(pwds, pwdc)) 219 result |= GETPWUID; 220 } 221 222 getpwuid_r(UID_ROOT, &sts, bufs, sizeof(bufs), &pwds); 223 cap_getpwuid_r(cappwd, UID_ROOT, &stc, bufc, sizeof(bufc), &pwdc); 224 if (passwd_compare(pwds, pwdc)) { 225 getpwuid_r(UID_OPERATOR, &sts, bufs, sizeof(bufs), &pwds); 226 cap_getpwuid_r(cappwd, UID_OPERATOR, &stc, bufc, sizeof(bufc), 227 &pwdc); 228 if (passwd_compare(pwds, pwdc)) 229 result |= GETPWUID_R; 230 } 231 232 return (result); 233 } 234 235 static void 236 test_cmds(cap_channel_t *origcappwd) 237 { 238 cap_channel_t *cappwd; 239 const char *cmds[7], *fields[10], *names[6]; 240 uid_t uids[5]; 241 242 fields[0] = "pw_name"; 243 fields[1] = "pw_passwd"; 244 fields[2] = "pw_uid"; 245 fields[3] = "pw_gid"; 246 fields[4] = "pw_change"; 247 fields[5] = "pw_class"; 248 fields[6] = "pw_gecos"; 249 fields[7] = "pw_dir"; 250 fields[8] = "pw_shell"; 251 fields[9] = "pw_expire"; 252 253 names[0] = "root"; 254 names[1] = "toor"; 255 names[2] = "daemon"; 256 names[3] = "operator"; 257 names[4] = "bin"; 258 names[5] = "kmem"; 259 260 uids[0] = 0; 261 uids[1] = 1; 262 uids[2] = 2; 263 uids[3] = 3; 264 uids[4] = 5; 265 266 /* 267 * Allow: 268 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r, 269 * getpwuid, getpwuid_r 270 * users: 271 * names: root, toor, daemon, operator, bin, kmem 272 * uids: 273 */ 274 cappwd = cap_clone(origcappwd); 275 CHECK(cappwd != NULL); 276 277 cmds[0] = "setpwent"; 278 cmds[1] = "getpwent"; 279 cmds[2] = "getpwent_r"; 280 cmds[3] = "getpwnam"; 281 cmds[4] = "getpwnam_r"; 282 cmds[5] = "getpwuid"; 283 cmds[6] = "getpwuid_r"; 284 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == 0); 285 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 286 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 287 288 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 289 GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 290 291 cap_close(cappwd); 292 293 /* 294 * Allow: 295 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r, 296 * getpwuid, getpwuid_r 297 * users: 298 * names: 299 * uids: 0, 1, 2, 3, 5 300 */ 301 cappwd = cap_clone(origcappwd); 302 CHECK(cappwd != NULL); 303 304 cmds[0] = "setpwent"; 305 cmds[1] = "getpwent"; 306 cmds[2] = "getpwent_r"; 307 cmds[3] = "getpwnam"; 308 cmds[4] = "getpwnam_r"; 309 cmds[5] = "getpwuid"; 310 cmds[6] = "getpwuid_r"; 311 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == 0); 312 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 313 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 314 315 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 316 GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 317 318 cap_close(cappwd); 319 320 /* 321 * Allow: 322 * cmds: getpwent, getpwent_r, getpwnam, getpwnam_r, 323 * getpwuid, getpwuid_r 324 * users: 325 * names: root, toor, daemon, operator, bin, kmem 326 * uids: 327 * Disallow: 328 * cmds: setpwent 329 * users: 330 */ 331 cappwd = cap_clone(origcappwd); 332 CHECK(cappwd != NULL); 333 334 cap_setpwent(cappwd); 335 336 cmds[0] = "getpwent"; 337 cmds[1] = "getpwent_r"; 338 cmds[2] = "getpwnam"; 339 cmds[3] = "getpwnam_r"; 340 cmds[4] = "getpwuid"; 341 cmds[5] = "getpwuid_r"; 342 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 343 cmds[0] = "setpwent"; 344 cmds[1] = "getpwent"; 345 cmds[2] = "getpwent_r"; 346 cmds[3] = "getpwnam"; 347 cmds[4] = "getpwnam_r"; 348 cmds[5] = "getpwuid"; 349 cmds[6] = "getpwuid_r"; 350 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 351 cmds[0] = "setpwent"; 352 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 353 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 354 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 355 356 CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | GETPWENT_R0 | 357 GETPWENT_R1 | GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 358 359 cap_close(cappwd); 360 361 /* 362 * Allow: 363 * cmds: getpwent, getpwent_r, getpwnam, getpwnam_r, 364 * getpwuid, getpwuid_r 365 * users: 366 * names: 367 * uids: 0, 1, 2, 3, 5 368 * Disallow: 369 * cmds: setpwent 370 * users: 371 */ 372 cappwd = cap_clone(origcappwd); 373 CHECK(cappwd != NULL); 374 375 cap_setpwent(cappwd); 376 377 cmds[0] = "getpwent"; 378 cmds[1] = "getpwent_r"; 379 cmds[2] = "getpwnam"; 380 cmds[3] = "getpwnam_r"; 381 cmds[4] = "getpwuid"; 382 cmds[5] = "getpwuid_r"; 383 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 384 cmds[0] = "setpwent"; 385 cmds[1] = "getpwent"; 386 cmds[2] = "getpwent_r"; 387 cmds[3] = "getpwnam"; 388 cmds[4] = "getpwnam_r"; 389 cmds[5] = "getpwuid"; 390 cmds[6] = "getpwuid_r"; 391 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 392 cmds[0] = "setpwent"; 393 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 394 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 395 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 396 397 CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | GETPWENT_R0 | 398 GETPWENT_R1 | GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 399 400 cap_close(cappwd); 401 402 /* 403 * Allow: 404 * cmds: setpwent, getpwent_r, getpwnam, getpwnam_r, 405 * getpwuid, getpwuid_r 406 * users: 407 * names: root, toor, daemon, operator, bin, kmem 408 * uids: 409 * Disallow: 410 * cmds: getpwent 411 * users: 412 */ 413 cappwd = cap_clone(origcappwd); 414 CHECK(cappwd != NULL); 415 416 cmds[0] = "setpwent"; 417 cmds[1] = "getpwent_r"; 418 cmds[2] = "getpwnam"; 419 cmds[3] = "getpwnam_r"; 420 cmds[4] = "getpwuid"; 421 cmds[5] = "getpwuid_r"; 422 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 423 cmds[0] = "setpwent"; 424 cmds[1] = "getpwent"; 425 cmds[2] = "getpwent_r"; 426 cmds[3] = "getpwnam"; 427 cmds[4] = "getpwnam_r"; 428 cmds[5] = "getpwuid"; 429 cmds[6] = "getpwuid_r"; 430 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 431 cmds[0] = "getpwent"; 432 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 433 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 434 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 435 436 CHECK(runtest_cmds(cappwd) == (GETPWENT_R2 | 437 GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 438 439 cap_close(cappwd); 440 441 /* 442 * Allow: 443 * cmds: setpwent, getpwent_r, getpwnam, getpwnam_r, 444 * getpwuid, getpwuid_r 445 * users: 446 * names: 447 * uids: 0, 1, 2, 3, 5 448 * Disallow: 449 * cmds: getpwent 450 * users: 451 */ 452 cappwd = cap_clone(origcappwd); 453 CHECK(cappwd != NULL); 454 455 cmds[0] = "setpwent"; 456 cmds[1] = "getpwent_r"; 457 cmds[2] = "getpwnam"; 458 cmds[3] = "getpwnam_r"; 459 cmds[4] = "getpwuid"; 460 cmds[5] = "getpwuid_r"; 461 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 462 cmds[0] = "setpwent"; 463 cmds[1] = "getpwent"; 464 cmds[2] = "getpwent_r"; 465 cmds[3] = "getpwnam"; 466 cmds[4] = "getpwnam_r"; 467 cmds[5] = "getpwuid"; 468 cmds[6] = "getpwuid_r"; 469 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 470 cmds[0] = "getpwent"; 471 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 472 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 473 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 474 475 CHECK(runtest_cmds(cappwd) == (GETPWENT_R2 | 476 GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 477 478 cap_close(cappwd); 479 480 /* 481 * Allow: 482 * cmds: setpwent, getpwent, getpwnam, getpwnam_r, 483 * getpwuid, getpwuid_r 484 * users: 485 * names: root, toor, daemon, operator, bin, kmem 486 * uids: 487 * Disallow: 488 * cmds: getpwent_r 489 * users: 490 */ 491 cappwd = cap_clone(origcappwd); 492 CHECK(cappwd != NULL); 493 494 cmds[0] = "setpwent"; 495 cmds[1] = "getpwent"; 496 cmds[2] = "getpwnam"; 497 cmds[3] = "getpwnam_r"; 498 cmds[4] = "getpwuid"; 499 cmds[5] = "getpwuid_r"; 500 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 501 cmds[0] = "setpwent"; 502 cmds[1] = "getpwent"; 503 cmds[2] = "getpwent_r"; 504 cmds[3] = "getpwnam"; 505 cmds[4] = "getpwnam_r"; 506 cmds[5] = "getpwuid"; 507 cmds[6] = "getpwuid_r"; 508 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 509 cmds[0] = "getpwent_r"; 510 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 511 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 512 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 513 514 CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | 515 GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 516 517 cap_close(cappwd); 518 519 /* 520 * Allow: 521 * cmds: setpwent, getpwent, getpwnam, getpwnam_r, 522 * getpwuid, getpwuid_r 523 * users: 524 * names: 525 * uids: 0, 1, 2, 3, 5 526 * Disallow: 527 * cmds: getpwent_r 528 * users: 529 */ 530 cappwd = cap_clone(origcappwd); 531 CHECK(cappwd != NULL); 532 533 cmds[0] = "setpwent"; 534 cmds[1] = "getpwent"; 535 cmds[2] = "getpwnam"; 536 cmds[3] = "getpwnam_r"; 537 cmds[4] = "getpwuid"; 538 cmds[5] = "getpwuid_r"; 539 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 540 cmds[0] = "setpwent"; 541 cmds[1] = "getpwent"; 542 cmds[2] = "getpwent_r"; 543 cmds[3] = "getpwnam"; 544 cmds[4] = "getpwnam_r"; 545 cmds[5] = "getpwuid"; 546 cmds[6] = "getpwuid_r"; 547 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 548 cmds[0] = "getpwent_r"; 549 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 550 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 551 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 552 553 CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | 554 GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R)); 555 556 cap_close(cappwd); 557 558 /* 559 * Allow: 560 * cmds: setpwent, getpwent, getpwent_r, getpwnam_r, 561 * getpwuid, getpwuid_r 562 * users: 563 * names: root, toor, daemon, operator, bin, kmem 564 * uids: 565 * Disallow: 566 * cmds: getpwnam 567 * users: 568 */ 569 cappwd = cap_clone(origcappwd); 570 CHECK(cappwd != NULL); 571 572 cmds[0] = "setpwent"; 573 cmds[1] = "getpwent"; 574 cmds[2] = "getpwent_r"; 575 cmds[3] = "getpwnam_r"; 576 cmds[4] = "getpwuid"; 577 cmds[5] = "getpwuid_r"; 578 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 579 cmds[0] = "setpwent"; 580 cmds[1] = "getpwent"; 581 cmds[2] = "getpwent_r"; 582 cmds[3] = "getpwnam"; 583 cmds[4] = "getpwnam_r"; 584 cmds[5] = "getpwuid"; 585 cmds[6] = "getpwuid_r"; 586 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 587 cmds[0] = "getpwnam"; 588 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 589 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 590 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 591 592 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 593 GETPWNAM_R | GETPWUID | GETPWUID_R)); 594 595 cap_close(cappwd); 596 597 /* 598 * Allow: 599 * cmds: setpwent, getpwent, getpwent_r, getpwnam_r, 600 * getpwuid, getpwuid_r 601 * users: 602 * names: 603 * uids: 0, 1, 2, 3, 5 604 * Disallow: 605 * cmds: getpwnam 606 * users: 607 */ 608 cappwd = cap_clone(origcappwd); 609 CHECK(cappwd != NULL); 610 611 cmds[0] = "setpwent"; 612 cmds[1] = "getpwent"; 613 cmds[2] = "getpwent_r"; 614 cmds[3] = "getpwnam_r"; 615 cmds[4] = "getpwuid"; 616 cmds[5] = "getpwuid_r"; 617 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 618 cmds[0] = "setpwent"; 619 cmds[1] = "getpwent"; 620 cmds[2] = "getpwent_r"; 621 cmds[3] = "getpwnam"; 622 cmds[4] = "getpwnam_r"; 623 cmds[5] = "getpwuid"; 624 cmds[6] = "getpwuid_r"; 625 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 626 cmds[0] = "getpwnam"; 627 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 628 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 629 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 630 631 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 632 GETPWNAM_R | GETPWUID | GETPWUID_R)); 633 634 cap_close(cappwd); 635 636 /* 637 * Allow: 638 * cmds: setpwent, getpwent, getpwent_r, getpwnam, 639 * getpwuid, getpwuid_r 640 * users: 641 * names: root, toor, daemon, operator, bin, kmem 642 * uids: 643 * Disallow: 644 * cmds: getpwnam_r 645 * users: 646 */ 647 cappwd = cap_clone(origcappwd); 648 CHECK(cappwd != NULL); 649 650 cmds[0] = "setpwent"; 651 cmds[1] = "getpwent"; 652 cmds[2] = "getpwent_r"; 653 cmds[3] = "getpwnam"; 654 cmds[4] = "getpwuid"; 655 cmds[5] = "getpwuid_r"; 656 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 657 cmds[0] = "setpwent"; 658 cmds[1] = "getpwent"; 659 cmds[2] = "getpwent_r"; 660 cmds[3] = "getpwnam"; 661 cmds[4] = "getpwnam_r"; 662 cmds[5] = "getpwuid"; 663 cmds[6] = "getpwuid_r"; 664 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 665 cmds[0] = "getpwnam_r"; 666 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 667 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 668 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 669 670 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 671 GETPWNAM | GETPWUID | GETPWUID_R)); 672 673 cap_close(cappwd); 674 675 /* 676 * Allow: 677 * cmds: setpwent, getpwent, getpwent_r, getpwnam, 678 * getpwuid, getpwuid_r 679 * users: 680 * names: 681 * uids: 0, 1, 2, 3, 5 682 * Disallow: 683 * cmds: getpwnam_r 684 * users: 685 */ 686 cappwd = cap_clone(origcappwd); 687 CHECK(cappwd != NULL); 688 689 cmds[0] = "setpwent"; 690 cmds[1] = "getpwent"; 691 cmds[2] = "getpwent_r"; 692 cmds[3] = "getpwnam"; 693 cmds[4] = "getpwuid"; 694 cmds[5] = "getpwuid_r"; 695 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 696 cmds[0] = "setpwent"; 697 cmds[1] = "getpwent"; 698 cmds[2] = "getpwent_r"; 699 cmds[3] = "getpwnam"; 700 cmds[4] = "getpwnam_r"; 701 cmds[5] = "getpwuid"; 702 cmds[6] = "getpwuid_r"; 703 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 704 cmds[0] = "getpwnam_r"; 705 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 706 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 707 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 708 709 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 710 GETPWNAM | GETPWUID | GETPWUID_R)); 711 712 cap_close(cappwd); 713 714 /* 715 * Allow: 716 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r, 717 * getpwuid_r 718 * users: 719 * names: root, toor, daemon, operator, bin, kmem 720 * uids: 721 * Disallow: 722 * cmds: getpwuid 723 * users: 724 */ 725 cappwd = cap_clone(origcappwd); 726 CHECK(cappwd != NULL); 727 728 cmds[0] = "setpwent"; 729 cmds[1] = "getpwent"; 730 cmds[2] = "getpwent_r"; 731 cmds[3] = "getpwnam"; 732 cmds[4] = "getpwnam_r"; 733 cmds[5] = "getpwuid_r"; 734 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 735 cmds[0] = "setpwent"; 736 cmds[1] = "getpwent"; 737 cmds[2] = "getpwent_r"; 738 cmds[3] = "getpwnam"; 739 cmds[4] = "getpwnam_r"; 740 cmds[5] = "getpwuid"; 741 cmds[6] = "getpwuid_r"; 742 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 743 cmds[0] = "getpwuid"; 744 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 745 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 746 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 747 748 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 749 GETPWNAM | GETPWNAM_R | GETPWUID_R)); 750 751 cap_close(cappwd); 752 753 /* 754 * Allow: 755 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r, 756 * getpwuid_r 757 * users: 758 * names: 759 * uids: 0, 1, 2, 3, 5 760 * Disallow: 761 * cmds: getpwuid 762 * users: 763 */ 764 cappwd = cap_clone(origcappwd); 765 CHECK(cappwd != NULL); 766 767 cmds[0] = "setpwent"; 768 cmds[1] = "getpwent"; 769 cmds[2] = "getpwent_r"; 770 cmds[3] = "getpwnam"; 771 cmds[4] = "getpwnam_r"; 772 cmds[5] = "getpwuid_r"; 773 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 774 cmds[0] = "setpwent"; 775 cmds[1] = "getpwent"; 776 cmds[2] = "getpwent_r"; 777 cmds[3] = "getpwnam"; 778 cmds[4] = "getpwnam_r"; 779 cmds[5] = "getpwuid"; 780 cmds[6] = "getpwuid_r"; 781 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 782 cmds[0] = "getpwuid"; 783 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 784 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 785 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 786 787 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 788 GETPWNAM | GETPWNAM_R | GETPWUID_R)); 789 790 cap_close(cappwd); 791 792 /* 793 * Allow: 794 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r, 795 * getpwuid 796 * users: 797 * names: root, toor, daemon, operator, bin, kmem 798 * uids: 799 * Disallow: 800 * cmds: getpwuid_r 801 * users: 802 */ 803 cappwd = cap_clone(origcappwd); 804 CHECK(cappwd != NULL); 805 806 cmds[0] = "setpwent"; 807 cmds[1] = "getpwent"; 808 cmds[2] = "getpwent_r"; 809 cmds[3] = "getpwnam"; 810 cmds[4] = "getpwnam_r"; 811 cmds[5] = "getpwuid"; 812 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 813 cmds[0] = "setpwent"; 814 cmds[1] = "getpwent"; 815 cmds[2] = "getpwent_r"; 816 cmds[3] = "getpwnam"; 817 cmds[4] = "getpwnam_r"; 818 cmds[5] = "getpwuid"; 819 cmds[6] = "getpwuid_r"; 820 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 821 cmds[0] = "getpwuid_r"; 822 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 823 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 824 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 825 826 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 827 GETPWNAM | GETPWNAM_R | GETPWUID)); 828 829 cap_close(cappwd); 830 831 /* 832 * Allow: 833 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r, 834 * getpwuid 835 * users: 836 * names: 837 * uids: 0, 1, 2, 3, 5 838 * Disallow: 839 * cmds: getpwuid_r 840 * users: 841 */ 842 cappwd = cap_clone(origcappwd); 843 CHECK(cappwd != NULL); 844 845 cmds[0] = "setpwent"; 846 cmds[1] = "getpwent"; 847 cmds[2] = "getpwent_r"; 848 cmds[3] = "getpwnam"; 849 cmds[4] = "getpwnam_r"; 850 cmds[5] = "getpwuid"; 851 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0); 852 cmds[0] = "setpwent"; 853 cmds[1] = "getpwent"; 854 cmds[2] = "getpwent_r"; 855 cmds[3] = "getpwnam"; 856 cmds[4] = "getpwnam_r"; 857 cmds[5] = "getpwuid"; 858 cmds[6] = "getpwuid_r"; 859 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE); 860 cmds[0] = "getpwuid_r"; 861 CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE); 862 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 863 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0); 864 865 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | 866 GETPWNAM | GETPWNAM_R | GETPWUID)); 867 868 cap_close(cappwd); 869 } 870 871 #define PW_NAME _PWF_NAME 872 #define PW_PASSWD _PWF_PASSWD 873 #define PW_UID _PWF_UID 874 #define PW_GID _PWF_GID 875 #define PW_CHANGE _PWF_CHANGE 876 #define PW_CLASS _PWF_CLASS 877 #define PW_GECOS _PWF_GECOS 878 #define PW_DIR _PWF_DIR 879 #define PW_SHELL _PWF_SHELL 880 #define PW_EXPIRE _PWF_EXPIRE 881 882 static unsigned int 883 passwd_fields(const struct passwd *pwd) 884 { 885 unsigned int result; 886 887 result = 0; 888 889 if (pwd->pw_name != NULL && pwd->pw_name[0] != '\0') 890 result |= PW_NAME; 891 // else 892 // printf("No pw_name\n"); 893 894 if (pwd->pw_passwd != NULL && pwd->pw_passwd[0] != '\0') 895 result |= PW_PASSWD; 896 else if ((pwd->pw_fields & _PWF_PASSWD) != 0) 897 result |= PW_PASSWD; 898 // else 899 // printf("No pw_passwd\n"); 900 901 if (pwd->pw_uid != (uid_t)-1) 902 result |= PW_UID; 903 // else 904 // printf("No pw_uid\n"); 905 906 if (pwd->pw_gid != (gid_t)-1) 907 result |= PW_GID; 908 // else 909 // printf("No pw_gid\n"); 910 911 if (pwd->pw_change != 0 || (pwd->pw_fields & _PWF_CHANGE) != 0) 912 result |= PW_CHANGE; 913 // else 914 // printf("No pw_change\n"); 915 916 if (pwd->pw_class != NULL && pwd->pw_class[0] != '\0') 917 result |= PW_CLASS; 918 else if ((pwd->pw_fields & _PWF_CLASS) != 0) 919 result |= PW_CLASS; 920 // else 921 // printf("No pw_class\n"); 922 923 if (pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0') 924 result |= PW_GECOS; 925 else if ((pwd->pw_fields & _PWF_GECOS) != 0) 926 result |= PW_GECOS; 927 // else 928 // printf("No pw_gecos\n"); 929 930 if (pwd->pw_dir != NULL && pwd->pw_dir[0] != '\0') 931 result |= PW_DIR; 932 else if ((pwd->pw_fields & _PWF_DIR) != 0) 933 result |= PW_DIR; 934 // else 935 // printf("No pw_dir\n"); 936 937 if (pwd->pw_shell != NULL && pwd->pw_shell[0] != '\0') 938 result |= PW_SHELL; 939 else if ((pwd->pw_fields & _PWF_SHELL) != 0) 940 result |= PW_SHELL; 941 // else 942 // printf("No pw_shell\n"); 943 944 if (pwd->pw_expire != 0 || (pwd->pw_fields & _PWF_EXPIRE) != 0) 945 result |= PW_EXPIRE; 946 // else 947 // printf("No pw_expire\n"); 948 949 if (false && pwd->pw_fields != (int)result) { 950 printf("fields=0x%x != result=0x%x\n", (const unsigned int)pwd->pw_fields, result); 951 printf(" fields result\n"); 952 printf("PW_NAME %d %d\n", (pwd->pw_fields & PW_NAME) != 0, (result & PW_NAME) != 0); 953 printf("PW_PASSWD %d %d\n", (pwd->pw_fields & PW_PASSWD) != 0, (result & PW_PASSWD) != 0); 954 printf("PW_UID %d %d\n", (pwd->pw_fields & PW_UID) != 0, (result & PW_UID) != 0); 955 printf("PW_GID %d %d\n", (pwd->pw_fields & PW_GID) != 0, (result & PW_GID) != 0); 956 printf("PW_CHANGE %d %d\n", (pwd->pw_fields & PW_CHANGE) != 0, (result & PW_CHANGE) != 0); 957 printf("PW_CLASS %d %d\n", (pwd->pw_fields & PW_CLASS) != 0, (result & PW_CLASS) != 0); 958 printf("PW_GECOS %d %d\n", (pwd->pw_fields & PW_GECOS) != 0, (result & PW_GECOS) != 0); 959 printf("PW_DIR %d %d\n", (pwd->pw_fields & PW_DIR) != 0, (result & PW_DIR) != 0); 960 printf("PW_SHELL %d %d\n", (pwd->pw_fields & PW_SHELL) != 0, (result & PW_SHELL) != 0); 961 printf("PW_EXPIRE %d %d\n", (pwd->pw_fields & PW_EXPIRE) != 0, (result & PW_EXPIRE) != 0); 962 } 963 964 //printf("result=0x%x\n", result); 965 return (result); 966 } 967 968 static bool 969 runtest_fields(cap_channel_t *cappwd, unsigned int expected) 970 { 971 char buf[1024]; 972 struct passwd *pwd; 973 struct passwd st; 974 975 //printf("expected=0x%x\n", expected); 976 cap_setpwent(cappwd); 977 pwd = cap_getpwent(cappwd); 978 if ((passwd_fields(pwd) & ~expected) != 0) 979 return (false); 980 981 cap_setpwent(cappwd); 982 cap_getpwent_r(cappwd, &st, buf, sizeof(buf), &pwd); 983 if ((passwd_fields(pwd) & ~expected) != 0) 984 return (false); 985 986 pwd = cap_getpwnam(cappwd, "root"); 987 if ((passwd_fields(pwd) & ~expected) != 0) 988 return (false); 989 990 cap_getpwnam_r(cappwd, "root", &st, buf, sizeof(buf), &pwd); 991 if ((passwd_fields(pwd) & ~expected) != 0) 992 return (false); 993 994 pwd = cap_getpwuid(cappwd, UID_ROOT); 995 if ((passwd_fields(pwd) & ~expected) != 0) 996 return (false); 997 998 cap_getpwuid_r(cappwd, UID_ROOT, &st, buf, sizeof(buf), &pwd); 999 if ((passwd_fields(pwd) & ~expected) != 0) 1000 return (false); 1001 1002 return (true); 1003 } 1004 1005 static void 1006 test_fields(cap_channel_t *origcappwd) 1007 { 1008 cap_channel_t *cappwd; 1009 const char *fields[10]; 1010 1011 /* No limits. */ 1012 1013 CHECK(runtest_fields(origcappwd, PW_NAME | PW_PASSWD | PW_UID | 1014 PW_GID | PW_CHANGE | PW_CLASS | PW_GECOS | PW_DIR | PW_SHELL | 1015 PW_EXPIRE)); 1016 1017 /* 1018 * Allow: 1019 * fields: pw_name, pw_passwd, pw_uid, pw_gid, pw_change, pw_class, 1020 * pw_gecos, pw_dir, pw_shell, pw_expire 1021 */ 1022 cappwd = cap_clone(origcappwd); 1023 CHECK(cappwd != NULL); 1024 1025 fields[0] = "pw_name"; 1026 fields[1] = "pw_passwd"; 1027 fields[2] = "pw_uid"; 1028 fields[3] = "pw_gid"; 1029 fields[4] = "pw_change"; 1030 fields[5] = "pw_class"; 1031 fields[6] = "pw_gecos"; 1032 fields[7] = "pw_dir"; 1033 fields[8] = "pw_shell"; 1034 fields[9] = "pw_expire"; 1035 CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0); 1036 1037 CHECK(runtest_fields(origcappwd, PW_NAME | PW_PASSWD | PW_UID | 1038 PW_GID | PW_CHANGE | PW_CLASS | PW_GECOS | PW_DIR | PW_SHELL | 1039 PW_EXPIRE)); 1040 1041 cap_close(cappwd); 1042 1043 /* 1044 * Allow: 1045 * fields: pw_name, pw_passwd, pw_uid, pw_gid, pw_change 1046 */ 1047 cappwd = cap_clone(origcappwd); 1048 CHECK(cappwd != NULL); 1049 1050 fields[0] = "pw_name"; 1051 fields[1] = "pw_passwd"; 1052 fields[2] = "pw_uid"; 1053 fields[3] = "pw_gid"; 1054 fields[4] = "pw_change"; 1055 CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0); 1056 fields[5] = "pw_class"; 1057 CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 && 1058 errno == ENOTCAPABLE); 1059 fields[0] = "pw_class"; 1060 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 && 1061 errno == ENOTCAPABLE); 1062 1063 CHECK(runtest_fields(cappwd, PW_NAME | PW_PASSWD | PW_UID | 1064 PW_GID | PW_CHANGE)); 1065 1066 cap_close(cappwd); 1067 1068 /* 1069 * Allow: 1070 * fields: pw_class, pw_gecos, pw_dir, pw_shell, pw_expire 1071 */ 1072 cappwd = cap_clone(origcappwd); 1073 CHECK(cappwd != NULL); 1074 1075 fields[0] = "pw_class"; 1076 fields[1] = "pw_gecos"; 1077 fields[2] = "pw_dir"; 1078 fields[3] = "pw_shell"; 1079 fields[4] = "pw_expire"; 1080 CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0); 1081 fields[5] = "pw_uid"; 1082 CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 && 1083 errno == ENOTCAPABLE); 1084 fields[0] = "pw_uid"; 1085 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 && 1086 errno == ENOTCAPABLE); 1087 1088 CHECK(runtest_fields(cappwd, PW_CLASS | PW_GECOS | PW_DIR | 1089 PW_SHELL | PW_EXPIRE)); 1090 1091 cap_close(cappwd); 1092 1093 /* 1094 * Allow: 1095 * fields: pw_name, pw_uid, pw_change, pw_gecos, pw_shell 1096 */ 1097 cappwd = cap_clone(origcappwd); 1098 CHECK(cappwd != NULL); 1099 1100 fields[0] = "pw_name"; 1101 fields[1] = "pw_uid"; 1102 fields[2] = "pw_change"; 1103 fields[3] = "pw_gecos"; 1104 fields[4] = "pw_shell"; 1105 CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0); 1106 fields[5] = "pw_class"; 1107 CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 && 1108 errno == ENOTCAPABLE); 1109 fields[0] = "pw_class"; 1110 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 && 1111 errno == ENOTCAPABLE); 1112 1113 CHECK(runtest_fields(cappwd, PW_NAME | PW_UID | PW_CHANGE | 1114 PW_GECOS | PW_SHELL)); 1115 1116 cap_close(cappwd); 1117 1118 /* 1119 * Allow: 1120 * fields: pw_passwd, pw_gid, pw_class, pw_dir, pw_expire 1121 */ 1122 cappwd = cap_clone(origcappwd); 1123 CHECK(cappwd != NULL); 1124 1125 fields[0] = "pw_passwd"; 1126 fields[1] = "pw_gid"; 1127 fields[2] = "pw_class"; 1128 fields[3] = "pw_dir"; 1129 fields[4] = "pw_expire"; 1130 CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0); 1131 fields[5] = "pw_uid"; 1132 CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 && 1133 errno == ENOTCAPABLE); 1134 fields[0] = "pw_uid"; 1135 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 && 1136 errno == ENOTCAPABLE); 1137 1138 CHECK(runtest_fields(cappwd, PW_PASSWD | PW_GID | PW_CLASS | 1139 PW_DIR | PW_EXPIRE)); 1140 1141 cap_close(cappwd); 1142 1143 /* 1144 * Allow: 1145 * fields: pw_uid, pw_class, pw_shell 1146 */ 1147 cappwd = cap_clone(origcappwd); 1148 CHECK(cappwd != NULL); 1149 1150 fields[0] = "pw_uid"; 1151 fields[1] = "pw_class"; 1152 fields[2] = "pw_shell"; 1153 CHECK(cap_pwd_limit_fields(cappwd, fields, 3) == 0); 1154 fields[3] = "pw_change"; 1155 CHECK(cap_pwd_limit_fields(cappwd, fields, 4) == -1 && 1156 errno == ENOTCAPABLE); 1157 fields[0] = "pw_change"; 1158 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 && 1159 errno == ENOTCAPABLE); 1160 1161 CHECK(runtest_fields(cappwd, PW_UID | PW_CLASS | PW_SHELL)); 1162 1163 cap_close(cappwd); 1164 1165 /* 1166 * Allow: 1167 * fields: pw_change 1168 */ 1169 cappwd = cap_clone(origcappwd); 1170 CHECK(cappwd != NULL); 1171 1172 fields[0] = "pw_change"; 1173 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == 0); 1174 fields[1] = "pw_uid"; 1175 CHECK(cap_pwd_limit_fields(cappwd, fields, 2) == -1 && 1176 errno == ENOTCAPABLE); 1177 fields[0] = "pw_uid"; 1178 CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 && 1179 errno == ENOTCAPABLE); 1180 1181 CHECK(runtest_fields(cappwd, PW_CHANGE)); 1182 1183 cap_close(cappwd); 1184 } 1185 1186 static bool 1187 runtest_users(cap_channel_t *cappwd, const char **names, const uid_t *uids, 1188 size_t nusers) 1189 { 1190 char buf[1024]; 1191 struct passwd *pwd; 1192 struct passwd st; 1193 unsigned int i, got; 1194 1195 cap_setpwent(cappwd); 1196 got = 0; 1197 for (;;) { 1198 pwd = cap_getpwent(cappwd); 1199 if (pwd == NULL) 1200 break; 1201 got++; 1202 for (i = 0; i < nusers; i++) { 1203 if (strcmp(names[i], pwd->pw_name) == 0 && 1204 uids[i] == pwd->pw_uid) { 1205 break; 1206 } 1207 } 1208 if (i == nusers) 1209 return (false); 1210 } 1211 if (got != nusers) 1212 return (false); 1213 1214 cap_setpwent(cappwd); 1215 got = 0; 1216 for (;;) { 1217 cap_getpwent_r(cappwd, &st, buf, sizeof(buf), &pwd); 1218 if (pwd == NULL) 1219 break; 1220 got++; 1221 for (i = 0; i < nusers; i++) { 1222 if (strcmp(names[i], pwd->pw_name) == 0 && 1223 uids[i] == pwd->pw_uid) { 1224 break; 1225 } 1226 } 1227 if (i == nusers) 1228 return (false); 1229 } 1230 if (got != nusers) 1231 return (false); 1232 1233 for (i = 0; i < nusers; i++) { 1234 pwd = cap_getpwnam(cappwd, names[i]); 1235 if (pwd == NULL) 1236 return (false); 1237 } 1238 1239 for (i = 0; i < nusers; i++) { 1240 cap_getpwnam_r(cappwd, names[i], &st, buf, sizeof(buf), &pwd); 1241 if (pwd == NULL) 1242 return (false); 1243 } 1244 1245 for (i = 0; i < nusers; i++) { 1246 pwd = cap_getpwuid(cappwd, uids[i]); 1247 if (pwd == NULL) 1248 return (false); 1249 } 1250 1251 for (i = 0; i < nusers; i++) { 1252 cap_getpwuid_r(cappwd, uids[i], &st, buf, sizeof(buf), &pwd); 1253 if (pwd == NULL) 1254 return (false); 1255 } 1256 1257 return (true); 1258 } 1259 1260 static void 1261 test_users(cap_channel_t *origcappwd) 1262 { 1263 cap_channel_t *cappwd; 1264 const char *names[6]; 1265 uid_t uids[6]; 1266 1267 /* 1268 * Allow: 1269 * users: 1270 * names: root, toor, daemon, operator, bin, tty 1271 * uids: 1272 */ 1273 cappwd = cap_clone(origcappwd); 1274 CHECK(cappwd != NULL); 1275 1276 names[0] = "root"; 1277 names[1] = "toor"; 1278 names[2] = "daemon"; 1279 names[3] = "operator"; 1280 names[4] = "bin"; 1281 names[5] = "tty"; 1282 CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0); 1283 uids[0] = 0; 1284 uids[1] = 0; 1285 uids[2] = 1; 1286 uids[3] = 2; 1287 uids[4] = 3; 1288 uids[5] = 4; 1289 1290 CHECK(runtest_users(cappwd, names, uids, 6)); 1291 1292 cap_close(cappwd); 1293 1294 /* 1295 * Allow: 1296 * users: 1297 * names: daemon, operator, bin 1298 * uids: 1299 */ 1300 cappwd = cap_clone(origcappwd); 1301 CHECK(cappwd != NULL); 1302 1303 names[0] = "daemon"; 1304 names[1] = "operator"; 1305 names[2] = "bin"; 1306 CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == 0); 1307 names[3] = "tty"; 1308 CHECK(cap_pwd_limit_users(cappwd, names, 4, NULL, 0) == -1 && 1309 errno == ENOTCAPABLE); 1310 names[0] = "tty"; 1311 CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 && 1312 errno == ENOTCAPABLE); 1313 names[0] = "daemon"; 1314 uids[0] = 1; 1315 uids[1] = 2; 1316 uids[2] = 3; 1317 1318 CHECK(runtest_users(cappwd, names, uids, 3)); 1319 1320 cap_close(cappwd); 1321 1322 /* 1323 * Allow: 1324 * users: 1325 * names: daemon, bin, tty 1326 * uids: 1327 */ 1328 cappwd = cap_clone(origcappwd); 1329 CHECK(cappwd != NULL); 1330 1331 names[0] = "daemon"; 1332 names[1] = "bin"; 1333 names[2] = "tty"; 1334 CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == 0); 1335 names[3] = "operator"; 1336 CHECK(cap_pwd_limit_users(cappwd, names, 4, NULL, 0) == -1 && 1337 errno == ENOTCAPABLE); 1338 names[0] = "operator"; 1339 CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 && 1340 errno == ENOTCAPABLE); 1341 names[0] = "daemon"; 1342 uids[0] = 1; 1343 uids[1] = 3; 1344 uids[2] = 4; 1345 1346 CHECK(runtest_users(cappwd, names, uids, 3)); 1347 1348 cap_close(cappwd); 1349 1350 /* 1351 * Allow: 1352 * users: 1353 * names: 1354 * uids: 1, 2, 3 1355 */ 1356 cappwd = cap_clone(origcappwd); 1357 CHECK(cappwd != NULL); 1358 1359 names[0] = "daemon"; 1360 names[1] = "operator"; 1361 names[2] = "bin"; 1362 uids[0] = 1; 1363 uids[1] = 2; 1364 uids[2] = 3; 1365 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == 0); 1366 uids[3] = 4; 1367 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 4) == -1 && 1368 errno == ENOTCAPABLE); 1369 uids[0] = 4; 1370 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 && 1371 errno == ENOTCAPABLE); 1372 uids[0] = 1; 1373 1374 CHECK(runtest_users(cappwd, names, uids, 3)); 1375 1376 cap_close(cappwd); 1377 1378 /* 1379 * Allow: 1380 * users: 1381 * names: 1382 * uids: 1, 3, 4 1383 */ 1384 cappwd = cap_clone(origcappwd); 1385 CHECK(cappwd != NULL); 1386 1387 names[0] = "daemon"; 1388 names[1] = "bin"; 1389 names[2] = "tty"; 1390 uids[0] = 1; 1391 uids[1] = 3; 1392 uids[2] = 4; 1393 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == 0); 1394 uids[3] = 5; 1395 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 4) == -1 && 1396 errno == ENOTCAPABLE); 1397 uids[0] = 5; 1398 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 && 1399 errno == ENOTCAPABLE); 1400 uids[0] = 1; 1401 1402 CHECK(runtest_users(cappwd, names, uids, 3)); 1403 1404 cap_close(cappwd); 1405 1406 /* 1407 * Allow: 1408 * users: 1409 * names: bin 1410 * uids: 1411 */ 1412 cappwd = cap_clone(origcappwd); 1413 CHECK(cappwd != NULL); 1414 1415 names[0] = "bin"; 1416 CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == 0); 1417 names[1] = "operator"; 1418 CHECK(cap_pwd_limit_users(cappwd, names, 2, NULL, 0) == -1 && 1419 errno == ENOTCAPABLE); 1420 names[0] = "operator"; 1421 CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 && 1422 errno == ENOTCAPABLE); 1423 names[0] = "bin"; 1424 uids[0] = 3; 1425 1426 CHECK(runtest_users(cappwd, names, uids, 1)); 1427 1428 cap_close(cappwd); 1429 1430 /* 1431 * Allow: 1432 * users: 1433 * names: daemon, tty 1434 * uids: 1435 */ 1436 cappwd = cap_clone(origcappwd); 1437 CHECK(cappwd != NULL); 1438 1439 names[0] = "daemon"; 1440 names[1] = "tty"; 1441 CHECK(cap_pwd_limit_users(cappwd, names, 2, NULL, 0) == 0); 1442 names[2] = "operator"; 1443 CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == -1 && 1444 errno == ENOTCAPABLE); 1445 names[0] = "operator"; 1446 CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 && 1447 errno == ENOTCAPABLE); 1448 names[0] = "daemon"; 1449 uids[0] = 1; 1450 uids[1] = 4; 1451 1452 CHECK(runtest_users(cappwd, names, uids, 2)); 1453 1454 cap_close(cappwd); 1455 1456 /* 1457 * Allow: 1458 * users: 1459 * names: 1460 * uids: 3 1461 */ 1462 cappwd = cap_clone(origcappwd); 1463 CHECK(cappwd != NULL); 1464 1465 names[0] = "bin"; 1466 uids[0] = 3; 1467 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == 0); 1468 uids[1] = 4; 1469 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 2) == -1 && 1470 errno == ENOTCAPABLE); 1471 uids[0] = 4; 1472 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 && 1473 errno == ENOTCAPABLE); 1474 uids[0] = 3; 1475 1476 CHECK(runtest_users(cappwd, names, uids, 1)); 1477 1478 cap_close(cappwd); 1479 1480 /* 1481 * Allow: 1482 * users: 1483 * names: 1484 * uids: 1, 4 1485 */ 1486 cappwd = cap_clone(origcappwd); 1487 CHECK(cappwd != NULL); 1488 1489 names[0] = "daemon"; 1490 names[1] = "tty"; 1491 uids[0] = 1; 1492 uids[1] = 4; 1493 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 2) == 0); 1494 uids[2] = 3; 1495 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == -1 && 1496 errno == ENOTCAPABLE); 1497 uids[0] = 3; 1498 CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 && 1499 errno == ENOTCAPABLE); 1500 uids[0] = 1; 1501 1502 CHECK(runtest_users(cappwd, names, uids, 2)); 1503 1504 cap_close(cappwd); 1505 } 1506 1507 int 1508 main(void) 1509 { 1510 cap_channel_t *capcas, *cappwd; 1511 1512 printf("1..188\n"); 1513 1514 capcas = cap_init(); 1515 CHECKX(capcas != NULL); 1516 1517 cappwd = cap_service_open(capcas, "system.pwd"); 1518 CHECKX(cappwd != NULL); 1519 1520 cap_close(capcas); 1521 1522 /* No limits. */ 1523 1524 CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | GETPWNAM | 1525 GETPWNAM_R | GETPWUID | GETPWUID_R)); 1526 1527 test_cmds(cappwd); 1528 1529 test_fields(cappwd); 1530 1531 test_users(cappwd); 1532 1533 cap_close(cappwd); 1534 1535 exit(0); 1536 } 1537