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