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