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