1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/sysmacros.h> 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/cred_impl.h> 33 #include <sys/vnode.h> 34 #include <sys/vfs.h> 35 #include <sys/stat.h> 36 #include <sys/errno.h> 37 #include <sys/kmem.h> 38 #include <sys/user.h> 39 #include <sys/proc.h> 40 #include <sys/acct.h> 41 #include <sys/ipc_impl.h> 42 #include <sys/cmn_err.h> 43 #include <sys/debug.h> 44 #include <sys/policy.h> 45 #include <sys/kobj.h> 46 #include <sys/msg.h> 47 #include <sys/devpolicy.h> 48 #include <c2/audit.h> 49 #include <sys/varargs.h> 50 #include <sys/modctl.h> 51 #include <sys/disp.h> 52 #include <sys/zone.h> 53 #include <inet/optcom.h> 54 #include <sys/sdt.h> 55 #include <sys/vfs.h> 56 #include <sys/mntent.h> 57 #include <sys/contract_impl.h> 58 59 /* 60 * There are two possible layers of privilege routines and two possible 61 * levels of secpolicy. Plus one other we may not be interested in, so 62 * we may need as many as 6 but no more. 63 */ 64 #define MAXPRIVSTACK 6 65 66 int priv_debug = 0; 67 68 /* 69 * This file contains the majority of the policy routines. 70 * Since the policy routines are defined by function and not 71 * by privilege, there is quite a bit of duplication of 72 * functions. 73 * 74 * The secpolicy functions must not make assumptions about 75 * locks held or not held as any lock can be held while they're 76 * being called. 77 * 78 * Credentials are read-only so no special precautions need to 79 * be taken while locking them. 80 * 81 * When a new policy check needs to be added to the system the 82 * following procedure should be followed: 83 * 84 * Pick an appropriate secpolicy_*() function 85 * -> done if one exists. 86 * Create a new secpolicy function, preferably with 87 * a descriptive name using the standard template. 88 * Pick an appropriate privilege for the policy. 89 * If no appropraite privilege exists, define new one 90 * (this should be done with extreme care; in most cases 91 * little is gained by adding another privilege) 92 * 93 * WHY ROOT IS STILL SPECIAL. 94 * 95 * In a number of the policy functions, there are still explicit 96 * checks for uid 0. The rationale behind these is that many root 97 * owned files/objects hold configuration information which can give full 98 * privileges to the user once written to. To prevent escalation 99 * of privilege by allowing just a single privilege to modify root owned 100 * objects, we've added these root specific checks where we considered 101 * them necessary: modifying root owned files, changing uids to 0, etc. 102 * 103 * PRIVILEGE ESCALATION AND ZONES. 104 * 105 * A number of operations potentially allow the caller to achieve 106 * privileges beyond the ones normally required to perform the operation. 107 * For example, if allowed to create a setuid 0 executable, a process can 108 * gain privileges beyond PRIV_FILE_SETID. Zones, however, place 109 * restrictions on the ability to gain privileges beyond those available 110 * within the zone through file and process manipulation. Hence, such 111 * operations require that the caller have an effective set that includes 112 * all privileges available within the current zone, or all privileges 113 * if executing in the global zone. 114 * 115 * This is indicated in the priv_policy* policy checking functions 116 * through a combination of parameters. The "priv" parameter indicates 117 * the privilege that is required, and the "allzone" parameter indicates 118 * whether or not all privileges in the zone are required. In addition, 119 * priv can be set to PRIV_ALL to indicate that all privileges are 120 * required (regardless of zone). There are three scenarios of interest: 121 * (1) operation requires a specific privilege 122 * (2) operation requires a specific privilege, and requires all 123 * privileges available within the zone (or all privileges if in 124 * the global zone) 125 * (3) operation requires all privileges, regardless of zone 126 * 127 * For (1), priv should be set to the specific privilege, and allzone 128 * should be set to B_FALSE. 129 * For (2), priv should be set to the specific privilege, and allzone 130 * should be set to B_TRUE. 131 * For (3), priv should be set to PRIV_ALL, and allzone should be set 132 * to B_FALSE. 133 * 134 */ 135 136 /* 137 * The privileges are checked against the Effective set for 138 * ordinary processes and checked against the Limit set 139 * for euid 0 processes that haven't manipulated their privilege 140 * sets. 141 */ 142 #define HAS_ALLPRIVS(cr) priv_isfullset(&CR_OEPRIV(cr)) 143 #define ZONEPRIVS(cr) ((cr)->cr_zone->zone_privset) 144 #define HAS_ALLZONEPRIVS(cr) priv_issubset(ZONEPRIVS(cr), &CR_OEPRIV(cr)) 145 #define HAS_PRIVILEGE(cr, pr) ((pr) == PRIV_ALL ? \ 146 HAS_ALLPRIVS(cr) : \ 147 PRIV_ISASSERT(&CR_OEPRIV(cr), pr)) 148 149 /* 150 * Policy checking functions 151 * 152 * In future, these will migrate to several files when policy 153 * becomes more or less pluggable. 154 * 155 * For now, there's only one policy and this is it. 156 */ 157 158 /* 159 * Generic policy calls 160 * 161 * The "bottom" functions of policy control 162 */ 163 164 static char * 165 mprintf(const char *fmt, ...) 166 { 167 va_list args; 168 char *buf; 169 size_t len; 170 171 va_start(args, fmt); 172 len = vsnprintf(NULL, 0, fmt, args) + 1; 173 va_end(args); 174 175 buf = kmem_alloc(len, KM_NOSLEEP); 176 177 if (buf == NULL) 178 return (NULL); 179 180 va_start(args, fmt); 181 (void) vsnprintf(buf, len, fmt, args); 182 va_end(args); 183 184 return (buf); 185 } 186 187 /* 188 * priv_policy_errmsg() 189 * 190 * Generate an error message if privilege debugging is enabled system wide 191 * or for this particular process. 192 */ 193 194 #define FMTHDR "%s[%d]: missing privilege \"%s\" (euid = %d, syscall = %d)" 195 #define FMTMSG " for \"%s\"" 196 #define FMTFUN " needed at %s+0x%lx" 197 198 /* The maximum size privilege format: the concatenation of the above */ 199 #define FMTMAX FMTHDR FMTMSG FMTFUN "\n" 200 201 static void 202 priv_policy_errmsg(const cred_t *cr, int priv, const char *msg) 203 { 204 struct proc *me; 205 pc_t stack[MAXPRIVSTACK]; 206 int depth; 207 int i; 208 char *sym; 209 ulong_t off; 210 const char *pname; 211 212 char *cmd; 213 char fmt[sizeof (FMTMAX)]; 214 215 if ((me = curproc) == &p0) 216 return; 217 218 /* Privileges must be defined */ 219 ASSERT(priv == PRIV_ALL || priv == PRIV_MULTIPLE || 220 priv == PRIV_ALLZONE || priv == PRIV_GLOBAL || 221 priv_getbynum(priv) != NULL); 222 223 if (priv == PRIV_ALLZONE && INGLOBALZONE(me)) 224 priv = PRIV_ALL; 225 226 if (curthread->t_pre_sys) 227 ttolwp(curthread)->lwp_badpriv = (short)priv; 228 229 if (priv_debug == 0 && (CR_FLAGS(cr) & PRIV_DEBUG) == 0) 230 return; 231 232 (void) strcpy(fmt, FMTHDR); 233 234 if (me->p_user.u_comm[0]) 235 cmd = &me->p_user.u_comm[0]; 236 else 237 cmd = "priv_policy"; 238 239 if (msg != NULL && *msg != '\0') { 240 (void) strcat(fmt, FMTMSG); 241 } else { 242 (void) strcat(fmt, "%s"); 243 msg = ""; 244 } 245 246 sym = NULL; 247 248 depth = getpcstack(stack, MAXPRIVSTACK); 249 250 /* 251 * Try to find the first interesting function on the stack. 252 * priv_policy* that's us, so completely uninteresting. 253 * suser(), drv_priv(), secpolicy_* are also called from 254 * too many locations to convey useful information. 255 */ 256 for (i = 0; i < depth; i++) { 257 sym = kobj_getsymname((uintptr_t)stack[i], &off); 258 if (sym != NULL && 259 strstr(sym, "hasprocperm") == 0 && 260 strcmp("suser", sym) != 0 && 261 strcmp("ipcaccess", sym) != 0 && 262 strcmp("drv_priv", sym) != 0 && 263 strncmp("secpolicy_", sym, 10) != 0 && 264 strncmp("priv_policy", sym, 11) != 0) 265 break; 266 } 267 268 if (sym != NULL) 269 (void) strcat(fmt, FMTFUN); 270 271 (void) strcat(fmt, "\n"); 272 273 switch (priv) { 274 case PRIV_ALL: 275 pname = "ALL"; 276 break; 277 case PRIV_MULTIPLE: 278 pname = "MULTIPLE"; 279 break; 280 case PRIV_ALLZONE: 281 pname = "ZONE"; 282 break; 283 case PRIV_GLOBAL: 284 pname = "GLOBAL"; 285 break; 286 default: 287 pname = priv_getbynum(priv); 288 break; 289 } 290 291 if (CR_FLAGS(cr) & PRIV_DEBUG) { 292 /* Remember last message, just like lwp_badpriv. */ 293 if (curthread->t_pdmsg != NULL) { 294 kmem_free(curthread->t_pdmsg, 295 strlen(curthread->t_pdmsg) + 1); 296 } 297 298 curthread->t_pdmsg = mprintf(fmt, cmd, me->p_pid, pname, 299 cr->cr_uid, curthread->t_sysnum, msg, sym, off); 300 301 curthread->t_post_sys = 1; 302 } else { 303 cmn_err(CE_NOTE, fmt, cmd, me->p_pid, pname, cr->cr_uid, 304 curthread->t_sysnum, msg, sym, off); 305 } 306 } 307 308 /* 309 * Audit failure, log error message. 310 */ 311 static void 312 priv_policy_err(const cred_t *cr, int priv, boolean_t allzone, const char *msg) 313 { 314 315 #ifdef C2_AUDIT 316 if (audit_active) 317 audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 0); 318 #endif 319 DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone); 320 321 if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || 322 curthread->t_pre_sys) { 323 if (allzone && !HAS_ALLZONEPRIVS(cr)) { 324 priv_policy_errmsg(cr, PRIV_ALLZONE, msg); 325 } else { 326 ASSERT(!HAS_PRIVILEGE(cr, priv)); 327 priv_policy_errmsg(cr, priv, msg); 328 } 329 } 330 } 331 332 /* 333 * priv_policy() 334 * return 0 or error. 335 * See block comment above for a description of "priv" and "allzone" usage. 336 */ 337 int 338 priv_policy(const cred_t *cr, int priv, boolean_t allzone, int err, 339 const char *msg) 340 { 341 if (HAS_PRIVILEGE(cr, priv) && (!allzone || HAS_ALLZONEPRIVS(cr))) { 342 if ((allzone || priv == PRIV_ALL || 343 !PRIV_ISASSERT(priv_basic, priv)) && 344 !servicing_interrupt()) { 345 PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */ 346 #ifdef C2_AUDIT 347 if (audit_active) 348 audit_priv(priv, 349 allzone ? ZONEPRIVS(cr) : NULL, 1); 350 #endif 351 } 352 err = 0; 353 DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone); 354 } else if (!servicing_interrupt()) { 355 /* Failure audited in this procedure */ 356 priv_policy_err(cr, priv, allzone, msg); 357 } 358 359 return (err); 360 } 361 362 /* 363 * Return B_TRUE for sufficient privileges, B_FALSE for insufficient privileges. 364 */ 365 boolean_t 366 priv_policy_choice(const cred_t *cr, int priv, boolean_t allzone) 367 { 368 boolean_t res = HAS_PRIVILEGE(cr, priv) && 369 (!allzone || HAS_ALLZONEPRIVS(cr)); 370 371 #ifdef C2_AUDIT 372 /* Audit success only */ 373 if (res && audit_active && 374 (allzone || priv == PRIV_ALL || !PRIV_ISASSERT(priv_basic, priv)) && 375 !servicing_interrupt()) { 376 audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 1); 377 } 378 #endif 379 if (res) { 380 DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone); 381 } else { 382 DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone); 383 } 384 return (res); 385 } 386 387 /* 388 * Non-auditing variant of priv_policy_choice(). 389 */ 390 boolean_t 391 priv_policy_only(const cred_t *cr, int priv, boolean_t allzone) 392 { 393 boolean_t res = HAS_PRIVILEGE(cr, priv) && 394 (!allzone || HAS_ALLZONEPRIVS(cr)); 395 396 if (res) { 397 DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone); 398 } else { 399 DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone); 400 } 401 return (res); 402 } 403 404 /* 405 * Check whether all privileges in the required set are present. 406 */ 407 static int 408 secpolicy_require_set(const cred_t *cr, const priv_set_t *req, const char *msg) 409 { 410 int priv; 411 int pfound = -1; 412 priv_set_t pset; 413 414 if (req == PRIV_FULLSET ? HAS_ALLPRIVS(cr) : priv_issubset(req, 415 &CR_OEPRIV(cr))) { 416 return (0); 417 } 418 419 if (req == PRIV_FULLSET || priv_isfullset(req)) { 420 priv_policy_err(cr, PRIV_ALL, B_FALSE, msg); 421 return (EACCES); 422 } 423 424 pset = CR_OEPRIV(cr); /* present privileges */ 425 priv_inverse(&pset); /* all non present privileges */ 426 priv_intersect(req, &pset); /* the actual missing privs */ 427 428 #ifdef C2_AUDIT 429 if (audit_active) 430 audit_priv(PRIV_NONE, &pset, 0); 431 #endif 432 /* 433 * Privilege debugging; special case "one privilege in set". 434 */ 435 if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || curthread->t_pre_sys) { 436 for (priv = 0; priv < nprivs; priv++) { 437 if (priv_ismember(&pset, priv)) { 438 if (pfound != -1) { 439 /* Multiple missing privs */ 440 priv_policy_errmsg(cr, PRIV_MULTIPLE, 441 msg); 442 return (EACCES); 443 } 444 pfound = priv; 445 } 446 } 447 ASSERT(pfound != -1); 448 /* Just the one missing privilege */ 449 priv_policy_errmsg(cr, pfound, msg); 450 } 451 452 return (EACCES); 453 } 454 455 /* 456 * Called when an operation requires that the caller be in the 457 * global zone, regardless of privilege. 458 */ 459 static int 460 priv_policy_global(const cred_t *cr) 461 { 462 if (crgetzoneid(cr) == GLOBAL_ZONEID) 463 return (0); /* success */ 464 465 if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || 466 curthread->t_pre_sys) { 467 priv_policy_errmsg(cr, PRIV_GLOBAL, NULL); 468 } 469 return (EPERM); 470 } 471 472 /* 473 * Changing process priority 474 */ 475 int 476 secpolicy_setpriority(const cred_t *cr) 477 { 478 return (PRIV_POLICY(cr, PRIV_PROC_PRIOCNTL, B_FALSE, EPERM, NULL)); 479 } 480 481 /* 482 * Binding to a privileged port, port must be specified in host byte 483 * order. 484 */ 485 int 486 secpolicy_net_privaddr(const cred_t *cr, in_port_t port) 487 { 488 char *reason; 489 int priv; 490 491 switch (port) { 492 case 137: 493 case 138: 494 case 139: 495 case 445: 496 /* 497 * NBT and SMB ports, these are extra privileged ports, 498 * allow bind only if the SYS_SMB privilege is present. 499 */ 500 priv = PRIV_SYS_SMB; 501 reason = "NBT or SMB port"; 502 break; 503 504 case 2049: 505 case 4045: 506 /* 507 * NFS ports, these are extra privileged ports, allow bind 508 * only if the SYS_NFS privilege is present. 509 */ 510 priv = PRIV_SYS_NFS; 511 reason = "NFS port"; 512 break; 513 514 default: 515 priv = PRIV_NET_PRIVADDR; 516 reason = NULL; 517 break; 518 519 } 520 521 return (PRIV_POLICY(cr, priv, B_FALSE, EACCES, reason)); 522 } 523 524 /* 525 * Binding to a multilevel port on a trusted (labeled) system. 526 */ 527 int 528 secpolicy_net_bindmlp(const cred_t *cr) 529 { 530 return (PRIV_POLICY(cr, PRIV_NET_BINDMLP, B_FALSE, EACCES, 531 NULL)); 532 } 533 534 /* 535 * Allow a communication between a zone and an unlabeled host when their 536 * labels don't match. 537 */ 538 int 539 secpolicy_net_mac_aware(const cred_t *cr) 540 { 541 return (PRIV_POLICY(cr, PRIV_NET_MAC_AWARE, B_FALSE, EACCES, 542 NULL)); 543 } 544 545 /* 546 * Common routine which determines whether a given credential can 547 * act on a given mount. 548 * When called through mount, the parameter needoptcheck is a pointer 549 * to a boolean variable which will be set to either true or false, 550 * depending on whether the mount policy should change the mount options. 551 * In all other cases, needoptcheck should be a NULL pointer. 552 */ 553 static int 554 secpolicy_fs_common(cred_t *cr, vnode_t *mvp, const vfs_t *vfsp, 555 boolean_t *needoptcheck) 556 { 557 boolean_t allzone = B_FALSE; 558 boolean_t mounting = needoptcheck != NULL; 559 560 /* 561 * Short circuit the following cases: 562 * vfsp == NULL or mvp == NULL (pure privilege check) 563 * have all privileges - no further checks required 564 * and no mount options need to be set. 565 */ 566 if (vfsp == NULL || mvp == NULL || HAS_ALLPRIVS(cr)) { 567 if (mounting) 568 *needoptcheck = B_FALSE; 569 570 return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, allzone, EPERM, NULL)); 571 } 572 573 /* 574 * When operating on an existing mount (either we're not mounting 575 * or we're doing a remount and VFS_REMOUNT will be set), zones 576 * can operate only on mounts established by the zone itself. 577 */ 578 if (!mounting || (vfsp->vfs_flag & VFS_REMOUNT) != 0) { 579 zoneid_t zoneid = crgetzoneid(cr); 580 581 if (zoneid != GLOBAL_ZONEID && 582 vfsp->vfs_zone->zone_id != zoneid) { 583 return (EPERM); 584 } 585 } 586 587 if (mounting) 588 *needoptcheck = B_TRUE; 589 590 /* 591 * Overlay mounts may hide important stuff; if you can't write to a 592 * mount point but would be able to mount on top of it, you can 593 * escalate your privileges. 594 * So we go about asking the same questions namefs does when it 595 * decides whether you can mount over a file or not but with the 596 * added restriction that you can only mount on top of a regular 597 * file or directory. 598 * If we have all the zone's privileges, we skip all other checks, 599 * or else we may actually get in trouble inside the automounter. 600 */ 601 if ((mvp->v_flag & VROOT) != 0 || 602 (mvp->v_type != VDIR && mvp->v_type != VREG) || 603 HAS_ALLZONEPRIVS(cr)) { 604 allzone = B_TRUE; 605 } else { 606 vattr_t va; 607 int err; 608 609 va.va_mask = AT_UID|AT_MODE; 610 err = VOP_GETATTR(mvp, &va, 0, cr, NULL); 611 if (err != 0) 612 return (err); 613 614 if ((err = secpolicy_vnode_owner(cr, va.va_uid)) != 0) 615 return (err); 616 617 if ((va.va_mode & VWRITE) == 0 && 618 secpolicy_vnode_access(cr, mvp, va.va_uid, VWRITE) != 0) { 619 return (EACCES); 620 } 621 } 622 return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, allzone, EPERM, NULL)); 623 } 624 625 void 626 secpolicy_fs_mount_clearopts(cred_t *cr, struct vfs *vfsp) 627 { 628 boolean_t amsuper = HAS_ALLZONEPRIVS(cr); 629 630 /* 631 * check; if we don't have either "nosuid" or 632 * both "nosetuid" and "nodevices", then we add 633 * "nosuid"; this depends on how the current 634 * implementation works (it first checks nosuid). In a 635 * zone, a user with all zone privileges can mount with 636 * "setuid" but never with "devices". 637 */ 638 if (!vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL) && 639 (!vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL) || 640 !vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL))) { 641 if (crgetzoneid(cr) == GLOBAL_ZONEID || !amsuper) 642 vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0); 643 else 644 vfs_setmntopt(vfsp, MNTOPT_NODEVICES, NULL, 0); 645 } 646 /* 647 * If we're not the local super user, we set the "restrict" 648 * option to indicate to automountd that this mount should 649 * be handled with care. 650 */ 651 if (!amsuper) 652 vfs_setmntopt(vfsp, MNTOPT_RESTRICT, NULL, 0); 653 654 } 655 656 extern vnode_t *rootvp; 657 extern vfs_t *rootvfs; 658 659 int 660 secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct vfs *vfsp) 661 { 662 boolean_t needoptchk; 663 int error; 664 665 /* 666 * If it's a remount, get the underlying mount point, 667 * except for the root where we use the rootvp. 668 */ 669 if ((vfsp->vfs_flag & VFS_REMOUNT) != 0) { 670 if (vfsp == rootvfs) 671 mvp = rootvp; 672 else 673 mvp = vfsp->vfs_vnodecovered; 674 } 675 676 error = secpolicy_fs_common(cr, mvp, vfsp, &needoptchk); 677 678 if (error == 0 && needoptchk) { 679 secpolicy_fs_mount_clearopts(cr, vfsp); 680 } 681 682 return (error); 683 } 684 685 /* 686 * Does the policy computations for "ownership" of a mount; 687 * here ownership is defined as the ability to "mount" 688 * the filesystem originally. The rootvfs doesn't cover any 689 * vnodes; we attribute its ownership to the rootvp. 690 */ 691 static int 692 secpolicy_fs_owner(cred_t *cr, const struct vfs *vfsp) 693 { 694 vnode_t *mvp; 695 696 if (vfsp == NULL) 697 mvp = NULL; 698 else if (vfsp == rootvfs) 699 mvp = rootvp; 700 else 701 mvp = vfsp->vfs_vnodecovered; 702 703 return (secpolicy_fs_common(cr, mvp, vfsp, NULL)); 704 } 705 706 int 707 secpolicy_fs_unmount(cred_t *cr, struct vfs *vfsp) 708 { 709 return (secpolicy_fs_owner(cr, vfsp)); 710 } 711 712 /* 713 * Quotas are a resource, but if one has the ability to mount a filesystem, he 714 * should be able to modify quotas on it. 715 */ 716 int 717 secpolicy_fs_quota(const cred_t *cr, const vfs_t *vfsp) 718 { 719 return (secpolicy_fs_owner((cred_t *)cr, vfsp)); 720 } 721 722 /* 723 * Exceeding minfree: also a per-mount resource constraint. 724 */ 725 int 726 secpolicy_fs_minfree(const cred_t *cr, const vfs_t *vfsp) 727 { 728 return (secpolicy_fs_owner((cred_t *)cr, vfsp)); 729 } 730 731 int 732 secpolicy_fs_config(const cred_t *cr, const vfs_t *vfsp) 733 { 734 return (secpolicy_fs_owner((cred_t *)cr, vfsp)); 735 } 736 737 /* ARGSUSED */ 738 int 739 secpolicy_fs_linkdir(const cred_t *cr, const vfs_t *vfsp) 740 { 741 return (PRIV_POLICY(cr, PRIV_SYS_LINKDIR, B_FALSE, EPERM, NULL)); 742 } 743 744 /* 745 * Name: secpolicy_vnode_access() 746 * 747 * Parameters: Process credential 748 * vnode 749 * uid of owner of vnode 750 * permission bits not granted to the caller when examining 751 * file mode bits (i.e., when a process wants to open a 752 * mode 444 file for VREAD|VWRITE, this function should be 753 * called only with a VWRITE argument). 754 * 755 * Normal: Verifies that cred has the appropriate privileges to 756 * override the mode bits that were denied. 757 * 758 * Override: file_dac_execute - if VEXEC bit was denied and vnode is 759 * not a directory. 760 * file_dac_read - if VREAD bit was denied. 761 * file_dac_search - if VEXEC bit was denied and vnode is 762 * a directory. 763 * file_dac_write - if VWRITE bit was denied. 764 * 765 * Root owned files are special cased to protect system 766 * configuration files and such. 767 * 768 * Output: EACCES - if privilege check fails. 769 */ 770 771 /* ARGSUSED */ 772 int 773 secpolicy_vnode_access(const cred_t *cr, vnode_t *vp, uid_t owner, mode_t mode) 774 { 775 if ((mode & VREAD) && 776 PRIV_POLICY(cr, PRIV_FILE_DAC_READ, B_FALSE, EACCES, NULL) != 0) 777 return (EACCES); 778 779 if (mode & VWRITE) { 780 boolean_t allzone; 781 782 if (owner == 0 && cr->cr_uid != 0) 783 allzone = B_TRUE; 784 else 785 allzone = B_FALSE; 786 if (PRIV_POLICY(cr, PRIV_FILE_DAC_WRITE, allzone, EACCES, NULL) 787 != 0) 788 return (EACCES); 789 } 790 791 if (mode & VEXEC) { 792 /* 793 * Directories use file_dac_search to override the execute bit. 794 */ 795 vtype_t vtype = vp->v_type; 796 797 if (vtype == VDIR) 798 return (PRIV_POLICY(cr, PRIV_FILE_DAC_SEARCH, B_FALSE, 799 EACCES, NULL)); 800 else 801 return (PRIV_POLICY(cr, PRIV_FILE_DAC_EXECUTE, B_FALSE, 802 EACCES, NULL)); 803 } 804 return (0); 805 } 806 807 /* 808 * Name: secpolicy_vnode_setid_modify() 809 * 810 * Normal: verify that subject can set the file setid flags. 811 * 812 * Output: EPERM - if not privileged. 813 */ 814 815 static int 816 secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner) 817 { 818 /* If changing to suid root, must have all zone privs */ 819 boolean_t allzone = B_TRUE; 820 821 if (owner != 0) { 822 if (owner == cr->cr_uid) 823 return (0); 824 allzone = B_FALSE; 825 } 826 return (PRIV_POLICY(cr, PRIV_FILE_SETID, allzone, EPERM, NULL)); 827 } 828 829 /* 830 * Are we allowed to retain the set-uid/set-gid bits when 831 * changing ownership or when writing to a file? 832 * "issuid" should be true when set-uid; only in that case 833 * root ownership is checked (setgid is assumed). 834 */ 835 int 836 secpolicy_vnode_setid_retain(const cred_t *cred, boolean_t issuidroot) 837 { 838 if (issuidroot && !HAS_ALLZONEPRIVS(cred)) 839 return (EPERM); 840 841 return (!PRIV_POLICY_CHOICE(cred, PRIV_FILE_SETID, B_FALSE)); 842 } 843 844 /* 845 * Name: secpolicy_vnode_setids_setgids() 846 * 847 * Normal: verify that subject can set the file setgid flag. 848 * 849 * Output: EPERM - if not privileged 850 */ 851 852 int 853 secpolicy_vnode_setids_setgids(const cred_t *cred, gid_t gid) 854 { 855 if (!groupmember(gid, cred)) 856 return (PRIV_POLICY(cred, PRIV_FILE_SETID, B_FALSE, EPERM, 857 NULL)); 858 return (0); 859 } 860 861 /* 862 * Create a file with a group different than any of the groups allowed: 863 * the group of the directory the file is created in, the effective 864 * group or any of the supplementary groups. 865 */ 866 int 867 secpolicy_vnode_create_gid(const cred_t *cred) 868 { 869 if (HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN)) 870 return (PRIV_POLICY(cred, PRIV_FILE_CHOWN, B_FALSE, EPERM, 871 NULL)); 872 else 873 return (PRIV_POLICY(cred, PRIV_FILE_CHOWN_SELF, B_FALSE, EPERM, 874 NULL)); 875 } 876 877 /* 878 * Name: secpolicy_vnode_utime_modify() 879 * 880 * Normal: verify that subject can modify the utime on a file. 881 * 882 * Output: EPERM - if access denied. 883 */ 884 885 static int 886 secpolicy_vnode_utime_modify(const cred_t *cred) 887 { 888 return (PRIV_POLICY(cred, PRIV_FILE_OWNER, B_FALSE, EPERM, 889 "modify file times")); 890 } 891 892 893 /* 894 * Name: secpolicy_vnode_setdac() 895 * 896 * Normal: verify that subject can modify the mode of a file. 897 * allzone privilege needed when modifying root owned object. 898 * 899 * Output: EPERM - if access denied. 900 */ 901 902 int 903 secpolicy_vnode_setdac(const cred_t *cred, uid_t owner) 904 { 905 if (owner == cred->cr_uid) 906 return (0); 907 908 return (PRIV_POLICY(cred, PRIV_FILE_OWNER, owner == 0, EPERM, NULL)); 909 } 910 /* 911 * Name: secpolicy_vnode_stky_modify() 912 * 913 * Normal: verify that subject can make a file a "sticky". 914 * 915 * Output: EPERM - if access denied. 916 */ 917 918 int 919 secpolicy_vnode_stky_modify(const cred_t *cred) 920 { 921 return (PRIV_POLICY(cred, PRIV_SYS_CONFIG, B_FALSE, EPERM, 922 "set file sticky")); 923 } 924 925 /* 926 * Policy determines whether we can remove an entry from a directory, 927 * regardless of permission bits. 928 */ 929 int 930 secpolicy_vnode_remove(const cred_t *cr) 931 { 932 return (PRIV_POLICY(cr, PRIV_FILE_OWNER, B_FALSE, EACCES, 933 "sticky directory")); 934 } 935 936 int 937 secpolicy_vnode_owner(const cred_t *cr, uid_t owner) 938 { 939 boolean_t allzone = (owner == 0); 940 941 if (owner == cr->cr_uid) 942 return (0); 943 944 return (PRIV_POLICY(cr, PRIV_FILE_OWNER, allzone, EPERM, NULL)); 945 } 946 947 void 948 secpolicy_setid_clear(vattr_t *vap, cred_t *cr) 949 { 950 if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0 && 951 secpolicy_vnode_setid_retain(cr, 952 (vap->va_mode & S_ISUID) != 0 && 953 (vap->va_mask & AT_UID) != 0 && vap->va_uid == 0) != 0) { 954 vap->va_mask |= AT_MODE; 955 vap->va_mode &= ~(S_ISUID|S_ISGID); 956 } 957 } 958 959 int 960 secpolicy_setid_setsticky_clear(vnode_t *vp, vattr_t *vap, const vattr_t *ovap, 961 cred_t *cr) 962 { 963 int error; 964 965 if ((vap->va_mode & S_ISUID) != 0 && 966 (error = secpolicy_vnode_setid_modify(cr, 967 ovap->va_uid)) != 0) { 968 return (error); 969 } 970 971 /* 972 * Check privilege if attempting to set the 973 * sticky bit on a non-directory. 974 */ 975 if (vp->v_type != VDIR && (vap->va_mode & S_ISVTX) != 0 && 976 secpolicy_vnode_stky_modify(cr) != 0) { 977 vap->va_mode &= ~S_ISVTX; 978 } 979 980 /* 981 * Check for privilege if attempting to set the 982 * group-id bit. 983 */ 984 if ((vap->va_mode & S_ISGID) != 0 && 985 secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) { 986 vap->va_mode &= ~S_ISGID; 987 } 988 989 return (0); 990 } 991 992 #define ATTR_FLAG_PRIV(attr, value, cr) \ 993 PRIV_POLICY(cr, value ? PRIV_FILE_FLAG_SET : PRIV_ALL, \ 994 B_FALSE, EPERM, NULL) 995 996 /* 997 * Check privileges for setting xvattr attributes 998 */ 999 int 1000 secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype) 1001 { 1002 xoptattr_t *xoap; 1003 int error = 0; 1004 1005 if ((xoap = xva_getxoptattr(xvap)) == NULL) 1006 return (EINVAL); 1007 1008 /* 1009 * First process the DOS bits 1010 */ 1011 if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE) || 1012 XVA_ISSET_REQ(xvap, XAT_HIDDEN) || 1013 XVA_ISSET_REQ(xvap, XAT_READONLY) || 1014 XVA_ISSET_REQ(xvap, XAT_SYSTEM) || 1015 XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { 1016 if ((error = secpolicy_vnode_owner(cr, owner)) != 0) 1017 return (error); 1018 } 1019 1020 /* 1021 * Now handle special attributes 1022 */ 1023 1024 if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) 1025 error = ATTR_FLAG_PRIV(XAT_IMMUTABLE, 1026 xoap->xoa_immutable, cr); 1027 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) 1028 error = ATTR_FLAG_PRIV(XAT_NOUNLINK, 1029 xoap->xoa_nounlink, cr); 1030 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) 1031 error = ATTR_FLAG_PRIV(XAT_APPENDONLY, 1032 xoap->xoa_appendonly, cr); 1033 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NODUMP)) 1034 error = ATTR_FLAG_PRIV(XAT_NODUMP, 1035 xoap->xoa_nodump, cr); 1036 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_OPAQUE)) 1037 error = EPERM; 1038 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { 1039 error = ATTR_FLAG_PRIV(XAT_AV_QUARANTINED, 1040 xoap->xoa_av_quarantined, cr); 1041 if (error == 0 && vtype != VREG) 1042 error = EINVAL; 1043 } 1044 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) 1045 error = ATTR_FLAG_PRIV(XAT_AV_MODIFIED, 1046 xoap->xoa_av_modified, cr); 1047 if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) { 1048 error = ATTR_FLAG_PRIV(XAT_AV_SCANSTAMP, 1049 xoap->xoa_av_scanstamp, cr); 1050 if (error == 0 && vtype != VREG) 1051 error = EINVAL; 1052 } 1053 return (error); 1054 } 1055 1056 /* 1057 * This function checks the policy decisions surrounding the 1058 * vop setattr call. 1059 * 1060 * It should be called after sufficient locks have been established 1061 * on the underlying data structures. No concurrent modifications 1062 * should be allowed. 1063 * 1064 * The caller must pass in unlocked version of its vaccess function 1065 * this is required because vop_access function should lock the 1066 * node for reading. A three argument function should be defined 1067 * which accepts the following argument: 1068 * A pointer to the internal "node" type (inode *) 1069 * vnode access bits (VREAD|VWRITE|VEXEC) 1070 * a pointer to the credential 1071 * 1072 * This function makes the following policy decisions: 1073 * 1074 * - change permissions 1075 * - permission to change file mode if not owner 1076 * - permission to add sticky bit to non-directory 1077 * - permission to add set-gid bit 1078 * 1079 * The ovap argument should include AT_MODE|AT_UID|AT_GID. 1080 * 1081 * If the vap argument does not include AT_MODE, the mode will be copied from 1082 * ovap. In certain situations set-uid/set-gid bits need to be removed; 1083 * this is done by marking vap->va_mask to include AT_MODE and va_mode 1084 * is updated to the newly computed mode. 1085 */ 1086 1087 int 1088 secpolicy_vnode_setattr(cred_t *cr, struct vnode *vp, struct vattr *vap, 1089 const struct vattr *ovap, int flags, 1090 int unlocked_access(void *, int, cred_t *), 1091 void *node) 1092 { 1093 int mask = vap->va_mask; 1094 int error = 0; 1095 boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; 1096 1097 if (mask & AT_SIZE) { 1098 if (vp->v_type == VDIR) { 1099 error = EISDIR; 1100 goto out; 1101 } 1102 1103 /* 1104 * If ATTR_NOACLCHECK is set in the flags, then we don't 1105 * perform the secondary unlocked_access() call since the 1106 * ACL (if any) is being checked there. 1107 */ 1108 if (skipaclchk == B_FALSE) { 1109 error = unlocked_access(node, VWRITE, cr); 1110 if (error) 1111 goto out; 1112 } 1113 } 1114 if (mask & AT_MODE) { 1115 /* 1116 * If not the owner of the file then check privilege 1117 * for two things: the privilege to set the mode at all 1118 * and, if we're setting setuid, we also need permissions 1119 * to add the set-uid bit, if we're not the owner. 1120 * In the specific case of creating a set-uid root 1121 * file, we need even more permissions. 1122 */ 1123 if ((error = secpolicy_vnode_setdac(cr, ovap->va_uid)) != 0) 1124 goto out; 1125 1126 if ((error = secpolicy_setid_setsticky_clear(vp, vap, 1127 ovap, cr)) != 0) 1128 goto out; 1129 } else 1130 vap->va_mode = ovap->va_mode; 1131 1132 if (mask & (AT_UID|AT_GID)) { 1133 boolean_t checkpriv = B_FALSE; 1134 int priv; 1135 boolean_t allzone = B_FALSE; 1136 1137 /* 1138 * Chowning files. 1139 * 1140 * If you are the file owner: 1141 * chown to other uid FILE_CHOWN_SELF 1142 * chown to gid (non-member) FILE_CHOWN_SELF 1143 * chown to gid (member) <none> 1144 * 1145 * Instead of PRIV_FILE_CHOWN_SELF, FILE_CHOWN is also 1146 * acceptable but the first one is reported when debugging. 1147 * 1148 * If you are not the file owner: 1149 * chown from root PRIV_FILE_CHOWN + zone 1150 * chown from other to any PRIV_FILE_CHOWN 1151 * 1152 */ 1153 if (cr->cr_uid != ovap->va_uid) { 1154 checkpriv = B_TRUE; 1155 allzone = (ovap->va_uid == 0); 1156 priv = PRIV_FILE_CHOWN; 1157 } else { 1158 if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) || 1159 ((mask & AT_GID) && vap->va_gid != ovap->va_gid && 1160 !groupmember(vap->va_gid, cr))) { 1161 checkpriv = B_TRUE; 1162 priv = HAS_PRIVILEGE(cr, PRIV_FILE_CHOWN) ? 1163 PRIV_FILE_CHOWN : PRIV_FILE_CHOWN_SELF; 1164 } 1165 } 1166 /* 1167 * If necessary, check privilege to see if update can be done. 1168 */ 1169 if (checkpriv && 1170 (error = PRIV_POLICY(cr, priv, allzone, EPERM, NULL)) 1171 != 0) { 1172 goto out; 1173 } 1174 1175 /* 1176 * If the file has either the set UID or set GID bits 1177 * set and the caller can set the bits, then leave them. 1178 */ 1179 secpolicy_setid_clear(vap, cr); 1180 } 1181 if (mask & (AT_ATIME|AT_MTIME)) { 1182 /* 1183 * If not the file owner and not otherwise privileged, 1184 * always return an error when setting the 1185 * time other than the current (ATTR_UTIME flag set). 1186 * If setting the current time (ATTR_UTIME not set) then 1187 * unlocked_access will check permissions according to policy. 1188 */ 1189 if (cr->cr_uid != ovap->va_uid) { 1190 if (flags & ATTR_UTIME) 1191 error = secpolicy_vnode_utime_modify(cr); 1192 else if (skipaclchk == B_FALSE) { 1193 error = unlocked_access(node, VWRITE, cr); 1194 if (error == EACCES && 1195 secpolicy_vnode_utime_modify(cr) == 0) 1196 error = 0; 1197 } 1198 if (error) 1199 goto out; 1200 } 1201 } 1202 1203 /* 1204 * Check for optional attributes here by checking the following: 1205 */ 1206 if (mask & AT_XVATTR) 1207 error = secpolicy_xvattr((xvattr_t *)vap, ovap->va_uid, cr, 1208 vp->v_type); 1209 out: 1210 return (error); 1211 } 1212 1213 /* 1214 * Name: secpolicy_pcfs_modify_bootpartition() 1215 * 1216 * Normal: verify that subject can modify a pcfs boot partition. 1217 * 1218 * Output: EACCES - if privilege check failed. 1219 */ 1220 /*ARGSUSED*/ 1221 int 1222 secpolicy_pcfs_modify_bootpartition(const cred_t *cred) 1223 { 1224 return (PRIV_POLICY(cred, PRIV_ALL, B_FALSE, EACCES, 1225 "modify pcfs boot partition")); 1226 } 1227 1228 /* 1229 * System V IPC routines 1230 */ 1231 int 1232 secpolicy_ipc_owner(const cred_t *cr, const struct kipc_perm *ip) 1233 { 1234 if (crgetzoneid(cr) != ip->ipc_zoneid || 1235 (cr->cr_uid != ip->ipc_uid && cr->cr_uid != ip->ipc_cuid)) { 1236 boolean_t allzone = B_FALSE; 1237 if (ip->ipc_uid == 0 || ip->ipc_cuid == 0) 1238 allzone = B_TRUE; 1239 return (PRIV_POLICY(cr, PRIV_IPC_OWNER, allzone, EPERM, NULL)); 1240 } 1241 return (0); 1242 } 1243 1244 int 1245 secpolicy_ipc_config(const cred_t *cr) 1246 { 1247 return (PRIV_POLICY(cr, PRIV_SYS_IPC_CONFIG, B_FALSE, EPERM, NULL)); 1248 } 1249 1250 int 1251 secpolicy_ipc_access(const cred_t *cr, const struct kipc_perm *ip, mode_t mode) 1252 { 1253 1254 boolean_t allzone = B_FALSE; 1255 1256 ASSERT((mode & (MSG_R|MSG_W)) != 0); 1257 1258 if ((mode & MSG_R) && 1259 PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0) 1260 return (EACCES); 1261 1262 if (mode & MSG_W) { 1263 if (cr->cr_uid != 0 && (ip->ipc_uid == 0 || ip->ipc_cuid == 0)) 1264 allzone = B_TRUE; 1265 1266 return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES, 1267 NULL)); 1268 } 1269 return (0); 1270 } 1271 1272 int 1273 secpolicy_rsm_access(const cred_t *cr, uid_t owner, mode_t mode) 1274 { 1275 boolean_t allzone = B_FALSE; 1276 1277 ASSERT((mode & (MSG_R|MSG_W)) != 0); 1278 1279 if ((mode & MSG_R) && 1280 PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0) 1281 return (EACCES); 1282 1283 if (mode & MSG_W) { 1284 if (cr->cr_uid != 0 && owner == 0) 1285 allzone = B_TRUE; 1286 1287 return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES, 1288 NULL)); 1289 } 1290 return (0); 1291 } 1292 1293 /* 1294 * Audit configuration. 1295 */ 1296 int 1297 secpolicy_audit_config(const cred_t *cr) 1298 { 1299 return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL)); 1300 } 1301 1302 /* 1303 * Audit record generation. 1304 */ 1305 int 1306 secpolicy_audit_modify(const cred_t *cr) 1307 { 1308 return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM, NULL)); 1309 } 1310 1311 /* 1312 * Get audit attributes. 1313 * Either PRIV_SYS_AUDIT or PRIV_PROC_AUDIT required; report the 1314 * "Least" of the two privileges on error. 1315 */ 1316 int 1317 secpolicy_audit_getattr(const cred_t *cr) 1318 { 1319 if (!PRIV_POLICY_ONLY(cr, PRIV_SYS_AUDIT, B_FALSE)) { 1320 return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM, 1321 NULL)); 1322 } else { 1323 return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL)); 1324 } 1325 } 1326 1327 1328 /* 1329 * Locking physical memory 1330 */ 1331 int 1332 secpolicy_lock_memory(const cred_t *cr) 1333 { 1334 return (PRIV_POLICY(cr, PRIV_PROC_LOCK_MEMORY, B_FALSE, EPERM, NULL)); 1335 } 1336 1337 /* 1338 * Accounting (both acct(2) and exacct). 1339 */ 1340 int 1341 secpolicy_acct(const cred_t *cr) 1342 { 1343 return (PRIV_POLICY(cr, PRIV_SYS_ACCT, B_FALSE, EPERM, NULL)); 1344 } 1345 1346 /* 1347 * Is this process privileged to change its uids at will? 1348 * Uid 0 is still considered "special" and having the SETID 1349 * privilege is not sufficient to get uid 0. 1350 * Files are owned by root, so the privilege would give 1351 * full access and euid 0 is still effective. 1352 * 1353 * If you have the privilege and euid 0 only then do you 1354 * get the powers of root wrt uid 0. 1355 * 1356 * For gid manipulations, this is should be called with an 1357 * uid of -1. 1358 * 1359 */ 1360 int 1361 secpolicy_allow_setid(const cred_t *cr, uid_t newuid, boolean_t checkonly) 1362 { 1363 boolean_t allzone = B_FALSE; 1364 1365 if (newuid == 0 && cr->cr_uid != 0 && cr->cr_suid != 0 && 1366 cr->cr_ruid != 0) { 1367 allzone = B_TRUE; 1368 } 1369 1370 return (checkonly ? !PRIV_POLICY_ONLY(cr, PRIV_PROC_SETID, allzone) : 1371 PRIV_POLICY(cr, PRIV_PROC_SETID, allzone, EPERM, NULL)); 1372 } 1373 1374 1375 /* 1376 * Acting on a different process: if the mode is for writing, 1377 * the restrictions are more severe. This is called after 1378 * we've verified that the uids do not match. 1379 */ 1380 int 1381 secpolicy_proc_owner(const cred_t *scr, const cred_t *tcr, int mode) 1382 { 1383 boolean_t allzone = B_FALSE; 1384 1385 if ((mode & VWRITE) && scr->cr_uid != 0 && 1386 (tcr->cr_uid == 0 || tcr->cr_ruid == 0 || tcr->cr_suid == 0)) 1387 allzone = B_TRUE; 1388 1389 return (PRIV_POLICY(scr, PRIV_PROC_OWNER, allzone, EPERM, NULL)); 1390 } 1391 1392 int 1393 secpolicy_proc_access(const cred_t *scr) 1394 { 1395 return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EACCES, NULL)); 1396 } 1397 1398 int 1399 secpolicy_proc_excl_open(const cred_t *scr) 1400 { 1401 return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EBUSY, NULL)); 1402 } 1403 1404 int 1405 secpolicy_proc_zone(const cred_t *scr) 1406 { 1407 return (PRIV_POLICY(scr, PRIV_PROC_ZONE, B_FALSE, EPERM, NULL)); 1408 } 1409 1410 /* 1411 * Destroying the system 1412 */ 1413 1414 int 1415 secpolicy_kmdb(const cred_t *scr) 1416 { 1417 return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL)); 1418 } 1419 1420 int 1421 secpolicy_error_inject(const cred_t *scr) 1422 { 1423 return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL)); 1424 } 1425 1426 /* 1427 * Processor sets, cpu configuration, resource pools. 1428 */ 1429 int 1430 secpolicy_pset(const cred_t *cr) 1431 { 1432 return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1433 } 1434 1435 int 1436 secpolicy_ponline(const cred_t *cr) 1437 { 1438 return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1439 } 1440 1441 int 1442 secpolicy_pool(const cred_t *cr) 1443 { 1444 return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1445 } 1446 1447 int 1448 secpolicy_blacklist(const cred_t *cr) 1449 { 1450 return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL)); 1451 } 1452 1453 /* 1454 * Catch all system configuration. 1455 */ 1456 int 1457 secpolicy_sys_config(const cred_t *cr, boolean_t checkonly) 1458 { 1459 if (checkonly) { 1460 return (PRIV_POLICY_ONLY(cr, PRIV_SYS_CONFIG, B_FALSE) ? 0 : 1461 EPERM); 1462 } else { 1463 return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 1464 } 1465 } 1466 1467 /* 1468 * Zone administration (halt, reboot, etc.) from within zone. 1469 */ 1470 int 1471 secpolicy_zone_admin(const cred_t *cr, boolean_t checkonly) 1472 { 1473 if (checkonly) { 1474 return (PRIV_POLICY_ONLY(cr, PRIV_SYS_ADMIN, B_FALSE) ? 0 : 1475 EPERM); 1476 } else { 1477 return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, 1478 NULL)); 1479 } 1480 } 1481 1482 /* 1483 * Zone configuration (create, halt, enter). 1484 */ 1485 int 1486 secpolicy_zone_config(const cred_t *cr) 1487 { 1488 /* 1489 * Require all privileges to avoid possibility of privilege 1490 * escalation. 1491 */ 1492 return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 1493 } 1494 1495 /* 1496 * Various other system configuration calls 1497 */ 1498 int 1499 secpolicy_coreadm(const cred_t *cr) 1500 { 1501 return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL)); 1502 } 1503 1504 int 1505 secpolicy_systeminfo(const cred_t *cr) 1506 { 1507 return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL)); 1508 } 1509 1510 int 1511 secpolicy_dispadm(const cred_t *cr) 1512 { 1513 return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 1514 } 1515 1516 int 1517 secpolicy_settime(const cred_t *cr) 1518 { 1519 return (PRIV_POLICY(cr, PRIV_SYS_TIME, B_FALSE, EPERM, NULL)); 1520 } 1521 1522 /* 1523 * For realtime users: high resolution clock. 1524 */ 1525 int 1526 secpolicy_clock_highres(const cred_t *cr) 1527 { 1528 return (PRIV_POLICY(cr, PRIV_PROC_CLOCK_HIGHRES, B_FALSE, EPERM, 1529 NULL)); 1530 } 1531 1532 /* 1533 * drv_priv() is documented as callable from interrupt context, not that 1534 * anyone ever does, but still. No debugging or auditing can be done when 1535 * it is called from interrupt context. 1536 * returns 0 on succes, EPERM on failure. 1537 */ 1538 int 1539 drv_priv(cred_t *cr) 1540 { 1541 return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 1542 } 1543 1544 int 1545 secpolicy_sys_devices(const cred_t *cr) 1546 { 1547 return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 1548 } 1549 1550 int 1551 secpolicy_excl_open(const cred_t *cr) 1552 { 1553 return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EBUSY, NULL)); 1554 } 1555 1556 int 1557 secpolicy_rctlsys(const cred_t *cr, boolean_t is_zone_rctl) 1558 { 1559 /* zone.* rctls can only be set from the global zone */ 1560 if (is_zone_rctl && priv_policy_global(cr) != 0) 1561 return (EPERM); 1562 return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL)); 1563 } 1564 1565 int 1566 secpolicy_resource(const cred_t *cr) 1567 { 1568 return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL)); 1569 } 1570 1571 /* 1572 * Processes with a real uid of 0 escape any form of accounting, much 1573 * like before. 1574 */ 1575 int 1576 secpolicy_newproc(const cred_t *cr) 1577 { 1578 if (cr->cr_ruid == 0) 1579 return (0); 1580 1581 return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL)); 1582 } 1583 1584 /* 1585 * Networking 1586 */ 1587 int 1588 secpolicy_net_rawaccess(const cred_t *cr) 1589 { 1590 return (PRIV_POLICY(cr, PRIV_NET_RAWACCESS, B_FALSE, EACCES, NULL)); 1591 } 1592 1593 /* 1594 * Need this privilege for accessing the ICMP device 1595 */ 1596 int 1597 secpolicy_net_icmpaccess(const cred_t *cr) 1598 { 1599 return (PRIV_POLICY(cr, PRIV_NET_ICMPACCESS, B_FALSE, EACCES, NULL)); 1600 } 1601 1602 /* 1603 * There are a few rare cases where the kernel generates ioctls() from 1604 * interrupt context with a credential of kcred rather than NULL. 1605 * In those cases, we take the safe and cheap test. 1606 */ 1607 int 1608 secpolicy_net_config(const cred_t *cr, boolean_t checkonly) 1609 { 1610 if (checkonly) { 1611 return (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE) ? 1612 0 : EPERM); 1613 } else { 1614 return (PRIV_POLICY(cr, PRIV_SYS_NET_CONFIG, B_FALSE, EPERM, 1615 NULL)); 1616 } 1617 } 1618 1619 1620 /* 1621 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG. 1622 * 1623 * There are a few rare cases where the kernel generates ioctls() from 1624 * interrupt context with a credential of kcred rather than NULL. 1625 * In those cases, we take the safe and cheap test. 1626 */ 1627 int 1628 secpolicy_ip_config(const cred_t *cr, boolean_t checkonly) 1629 { 1630 if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) 1631 return (secpolicy_net_config(cr, checkonly)); 1632 1633 if (checkonly) { 1634 return (PRIV_POLICY_ONLY(cr, PRIV_SYS_IP_CONFIG, B_FALSE) ? 1635 0 : EPERM); 1636 } else { 1637 return (PRIV_POLICY(cr, PRIV_SYS_IP_CONFIG, B_FALSE, EPERM, 1638 NULL)); 1639 } 1640 } 1641 1642 1643 /* 1644 * Map IP pseudo privileges to actual privileges. 1645 * So we don't need to recompile IP when we change the privileges. 1646 */ 1647 int 1648 secpolicy_ip(const cred_t *cr, int netpriv, boolean_t checkonly) 1649 { 1650 int priv = PRIV_ALL; 1651 1652 switch (netpriv) { 1653 case OP_CONFIG: 1654 priv = PRIV_SYS_IP_CONFIG; 1655 break; 1656 case OP_RAW: 1657 priv = PRIV_NET_RAWACCESS; 1658 break; 1659 case OP_PRIVPORT: 1660 priv = PRIV_NET_PRIVADDR; 1661 break; 1662 } 1663 ASSERT(priv != PRIV_ALL); 1664 if (checkonly) 1665 return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM); 1666 else 1667 return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL)); 1668 } 1669 1670 /* 1671 * Map network pseudo privileges to actual privileges. 1672 * So we don't need to recompile IP when we change the privileges. 1673 */ 1674 int 1675 secpolicy_net(const cred_t *cr, int netpriv, boolean_t checkonly) 1676 { 1677 int priv = PRIV_ALL; 1678 1679 switch (netpriv) { 1680 case OP_CONFIG: 1681 priv = PRIV_SYS_NET_CONFIG; 1682 break; 1683 case OP_RAW: 1684 priv = PRIV_NET_RAWACCESS; 1685 break; 1686 case OP_PRIVPORT: 1687 priv = PRIV_NET_PRIVADDR; 1688 break; 1689 } 1690 ASSERT(priv != PRIV_ALL); 1691 if (checkonly) 1692 return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM); 1693 else 1694 return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL)); 1695 } 1696 1697 /* 1698 * Checks for operations that are either client-only or are used by 1699 * both clients and servers. 1700 */ 1701 int 1702 secpolicy_nfs(const cred_t *cr) 1703 { 1704 return (PRIV_POLICY(cr, PRIV_SYS_NFS, B_FALSE, EPERM, NULL)); 1705 } 1706 1707 /* 1708 * Special case for opening rpcmod: have NFS privileges or network 1709 * config privileges. 1710 */ 1711 int 1712 secpolicy_rpcmod_open(const cred_t *cr) 1713 { 1714 if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NFS, B_FALSE)) 1715 return (secpolicy_nfs(cr)); 1716 else 1717 return (secpolicy_net_config(cr, NULL)); 1718 } 1719 1720 int 1721 secpolicy_chroot(const cred_t *cr) 1722 { 1723 return (PRIV_POLICY(cr, PRIV_PROC_CHROOT, B_FALSE, EPERM, NULL)); 1724 } 1725 1726 int 1727 secpolicy_tasksys(const cred_t *cr) 1728 { 1729 return (PRIV_POLICY(cr, PRIV_PROC_TASKID, B_FALSE, EPERM, NULL)); 1730 } 1731 1732 /* 1733 * Basic privilege checks. 1734 */ 1735 int 1736 secpolicy_basic_exec(const cred_t *cr) 1737 { 1738 return (PRIV_POLICY(cr, PRIV_PROC_EXEC, B_FALSE, EPERM, NULL)); 1739 } 1740 1741 int 1742 secpolicy_basic_fork(const cred_t *cr) 1743 { 1744 return (PRIV_POLICY(cr, PRIV_PROC_FORK, B_FALSE, EPERM, NULL)); 1745 } 1746 1747 int 1748 secpolicy_basic_proc(const cred_t *cr) 1749 { 1750 return (PRIV_POLICY(cr, PRIV_PROC_SESSION, B_FALSE, EPERM, NULL)); 1751 } 1752 1753 /* 1754 * Slightly complicated because we don't want to trigger the policy too 1755 * often. First we shortcircuit access to "self" (tp == sp) or if 1756 * we don't have the privilege but if we have permission 1757 * just return (0) and we don't flag the privilege as needed. 1758 * Else, we test for the privilege because we either have it or need it. 1759 */ 1760 int 1761 secpolicy_basic_procinfo(const cred_t *cr, proc_t *tp, proc_t *sp) 1762 { 1763 if (tp == sp || 1764 !HAS_PRIVILEGE(cr, PRIV_PROC_INFO) && prochasprocperm(tp, sp, cr)) { 1765 return (0); 1766 } else { 1767 return (PRIV_POLICY(cr, PRIV_PROC_INFO, B_FALSE, EPERM, NULL)); 1768 } 1769 } 1770 1771 int 1772 secpolicy_basic_link(const cred_t *cr) 1773 { 1774 return (PRIV_POLICY(cr, PRIV_FILE_LINK_ANY, B_FALSE, EPERM, NULL)); 1775 } 1776 1777 /* 1778 * Additional device protection. 1779 * 1780 * Traditionally, a device has specific permissions on the node in 1781 * the filesystem which govern which devices can be opened by what 1782 * processes. In certain cases, it is desirable to add extra 1783 * restrictions, as writing to certain devices is identical to 1784 * having a complete run of the system. 1785 * 1786 * This mechanism is called the device policy. 1787 * 1788 * When a device is opened, its policy entry is looked up in the 1789 * policy cache and checked. 1790 */ 1791 int 1792 secpolicy_spec_open(const cred_t *cr, struct vnode *vp, int oflag) 1793 { 1794 devplcy_t *plcy; 1795 int err; 1796 struct snode *csp = VTOS(common_specvp(vp)); 1797 priv_set_t pset; 1798 1799 mutex_enter(&csp->s_lock); 1800 1801 if (csp->s_plcy == NULL || csp->s_plcy->dp_gen != devplcy_gen) { 1802 plcy = devpolicy_find(vp); 1803 if (csp->s_plcy) 1804 dpfree(csp->s_plcy); 1805 csp->s_plcy = plcy; 1806 ASSERT(plcy != NULL); 1807 } else 1808 plcy = csp->s_plcy; 1809 1810 if (plcy == nullpolicy) { 1811 mutex_exit(&csp->s_lock); 1812 return (0); 1813 } 1814 1815 dphold(plcy); 1816 1817 mutex_exit(&csp->s_lock); 1818 1819 if (oflag & FWRITE) 1820 pset = plcy->dp_wrp; 1821 else 1822 pset = plcy->dp_rdp; 1823 /* 1824 * Special case: 1825 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG. 1826 * If PRIV_SYS_NET_CONFIG is present and PRIV_SYS_IP_CONFIG is 1827 * required, replace PRIV_SYS_IP_CONFIG with PRIV_SYS_NET_CONFIG 1828 * in the required privilege set before doing the check. 1829 */ 1830 if (priv_ismember(&pset, PRIV_SYS_IP_CONFIG) && 1831 priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_NET_CONFIG) && 1832 !priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_IP_CONFIG)) { 1833 priv_delset(&pset, PRIV_SYS_IP_CONFIG); 1834 priv_addset(&pset, PRIV_SYS_NET_CONFIG); 1835 } 1836 1837 err = secpolicy_require_set(cr, &pset, "devpolicy"); 1838 dpfree(plcy); 1839 1840 return (err); 1841 } 1842 1843 int 1844 secpolicy_modctl(const cred_t *cr, int cmd) 1845 { 1846 switch (cmd) { 1847 case MODINFO: 1848 case MODGETMAJBIND: 1849 case MODGETPATH: 1850 case MODGETPATHLEN: 1851 case MODGETNAME: 1852 case MODGETFBNAME: 1853 case MODGETDEVPOLICY: 1854 case MODGETDEVPOLICYBYNAME: 1855 case MODDEVT2INSTANCE: 1856 case MODSIZEOF_DEVID: 1857 case MODGETDEVID: 1858 case MODSIZEOF_MINORNAME: 1859 case MODGETMINORNAME: 1860 case MODGETDEVFSPATH_LEN: 1861 case MODGETDEVFSPATH: 1862 case MODGETDEVFSPATH_MI_LEN: 1863 case MODGETDEVFSPATH_MI: 1864 /* Unprivileged */ 1865 return (0); 1866 case MODLOAD: 1867 case MODSETDEVPOLICY: 1868 return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 1869 default: 1870 return (secpolicy_sys_config(cr, B_FALSE)); 1871 } 1872 } 1873 1874 int 1875 secpolicy_console(const cred_t *cr) 1876 { 1877 return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 1878 } 1879 1880 int 1881 secpolicy_power_mgmt(const cred_t *cr) 1882 { 1883 return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL)); 1884 } 1885 1886 /* 1887 * Simulate terminal input; another escalation of privileges avenue. 1888 */ 1889 1890 int 1891 secpolicy_sti(const cred_t *cr) 1892 { 1893 return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 1894 } 1895 1896 boolean_t 1897 secpolicy_net_reply_equal(const cred_t *cr) 1898 { 1899 return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 1900 } 1901 1902 int 1903 secpolicy_swapctl(const cred_t *cr) 1904 { 1905 return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL)); 1906 } 1907 1908 int 1909 secpolicy_cpc_cpu(const cred_t *cr) 1910 { 1911 return (PRIV_POLICY(cr, PRIV_CPC_CPU, B_FALSE, EACCES, NULL)); 1912 } 1913 1914 /* 1915 * secpolicy_contract_observer 1916 * 1917 * Determine if the subject may observe a specific contract's events. 1918 */ 1919 int 1920 secpolicy_contract_observer(const cred_t *cr, struct contract *ct) 1921 { 1922 if (contract_owned(ct, cr, B_FALSE)) 1923 return (0); 1924 return (PRIV_POLICY(cr, PRIV_CONTRACT_OBSERVER, B_FALSE, EPERM, NULL)); 1925 } 1926 1927 /* 1928 * secpolicy_contract_observer_choice 1929 * 1930 * Determine if the subject may observe any contract's events. Just 1931 * tests privilege and audits on success. 1932 */ 1933 boolean_t 1934 secpolicy_contract_observer_choice(const cred_t *cr) 1935 { 1936 return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_OBSERVER, B_FALSE)); 1937 } 1938 1939 /* 1940 * secpolicy_contract_event 1941 * 1942 * Determine if the subject may request critical contract events or 1943 * reliable contract event delivery. 1944 */ 1945 int 1946 secpolicy_contract_event(const cred_t *cr) 1947 { 1948 return (PRIV_POLICY(cr, PRIV_CONTRACT_EVENT, B_FALSE, EPERM, NULL)); 1949 } 1950 1951 /* 1952 * secpolicy_contract_event_choice 1953 * 1954 * Determine if the subject may retain contract events in its critical 1955 * set when a change in other terms would normally require a change in 1956 * the critical set. Just tests privilege and audits on success. 1957 */ 1958 boolean_t 1959 secpolicy_contract_event_choice(const cred_t *cr) 1960 { 1961 return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_EVENT, B_FALSE)); 1962 } 1963 1964 /* 1965 * secpolicy_gart_access 1966 * 1967 * Determine if the subject has sufficient priveleges to make ioctls to agpgart 1968 * device. 1969 */ 1970 int 1971 secpolicy_gart_access(const cred_t *cr) 1972 { 1973 return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM, NULL)); 1974 } 1975 1976 /* 1977 * secpolicy_gart_map 1978 * 1979 * Determine if the subject has sufficient priveleges to map aperture range 1980 * through agpgart driver. 1981 */ 1982 int 1983 secpolicy_gart_map(const cred_t *cr) 1984 { 1985 if (PRIV_POLICY_ONLY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE)) { 1986 return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM, 1987 NULL)); 1988 } else { 1989 return (PRIV_POLICY(cr, PRIV_GRAPHICS_MAP, B_FALSE, EPERM, 1990 NULL)); 1991 } 1992 } 1993 1994 /* 1995 * secpolicy_zinject 1996 * 1997 * Determine if the subject can inject faults in the ZFS fault injection 1998 * framework. Requires all privileges. 1999 */ 2000 int 2001 secpolicy_zinject(const cred_t *cr) 2002 { 2003 return (secpolicy_require_set(cr, PRIV_FULLSET, NULL)); 2004 } 2005 2006 /* 2007 * secpolicy_zfs 2008 * 2009 * Determine if the subject has permission to manipulate ZFS datasets 2010 * (not pools). Equivalent to the SYS_MOUNT privilege. 2011 */ 2012 int 2013 secpolicy_zfs(const cred_t *cr) 2014 { 2015 return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, B_FALSE, EPERM, NULL)); 2016 } 2017 2018 /* 2019 * secpolicy_idmap 2020 * 2021 * Determine if the calling process has permissions to register an SID 2022 * mapping daemon and allocate ephemeral IDs. 2023 */ 2024 int 2025 secpolicy_idmap(const cred_t *cr) 2026 { 2027 return (PRIV_POLICY(cr, PRIV_ALL, B_FALSE, EPERM, NULL)); 2028 } 2029 2030 /* 2031 * secpolicy_ucode_update 2032 * 2033 * Determine if the subject has sufficient privilege to update microcode. 2034 */ 2035 int 2036 secpolicy_ucode_update(const cred_t *scr) 2037 { 2038 return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL)); 2039 } 2040 2041 /* 2042 * secpolicy_sadopen 2043 * 2044 * Determine if the subject has sufficient privilege to access /dev/sad/admin. 2045 * /dev/sad/admin appear in global zone and exclusive-IP zones only. 2046 * In global zone, sys_config is required. 2047 * In exclusive-IP zones, sys_ip_config is required. 2048 * Note that sys_config is prohibited in non-global zones. 2049 */ 2050 int 2051 secpolicy_sadopen(const cred_t *credp) 2052 { 2053 priv_set_t pset; 2054 2055 priv_emptyset(&pset); 2056 2057 if (crgetzoneid(credp) == GLOBAL_ZONEID) 2058 priv_addset(&pset, PRIV_SYS_CONFIG); 2059 else 2060 priv_addset(&pset, PRIV_SYS_IP_CONFIG); 2061 2062 return (secpolicy_require_set(credp, &pset, "devpolicy")); 2063 } 2064 2065 /* 2066 * secpolicy_smb 2067 * 2068 * Determine if the cred_t has PRIV_SYS_SMB privilege, indicating 2069 * that it has permission to access the smbsrv kernel driver. 2070 * PRIV_POLICY checks the privilege and audits the check. 2071 * 2072 * Returns: 2073 * 0 Driver access is allowed. 2074 * EPERM Driver access is NOT permitted. 2075 */ 2076 int 2077 secpolicy_smb(const cred_t *cr) 2078 { 2079 return (PRIV_POLICY(cr, PRIV_SYS_SMB, B_FALSE, EPERM, NULL)); 2080 } 2081 2082 /* 2083 * secpolicy_vscan 2084 * 2085 * Determine if cred_t has the necessary privileges to access a file 2086 * for virus scanning and update its extended system attributes. 2087 * PRIV_FILE_DAC_SEARCH, PRIV_FILE_DAC_READ - file access 2088 * PRIV_FILE_FLAG_SET - set extended system attributes 2089 * 2090 * PRIV_POLICY checks the privilege and audits the check. 2091 * 2092 * Returns: 2093 * 0 file access for virus scanning allowed. 2094 * EPERM file access for virus scanning is NOT permitted. 2095 */ 2096 int 2097 secpolicy_vscan(const cred_t *cr) 2098 { 2099 if ((PRIV_POLICY(cr, PRIV_FILE_DAC_SEARCH, B_FALSE, EPERM, NULL)) || 2100 (PRIV_POLICY(cr, PRIV_FILE_DAC_READ, B_FALSE, EPERM, NULL)) || 2101 (PRIV_POLICY(cr, PRIV_FILE_FLAG_SET, B_FALSE, EPERM, NULL))) { 2102 return (EPERM); 2103 } 2104 2105 return (0); 2106 } 2107