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