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