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