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