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