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