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