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