The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/security/mac_bsdextended/mac_bsdextended.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
    3  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
    4  * Copyright (c) 2005 Tom Rhodes
    5  * All rights reserved.
    6  *
    7  * This software was developed by Robert Watson for the TrustedBSD Project.
    8  * It was later enhanced by Tom Rhodes for the TrustedBSD Project.
    9  *
   10  * This software was developed for the FreeBSD Project in part by Network
   11  * Associates Laboratories, the Security Research Division of Network
   12  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
   13  * as part of the DARPA CHATS research program.
   14  *
   15  * Redistribution and use in source and binary forms, with or without
   16  * modification, are permitted provided that the following conditions
   17  * are met:
   18  * 1. Redistributions of source code must retain the above copyright
   19  *    notice, this list of conditions and the following disclaimer.
   20  * 2. Redistributions in binary form must reproduce the above copyright
   21  *    notice, this list of conditions and the following disclaimer in the
   22  *    documentation and/or other materials provided with the distribution.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  * $FreeBSD: releng/7.3/sys/security/mac_bsdextended/mac_bsdextended.c 190167 2009-03-20 18:04:20Z csjp $
   37  */
   38 
   39 /*
   40  * Developed by the TrustedBSD Project.
   41  *
   42  * "BSD Extended" MAC policy, allowing the administrator to impose mandatory
   43  * firewall-like rules regarding users and file system objects.
   44  */
   45 
   46 #include <sys/param.h>
   47 #include <sys/acl.h>
   48 #include <sys/kernel.h>
   49 #include <sys/jail.h>
   50 #include <sys/lock.h>
   51 #include <sys/malloc.h>
   52 #include <sys/module.h>
   53 #include <sys/mount.h>
   54 #include <sys/mutex.h>
   55 #include <sys/priv.h>
   56 #include <sys/proc.h>
   57 #include <sys/systm.h>
   58 #include <sys/vnode.h>
   59 #include <sys/sysctl.h>
   60 #include <sys/syslog.h>
   61 
   62 #include <security/mac/mac_policy.h>
   63 #include <security/mac_bsdextended/mac_bsdextended.h>
   64 
   65 static struct mtx ugidfw_mtx;
   66 
   67 SYSCTL_DECL(_security_mac);
   68 
   69 SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0,
   70     "TrustedBSD extended BSD MAC policy controls");
   71 
   72 static int      ugidfw_enabled = 1;
   73 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW,
   74     &ugidfw_enabled, 0, "Enforce extended BSD policy");
   75 TUNABLE_INT("security.mac.bsdextended.enabled", &ugidfw_enabled);
   76 
   77 MALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule");
   78 
   79 #define MAC_BSDEXTENDED_MAXRULES        250
   80 static struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES];
   81 static int rule_count = 0;
   82 static int rule_slots = 0;
   83 static int rule_version = MB_VERSION;
   84 
   85 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
   86     &rule_count, 0, "Number of defined rules\n");
   87 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
   88     &rule_slots, 0, "Number of used rule slots\n");
   89 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD,
   90     &rule_version, 0, "Version number for API\n");
   91 
   92 /*
   93  * This is just used for logging purposes, eventually we would like to log
   94  * much more then failed requests.
   95  */
   96 static int ugidfw_logging;
   97 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW,
   98     &ugidfw_logging, 0, "Log failed authorization requests");
   99 
  100 /*
  101  * This tunable is here for compatibility.  It will allow the user to switch
  102  * between the new mode (first rule matches) and the old functionality (all
  103  * rules match).
  104  */
  105 static int ugidfw_firstmatch_enabled;
  106 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
  107     CTLFLAG_RW, &ugidfw_firstmatch_enabled, 1,
  108     "Disable/enable match first rule functionality");
  109 
  110 static int
  111 ugidfw_rule_valid(struct mac_bsdextended_rule *rule)
  112 {
  113 
  114         if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
  115                 return (EINVAL);
  116         if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
  117                 return (EINVAL);
  118         if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
  119                 return (EINVAL);
  120         if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
  121                 return (EINVAL);
  122         if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) &&
  123             (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE)
  124                 return (EINVAL);
  125         if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM)
  126                 return (EINVAL);
  127         return (0);
  128 }
  129 
  130 static int
  131 sysctl_rule(SYSCTL_HANDLER_ARGS)
  132 {
  133         struct mac_bsdextended_rule temprule, *ruleptr;
  134         u_int namelen;
  135         int error, index, *name;
  136 
  137         error = 0;
  138         name = (int *)arg1;
  139         namelen = arg2;
  140         if (namelen != 1)
  141                 return (EINVAL);
  142         index = name[0];
  143         if (index >= MAC_BSDEXTENDED_MAXRULES)
  144                 return (ENOENT);
  145 
  146         ruleptr = NULL;
  147         if (req->newptr && req->newlen != 0) {
  148                 error = SYSCTL_IN(req, &temprule, sizeof(temprule));
  149                 if (error)
  150                         return (error);
  151                 MALLOC(ruleptr, struct mac_bsdextended_rule *,
  152                     sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO);
  153         }
  154 
  155         mtx_lock(&ugidfw_mtx);
  156         if (req->oldptr) {
  157                 if (index < 0 || index > rule_slots + 1) {
  158                         error = ENOENT;
  159                         goto out;
  160                 }
  161                 if (rules[index] == NULL) {
  162                         error = ENOENT;
  163                         goto out;
  164                 }
  165                 temprule = *rules[index];
  166         }
  167         if (req->newptr && req->newlen == 0) {
  168                 KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL"));
  169                 ruleptr = rules[index];
  170                 if (ruleptr == NULL) {
  171                         error = ENOENT;
  172                         goto out;
  173                 }
  174                 rule_count--;
  175                 rules[index] = NULL;
  176         } else if (req->newptr) {
  177                 error = ugidfw_rule_valid(&temprule);
  178                 if (error)
  179                         goto out;
  180                 if (rules[index] == NULL) {
  181                         *ruleptr = temprule;
  182                         rules[index] = ruleptr;
  183                         ruleptr = NULL;
  184                         if (index + 1 > rule_slots)
  185                                 rule_slots = index + 1;
  186                         rule_count++;
  187                 } else
  188                         *rules[index] = temprule;
  189         }
  190 out:
  191         mtx_unlock(&ugidfw_mtx);
  192         if (ruleptr != NULL)
  193                 FREE(ruleptr, M_MACBSDEXTENDED);
  194         if (req->oldptr && error == 0)
  195                 error = SYSCTL_OUT(req, &temprule, sizeof(temprule));
  196         return (error);
  197 }
  198 
  199 SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
  200     CTLFLAG_MPSAFE | CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
  201 
  202 static void
  203 ugidfw_init(struct mac_policy_conf *mpc)
  204 {
  205 
  206         mtx_init(&ugidfw_mtx, "mac_bsdextended lock", NULL, MTX_DEF);
  207 }
  208 
  209 static void
  210 ugidfw_destroy(struct mac_policy_conf *mpc)
  211 {
  212         int i;
  213 
  214         for (i = 0; i < MAC_BSDEXTENDED_MAXRULES; i++) {
  215                 if (rules[i] != NULL)
  216                         free(rules[i], M_MACBSDEXTENDED);
  217         }
  218         mtx_destroy(&ugidfw_mtx);
  219 }
  220 
  221 static int
  222 ugidfw_rulecheck(struct mac_bsdextended_rule *rule,
  223     struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode)
  224 {
  225         int match;
  226         int i;
  227 
  228         /*
  229          * Is there a subject match?
  230          */
  231         mtx_assert(&ugidfw_mtx, MA_OWNED);
  232         if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) {
  233                 match =  ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max &&
  234                     cred->cr_uid >= rule->mbr_subject.mbs_uid_min) ||
  235                     (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max &&
  236                     cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) ||
  237                     (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max &&
  238                     cred->cr_svuid >= rule->mbr_subject.mbs_uid_min));
  239                 if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED)
  240                         match = !match;
  241                 if (!match)
  242                         return (0);
  243         }
  244 
  245         if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) {
  246                 match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max &&
  247                     cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) ||
  248                     (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max &&
  249                     cred->cr_svgid >= rule->mbr_subject.mbs_gid_min));
  250                 if (!match) {
  251                         for (i = 0; i < cred->cr_ngroups; i++) {
  252                                 if (cred->cr_groups[i]
  253                                     <= rule->mbr_subject.mbs_gid_max &&
  254                                     cred->cr_groups[i]
  255                                     >= rule->mbr_subject.mbs_gid_min) {
  256                                         match = 1;
  257                                         break;
  258                                 }
  259                         }
  260                 }
  261                 if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED)
  262                         match = !match;
  263                 if (!match)
  264                         return (0);
  265         }
  266 
  267         if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) {
  268                 match = (cred->cr_prison != NULL &&
  269                     cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison);
  270                 if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED)
  271                         match = !match;
  272                 if (!match)
  273                         return (0);
  274         }
  275 
  276         /*
  277          * Is there an object match?
  278          */
  279         if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) {
  280                 match = (vap->va_uid <= rule->mbr_object.mbo_uid_max &&
  281                     vap->va_uid >= rule->mbr_object.mbo_uid_min);
  282                 if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED)
  283                         match = !match;
  284                 if (!match)
  285                         return (0);
  286         }
  287 
  288         if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) {
  289                 match = (vap->va_gid <= rule->mbr_object.mbo_gid_max &&
  290                     vap->va_gid >= rule->mbr_object.mbo_gid_min);
  291                 if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED)
  292                         match = !match;
  293                 if (!match)
  294                         return (0);
  295         }
  296 
  297         if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) {
  298                 match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid),
  299                     &(rule->mbr_object.mbo_fsid),
  300                     sizeof(rule->mbr_object.mbo_fsid)) == 0);
  301                 if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED)
  302                         match = !match;
  303                 if (!match)
  304                         return (0);
  305         }
  306 
  307         if (rule->mbr_object.mbo_flags & MBO_SUID) {
  308                 match = (vap->va_mode & VSUID);
  309                 if (rule->mbr_object.mbo_neg & MBO_SUID)
  310                         match = !match;
  311                 if (!match)
  312                         return (0);
  313         }
  314 
  315         if (rule->mbr_object.mbo_flags & MBO_SGID) {
  316                 match = (vap->va_mode & VSGID);
  317                 if (rule->mbr_object.mbo_neg & MBO_SGID)
  318                         match = !match;
  319                 if (!match)
  320                         return (0);
  321         }
  322 
  323         if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) {
  324                 match = (vap->va_uid == cred->cr_uid ||
  325                     vap->va_uid == cred->cr_ruid ||
  326                     vap->va_uid == cred->cr_svuid);
  327                 if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT)
  328                         match = !match;
  329                 if (!match)
  330                         return (0);
  331         }
  332 
  333         if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) {
  334                 match = (groupmember(vap->va_gid, cred) ||
  335                     vap->va_gid == cred->cr_rgid ||
  336                     vap->va_gid == cred->cr_svgid);
  337                 if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT)
  338                         match = !match;
  339                 if (!match)
  340                         return (0);
  341         }
  342 
  343         if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) {
  344                 switch (vap->va_type) {
  345                 case VREG:
  346                         match = (rule->mbr_object.mbo_type & MBO_TYPE_REG);
  347                         break;
  348                 case VDIR:
  349                         match = (rule->mbr_object.mbo_type & MBO_TYPE_DIR);
  350                         break;
  351                 case VBLK:
  352                         match = (rule->mbr_object.mbo_type & MBO_TYPE_BLK);
  353                         break;
  354                 case VCHR:
  355                         match = (rule->mbr_object.mbo_type & MBO_TYPE_CHR);
  356                         break;
  357                 case VLNK:
  358                         match = (rule->mbr_object.mbo_type & MBO_TYPE_LNK);
  359                         break;
  360                 case VSOCK:
  361                         match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK);
  362                         break;
  363                 case VFIFO:
  364                         match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO);
  365                         break;
  366                 default:
  367                         match = 0;
  368                 }
  369                 if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED)
  370                         match = !match;
  371                 if (!match)
  372                         return (0);
  373         }
  374 
  375         /*
  376          * Is the access permitted?
  377          */
  378         if ((rule->mbr_mode & acc_mode) != acc_mode) {
  379                 if (ugidfw_logging)
  380                         log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
  381                             " on %d:%d failed. \n", cred->cr_ruid,
  382                             cred->cr_rgid, acc_mode, vap->va_uid,
  383                             vap->va_gid);
  384                 return (EACCES);
  385         }
  386 
  387         /*
  388          * If the rule matched, permits access, and first match is enabled,
  389          * return success.
  390          */
  391         if (ugidfw_firstmatch_enabled)
  392                 return (EJUSTRETURN);
  393         else
  394                 return (0);
  395 }
  396 
  397 static int
  398 ugidfw_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
  399     int acc_mode)
  400 {
  401         int error, i;
  402 
  403         /*
  404          * XXXRW: More specific privilege selection needed.
  405          */
  406         if (suser_cred(cred, 0) == 0)
  407                 return (0);
  408 
  409         /*
  410          * Since we do not separately handle append, map append to write.
  411          */
  412         if (acc_mode & MBI_APPEND) {
  413                 acc_mode &= ~MBI_APPEND;
  414                 acc_mode |= MBI_WRITE;
  415         }
  416         mtx_lock(&ugidfw_mtx);
  417         for (i = 0; i < rule_slots; i++) {
  418                 if (rules[i] == NULL)
  419                         continue;
  420                 error = ugidfw_rulecheck(rules[i], cred,
  421                     vp, vap, acc_mode);
  422                 if (error == EJUSTRETURN)
  423                         break;
  424                 if (error) {
  425                         mtx_unlock(&ugidfw_mtx);
  426                         return (error);
  427                 }
  428         }
  429         mtx_unlock(&ugidfw_mtx);
  430         return (0);
  431 }
  432 
  433 static int
  434 ugidfw_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode)
  435 {
  436         int error;
  437         struct vattr vap;
  438 
  439         if (!ugidfw_enabled)
  440                 return (0);
  441         error = VOP_GETATTR(vp, &vap, cred, curthread);
  442         if (error)
  443                 return (error);
  444         return (ugidfw_check(cred, vp, &vap, acc_mode));
  445 }
  446 
  447 static int
  448 ugidfw_check_system_acct(struct ucred *cred, struct vnode *vp,
  449     struct label *vplabel)
  450 {
  451 
  452         if (vp != NULL)
  453                 return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  454         else
  455                 return (0);
  456 }
  457 
  458 static int
  459 ugidfw_check_system_auditctl(struct ucred *cred, struct vnode *vp,
  460     struct label *vplabel)
  461 {
  462 
  463         if (vp != NULL)
  464                 return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  465         else
  466                 return (0);
  467 }
  468 
  469 static int
  470 ugidfw_check_system_swapon(struct ucred *cred, struct vnode *vp,
  471     struct label *vplabel)
  472 {
  473 
  474         return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  475 }
  476 
  477 static int
  478 ugidfw_check_vnode_access(struct ucred *cred, struct vnode *vp,
  479     struct label *vplabel, int acc_mode)
  480 {
  481 
  482         return (ugidfw_check_vp(cred, vp, acc_mode));
  483 }
  484 
  485 static int
  486 ugidfw_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
  487     struct label *dvplabel)
  488 {
  489 
  490         return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
  491 }
  492 
  493 static int
  494 ugidfw_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
  495     struct label *dvplabel)
  496 {
  497 
  498         return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
  499 }
  500 
  501 static int
  502 ugidfw_check_create_vnode(struct ucred *cred, struct vnode *dvp,
  503     struct label *dvplabel, struct componentname *cnp, struct vattr *vap)
  504 {
  505 
  506         return (ugidfw_check_vp(cred, dvp, MBI_WRITE));
  507 }
  508 
  509 static int
  510 ugidfw_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
  511     struct label *vplabel, acl_type_t type)
  512 {
  513 
  514         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  515 }
  516 
  517 static int
  518 ugidfw_check_vnode_deleteextattr(struct ucred *cred,
  519     struct vnode *vp, struct label *vplabel, int attrnamespace,
  520     const char *name)
  521 {
  522 
  523         return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  524 }
  525 
  526 static int
  527 ugidfw_check_vnode_exec(struct ucred *cred, struct vnode *vp,
  528     struct label *vplabel, struct image_params *imgp,
  529     struct label *execlabel)
  530 {
  531 
  532         return (ugidfw_check_vp(cred, vp, MBI_READ|MBI_EXEC));
  533 }
  534 
  535 static int
  536 ugidfw_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
  537     struct label *vplabel, acl_type_t type)
  538 {
  539 
  540         return (ugidfw_check_vp(cred, vp, MBI_STAT));
  541 }
  542 
  543 static int
  544 ugidfw_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
  545     struct label *vplabel, int attrnamespace, const char *name,
  546     struct uio *uio)
  547 {
  548 
  549         return (ugidfw_check_vp(cred, vp, MBI_READ));
  550 }
  551 
  552 static int
  553 ugidfw_check_vnode_link(struct ucred *cred, struct vnode *dvp,
  554     struct label *dvplabel, struct vnode *vp, struct label *label,
  555     struct componentname *cnp)
  556 {
  557         int error;
  558 
  559         error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
  560         if (error)
  561                 return (error);
  562         error = ugidfw_check_vp(cred, vp, MBI_WRITE);
  563         if (error)
  564                 return (error);
  565         return (0);
  566 }
  567 
  568 static int
  569 ugidfw_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
  570     struct label *vplabel, int attrnamespace)
  571 {
  572 
  573         return (ugidfw_check_vp(cred, vp, MBI_READ));
  574 }
  575 
  576 static int
  577 ugidfw_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
  578     struct label *dvplabel, struct componentname *cnp)
  579 {
  580 
  581         return (ugidfw_check_vp(cred, dvp, MBI_EXEC));
  582 }
  583 
  584 static int
  585 ugidfw_check_vnode_open(struct ucred *cred, struct vnode *vp,
  586     struct label *vplabel, int acc_mode)
  587 {
  588 
  589         return (ugidfw_check_vp(cred, vp, acc_mode));
  590 }
  591 
  592 static int
  593 ugidfw_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
  594     struct label *dvplabel)
  595 {
  596 
  597         return (ugidfw_check_vp(cred, dvp, MBI_READ));
  598 }
  599 
  600 static int
  601 ugidfw_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
  602     struct label *vplabel)
  603 {
  604 
  605         return (ugidfw_check_vp(cred, vp, MBI_READ));
  606 }
  607 
  608 static int
  609 ugidfw_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
  610     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
  611     struct componentname *cnp)
  612 {
  613         int error;
  614 
  615         error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
  616         if (error)
  617                 return (error);
  618         return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  619 }
  620 
  621 static int
  622 ugidfw_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
  623     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
  624     int samedir, struct componentname *cnp)
  625 {
  626         int error;
  627 
  628         error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
  629         if (error)
  630                 return (error);
  631         if (vp != NULL)
  632                 error = ugidfw_check_vp(cred, vp, MBI_WRITE);
  633         return (error);
  634 }
  635 
  636 static int
  637 ugidfw_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
  638     struct label *vplabel)
  639 {
  640 
  641         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  642 }
  643 
  644 static int
  645 ugidfw_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
  646     struct label *vplabel, acl_type_t type, struct acl *acl)
  647 {
  648 
  649         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  650 }
  651 
  652 static int
  653 ugidfw_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
  654     struct label *vplabel, int attrnamespace, const char *name,
  655     struct uio *uio)
  656 {
  657 
  658         return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  659 }
  660 
  661 static int
  662 ugidfw_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
  663     struct label *vplabel, u_long flags)
  664 {
  665 
  666         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  667 }
  668 
  669 static int
  670 ugidfw_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
  671     struct label *vplabel, mode_t mode)
  672 {
  673 
  674         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  675 }
  676 
  677 static int
  678 ugidfw_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
  679     struct label *vplabel, uid_t uid, gid_t gid)
  680 {
  681 
  682         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  683 }
  684 
  685 static int
  686 ugidfw_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
  687     struct label *vplabel, struct timespec atime, struct timespec utime)
  688 {
  689 
  690         return (ugidfw_check_vp(cred, vp, MBI_ADMIN));
  691 }
  692 
  693 static int
  694 ugidfw_check_vnode_stat(struct ucred *active_cred,
  695     struct ucred *file_cred, struct vnode *vp, struct label *vplabel)
  696 {
  697 
  698         return (ugidfw_check_vp(active_cred, vp, MBI_STAT));
  699 }
  700 
  701 static int
  702 ugidfw_check_vnode_unlink(struct ucred *cred, struct vnode *dvp,
  703     struct label *dvplabel, struct vnode *vp, struct label *vplabel,
  704     struct componentname *cnp)
  705 {
  706         int error;
  707 
  708         error = ugidfw_check_vp(cred, dvp, MBI_WRITE);
  709         if (error)
  710                 return (error);
  711         return (ugidfw_check_vp(cred, vp, MBI_WRITE));
  712 }
  713 
  714 static struct mac_policy_ops ugidfw_ops =
  715 {
  716         .mpo_destroy = ugidfw_destroy,
  717         .mpo_init = ugidfw_init,
  718         .mpo_check_system_acct = ugidfw_check_system_acct,
  719         .mpo_check_system_auditctl = ugidfw_check_system_auditctl,
  720         .mpo_check_system_swapon = ugidfw_check_system_swapon,
  721         .mpo_check_vnode_access = ugidfw_check_vnode_access,
  722         .mpo_check_vnode_chdir = ugidfw_check_vnode_chdir,
  723         .mpo_check_vnode_chroot = ugidfw_check_vnode_chroot,
  724         .mpo_check_vnode_create = ugidfw_check_create_vnode,
  725         .mpo_check_vnode_deleteacl = ugidfw_check_vnode_deleteacl,
  726         .mpo_check_vnode_deleteextattr = ugidfw_check_vnode_deleteextattr,
  727         .mpo_check_vnode_exec = ugidfw_check_vnode_exec,
  728         .mpo_check_vnode_getacl = ugidfw_check_vnode_getacl,
  729         .mpo_check_vnode_getextattr = ugidfw_check_vnode_getextattr,
  730         .mpo_check_vnode_link = ugidfw_check_vnode_link,
  731         .mpo_check_vnode_listextattr = ugidfw_check_vnode_listextattr,
  732         .mpo_check_vnode_lookup = ugidfw_check_vnode_lookup,
  733         .mpo_check_vnode_open = ugidfw_check_vnode_open,
  734         .mpo_check_vnode_readdir = ugidfw_check_vnode_readdir,
  735         .mpo_check_vnode_readlink = ugidfw_check_vnode_readdlink,
  736         .mpo_check_vnode_rename_from = ugidfw_check_vnode_rename_from,
  737         .mpo_check_vnode_rename_to = ugidfw_check_vnode_rename_to,
  738         .mpo_check_vnode_revoke = ugidfw_check_vnode_revoke,
  739         .mpo_check_vnode_setacl = ugidfw_check_setacl_vnode,
  740         .mpo_check_vnode_setextattr = ugidfw_check_vnode_setextattr,
  741         .mpo_check_vnode_setflags = ugidfw_check_vnode_setflags,
  742         .mpo_check_vnode_setmode = ugidfw_check_vnode_setmode,
  743         .mpo_check_vnode_setowner = ugidfw_check_vnode_setowner,
  744         .mpo_check_vnode_setutimes = ugidfw_check_vnode_setutimes,
  745         .mpo_check_vnode_stat = ugidfw_check_vnode_stat,
  746         .mpo_check_vnode_unlink = ugidfw_check_vnode_unlink,
  747 };
  748 
  749 MAC_POLICY_SET(&ugidfw_ops, mac_bsdextended, "TrustedBSD MAC/BSD Extended",
  750     MPC_LOADTIME_FLAG_UNLOADOK, NULL);

Cache object: 591d04dff4bb3bbe6fea6b85481613f5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.