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