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