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/bsd/kern/kern_prot.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) 2000-2003 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
   26 /*
   27  * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
   28  *      The Regents of the University of California.  All rights reserved.
   29  * (c) UNIX System Laboratories, Inc.
   30  * All or some portions of this file are derived from material licensed
   31  * to the University of California by American Telephone and Telegraph
   32  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   33  * the permission of UNIX System Laboratories, Inc.
   34  *
   35  * Redistribution and use in source and binary forms, with or without
   36  * modification, are permitted provided that the following conditions
   37  * are met:
   38  * 1. Redistributions of source code must retain the above copyright
   39  *    notice, this list of conditions and the following disclaimer.
   40  * 2. Redistributions in binary form must reproduce the above copyright
   41  *    notice, this list of conditions and the following disclaimer in the
   42  *    documentation and/or other materials provided with the distribution.
   43  * 3. All advertising materials mentioning features or use of this software
   44  *    must display the following acknowledgement:
   45  *      This product includes software developed by the University of
   46  *      California, Berkeley and its contributors.
   47  * 4. Neither the name of the University nor the names of its contributors
   48  *    may be used to endorse or promote products derived from this software
   49  *    without specific prior written permission.
   50  *
   51  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   53  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   54  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   55  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   58  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   59  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   60  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   61  * SUCH DAMAGE.
   62  *
   63  *      @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
   64  */
   65 
   66 /*
   67  * System calls related to processes and protection
   68  */
   69 
   70 #include <sys/param.h>
   71 #include <sys/acct.h>
   72 #include <sys/systm.h>
   73 #include <sys/ucred.h>
   74 #include <sys/proc.h>
   75 #include <sys/timeb.h>
   76 #include <sys/times.h>
   77 #include <sys/malloc.h>
   78 #include <sys/kern_audit.h>
   79 
   80 #include <sys/mount.h>
   81 #include <mach/message.h>
   82 #include <mach/host_security.h>
   83 
   84 #include <kern/host.h>
   85 
   86 /*
   87  * setprivexec:  (dis)allow this process to hold
   88  * task, thread, or execption ports of processes about to exec.
   89  */
   90 struct setprivexec_args {
   91         int flag;
   92 }; 
   93 int
   94 setprivexec(p, uap, retval)
   95         struct proc *p;
   96         register struct setprivexec_args *uap;
   97         register_t *retval;
   98 {
   99         *retval = p->p_debugger;
  100         p->p_debugger = (uap->flag != 0);
  101         return(0);
  102 }
  103 
  104 /* ARGSUSED */
  105 getpid(p, uap, retval)
  106         struct proc *p;
  107         void *uap;
  108         register_t *retval;
  109 {
  110 
  111         *retval = p->p_pid;
  112 #if COMPAT_43
  113         retval[1] = p->p_pptr->p_pid;
  114 #endif
  115         return (0);
  116 }
  117 
  118 /* ARGSUSED */
  119 getppid(p, uap, retval)
  120         struct proc *p;
  121         void *uap;
  122         register_t *retval;
  123 {
  124 
  125         *retval = p->p_pptr->p_pid;
  126         return (0);
  127 }
  128 
  129 /* Get process group ID; note that POSIX getpgrp takes no parameter */
  130 getpgrp(p, uap, retval)
  131         struct proc *p;
  132         void *uap;
  133         register_t *retval;
  134 {
  135 
  136         *retval = p->p_pgrp->pg_id;
  137         return (0);
  138 }
  139 
  140 /* Get an arbitary pid's process group id */
  141 struct getpgid_args {
  142         pid_t   pid;
  143 };
  144 
  145 int
  146 getpgid(p, uap, retval)
  147         struct proc *p;
  148         struct getpgid_args *uap;
  149         register_t *retval;
  150 {
  151         struct proc *pt;
  152 
  153         pt = p;
  154         if (uap->pid == 0)
  155                 goto found;
  156 
  157         if ((pt = pfind(uap->pid)) == 0)
  158                 return (ESRCH);
  159 found:
  160         *retval = pt->p_pgrp->pg_id;
  161         return (0);
  162 }
  163 
  164 /*
  165  * Get an arbitary pid's session id.
  166  */
  167 struct getsid_args {
  168         pid_t   pid;
  169 };
  170 
  171 int
  172 getsid(p, uap, retval)
  173         struct proc *p;
  174         struct getsid_args *uap;
  175         register_t *retval;
  176 {
  177         struct proc *pt;
  178 
  179         pt = p;
  180         if (uap->pid == 0)
  181                 goto found;
  182 
  183         if ((pt = pfind(uap->pid)) == 0)
  184                 return (ESRCH);
  185 found:
  186         *retval = pt->p_session->s_sid;
  187         return (0);
  188 }
  189 
  190 /* ARGSUSED */
  191 getuid(p, uap, retval)
  192         struct proc *p;
  193         void *uap;
  194         register_t *retval;
  195 {
  196 
  197         *retval = p->p_cred->p_ruid;
  198 #if COMPAT_43
  199         retval[1] = p->p_ucred->cr_uid;
  200 #endif
  201         return (0);
  202 }
  203 
  204 /* ARGSUSED */
  205 geteuid(p, uap, retval)
  206         struct proc *p;
  207         void *uap;
  208         register_t *retval;
  209 {
  210 
  211         *retval = p->p_ucred->cr_uid;
  212         return (0);
  213 }
  214 
  215 /* ARGSUSED */
  216 getgid(p, uap, retval)
  217         struct proc *p;
  218         void *uap;
  219         register_t *retval;
  220 {
  221 
  222         *retval = p->p_cred->p_rgid;
  223 #if COMPAT_43
  224         retval[1] = p->p_ucred->cr_groups[0];
  225 #endif
  226         return (0);
  227 }
  228 
  229 /*
  230  * Get effective group ID.  The "egid" is groups[0], and could be obtained
  231  * via getgroups.  This syscall exists because it is somewhat painful to do
  232  * correctly in a library function.
  233  */
  234 /* ARGSUSED */
  235 getegid(p, uap, retval)
  236         struct proc *p;
  237         void *uap;
  238         register_t *retval;
  239 {
  240 
  241         *retval = p->p_ucred->cr_groups[0];
  242         return (0);
  243 }
  244 
  245 struct  getgroups_args {
  246         u_int   gidsetsize;
  247         gid_t   *gidset;
  248 };
  249 getgroups(p, uap, retval)
  250         struct proc *p;
  251         register struct getgroups_args *uap;
  252         register_t *retval;
  253 {
  254         register struct pcred *pc = p->p_cred;
  255         register u_int ngrp;
  256         int error;
  257 
  258         if ((ngrp = uap->gidsetsize) == 0) {
  259                 *retval = pc->pc_ucred->cr_ngroups;
  260                 return (0);
  261         }
  262         if (ngrp < pc->pc_ucred->cr_ngroups)
  263                 return (EINVAL);
  264         pcred_readlock(p);
  265         ngrp = pc->pc_ucred->cr_ngroups;
  266         if (error = copyout((caddr_t)pc->pc_ucred->cr_groups,
  267             (caddr_t)uap->gidset, ngrp * sizeof(gid_t))) {
  268                 pcred_unlock(p);
  269                 return (error);
  270         }
  271         pcred_unlock(p);
  272         *retval = ngrp;
  273         return (0);
  274 }
  275 
  276 /* ARGSUSED */
  277 setsid(p, uap, retval)
  278         register struct proc *p;
  279         void *uap;
  280         register_t *retval;
  281 {
  282 
  283         if (p->p_pgid == p->p_pid || pgfind(p->p_pid) || p->p_flag & P_INVFORK) {
  284                 return (EPERM);
  285         } else {
  286                 (void)enterpgrp(p, p->p_pid, 1);
  287                 *retval = p->p_pid;
  288                 return (0);
  289         }
  290 }
  291 
  292 /*
  293  * set process group (setpgid/old setpgrp)
  294  *
  295  * caller does setpgid(targpid, targpgid)
  296  *
  297  * pid must be caller or child of caller (ESRCH)
  298  * if a child
  299  *      pid must be in same session (EPERM)
  300  *      pid can't have done an exec (EACCES)
  301  * if pgid != pid
  302  *      there must exist some pid in same session having pgid (EPERM)
  303  * pid must not be session leader (EPERM)
  304  */
  305 struct setpgid_args {
  306         int     pid;
  307         int     pgid;
  308 };
  309 /* ARGSUSED */
  310 setpgid(curp, uap, retval)
  311         struct proc *curp;
  312         register struct setpgid_args *uap;
  313         register_t *retval;
  314 {
  315         register struct proc *targp;            /* target process */
  316         register struct pgrp *pgrp;             /* target pgrp */
  317 
  318         if (uap->pid != 0 && uap->pid != curp->p_pid) {
  319                 if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
  320                         return (ESRCH);
  321                 if (targp->p_session != curp->p_session)
  322                         return (EPERM);
  323                 if (targp->p_flag & P_EXEC)
  324                         return (EACCES);
  325         } else
  326                 targp = curp;
  327         if (SESS_LEADER(targp))
  328                 return (EPERM);
  329         if (uap->pgid == 0)
  330                 uap->pgid = targp->p_pid;
  331         else if (uap->pgid != targp->p_pid)
  332                 if ((pgrp = pgfind(uap->pgid)) == 0 ||
  333                     pgrp->pg_session != curp->p_session)
  334                         return (EPERM);
  335         return (enterpgrp(targp, uap->pgid, 0));
  336 }
  337 
  338 struct issetugid_args {
  339         int dummy;
  340 };
  341 issetugid(p, uap, retval)
  342         struct proc *p;
  343         struct issetugid_args *uap;
  344         register_t *retval;
  345 {
  346         /*
  347          * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
  348          * we use P_SUGID because we consider changing the owners as
  349          * "tainting" as well.
  350          * This is significant for procs that start as root and "become"
  351          * a user without an exec - programs cannot know *everything*
  352          * that libc *might* have put in their data segment.
  353          */
  354 
  355         *retval = (p->p_flag & P_SUGID) ? 1 : 0;
  356         return (0);
  357 }
  358 
  359 struct setuid_args {
  360         uid_t   uid;
  361 };
  362 /* ARGSUSED */
  363 setuid(p, uap, retval)
  364         struct proc *p;
  365         struct setuid_args *uap;
  366         register_t *retval;
  367 {
  368         register struct pcred *pc = p->p_cred;
  369         register uid_t uid;
  370         int error;
  371 
  372         uid = uap->uid;
  373         AUDIT_ARG(uid, uid, 0, 0, 0);
  374         if (uid != pc->p_ruid &&
  375             (error = suser(pc->pc_ucred, &p->p_acflag)))
  376                 return (error);
  377         /*
  378          * Everything's okay, do it.
  379          * Transfer proc count to new user.
  380          * Copy credentials so other references do not see our changes.
  381          */
  382 
  383         /* prepare app access profile files */
  384         prepare_profile_database(uap->uid);
  385         pcred_writelock(p);
  386         (void)chgproccnt(pc->p_ruid, -1);
  387         (void)chgproccnt(uid, 1);
  388         pc->pc_ucred = crcopy(pc->pc_ucred);
  389         pc->pc_ucred->cr_uid = uid;
  390         pc->p_ruid = uid;
  391         pc->p_svuid = uid;
  392         pcred_unlock(p);
  393         set_security_token(p);
  394         p->p_flag |= P_SUGID;
  395         return (0);
  396 }
  397 
  398 struct seteuid_args {
  399         uid_t euid;
  400 };
  401 /* ARGSUSED */
  402 seteuid(p, uap, retval)
  403         struct proc *p;
  404         struct seteuid_args *uap;
  405         register_t *retval;
  406 {
  407         register struct pcred *pc = p->p_cred;
  408         register uid_t euid;
  409         int error;
  410 
  411         euid = uap->euid;
  412         AUDIT_ARG(uid, 0, euid, 0, 0);
  413         if (euid != pc->p_ruid && euid != pc->p_svuid &&
  414             (error = suser(pc->pc_ucred, &p->p_acflag)))
  415                 return (error);
  416         /*
  417          * Everything's okay, do it.  Copy credentials so other references do
  418          * not see our changes.
  419          */
  420         pcred_writelock(p);
  421         pc->pc_ucred = crcopy(pc->pc_ucred);
  422         pc->pc_ucred->cr_uid = euid;
  423         pcred_unlock(p);
  424         set_security_token(p);
  425         p->p_flag |= P_SUGID;
  426         return (0);
  427 }
  428 
  429 struct setgid_args {
  430         gid_t   gid;
  431 };
  432 /* ARGSUSED */
  433 setgid(p, uap, retval)
  434         struct proc *p;
  435         struct setgid_args *uap;
  436         register_t *retval;
  437 {
  438         register struct pcred *pc = p->p_cred;
  439         register gid_t gid;
  440         int error;
  441 
  442         gid = uap->gid;
  443         AUDIT_ARG(gid, gid, 0, 0, 0);
  444         if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
  445                 return (error);
  446         pcred_writelock(p);
  447         pc->pc_ucred = crcopy(pc->pc_ucred);
  448         pc->pc_ucred->cr_groups[0] = gid;
  449         pc->p_rgid = gid;
  450         pc->p_svgid = gid;              /* ??? */
  451         pcred_unlock(p);
  452         set_security_token(p);
  453         p->p_flag |= P_SUGID;
  454         return (0);
  455 }
  456 
  457 struct setegid_args {
  458         gid_t   egid;
  459 };
  460 /* ARGSUSED */
  461 setegid(p, uap, retval)
  462         struct proc *p;
  463         struct setegid_args *uap;
  464         register_t *retval;
  465 {
  466         register struct pcred *pc = p->p_cred;
  467         register gid_t egid;
  468         int error;
  469 
  470         egid = uap->egid;
  471         AUDIT_ARG(gid, 0, egid, 0, 0);
  472         if (egid != pc->p_rgid && egid != pc->p_svgid &&
  473             (error = suser(pc->pc_ucred, &p->p_acflag)))
  474                 return (error);
  475         pcred_writelock(p);
  476         pc->pc_ucred = crcopy(pc->pc_ucred);
  477         pc->pc_ucred->cr_groups[0] = egid;
  478         pcred_unlock(p);
  479         set_security_token(p);
  480         p->p_flag |= P_SUGID;
  481         return (0);
  482 }
  483 
  484 struct setgroups_args{
  485         u_int   gidsetsize;
  486         gid_t   *gidset;
  487 };
  488 
  489 /* ARGSUSED */
  490 setgroups(p, uap, retval)
  491         struct proc *p;
  492         struct setgroups_args *uap;
  493         register_t *retval;
  494 {
  495         register struct pcred *pc = p->p_cred;
  496         struct ucred *new, *old;
  497         register u_int ngrp;
  498         int error;
  499 
  500         if (error = suser(pc->pc_ucred, &p->p_acflag))
  501                 return (error);
  502         ngrp = uap->gidsetsize;
  503         if (ngrp > NGROUPS)
  504                 return (EINVAL);
  505         new = crget();
  506         
  507         if ( ngrp < 1 ) {
  508                 ngrp = 1;
  509         }
  510         else {
  511                 error = copyin((caddr_t)uap->gidset,
  512                         (caddr_t)new->cr_groups, ngrp * sizeof(gid_t));
  513                 if (error) {
  514                         crfree(new);
  515                         return (error);
  516                 }
  517         }
  518         new->cr_ngroups = ngrp;
  519         AUDIT_ARG(groupset, new->cr_groups, ngrp);
  520         pcred_writelock(p);
  521         old = pc->pc_ucred;
  522         new->cr_uid = old->cr_uid;
  523         pc->pc_ucred = new;
  524         pcred_unlock(p);
  525         set_security_token(p);
  526         p->p_flag |= P_SUGID;
  527         if (old != NOCRED)
  528                 crfree(old);
  529         return (0);
  530 }
  531 
  532 #if COMPAT_43
  533 struct osetreuid_args{
  534         int     ruid;
  535         int     euid;
  536 };
  537 /* ARGSUSED */
  538 osetreuid(p, uap, retval)
  539         register struct proc *p;
  540         struct osetreuid_args *uap;
  541         register_t *retval;
  542 {
  543         struct seteuid_args seuidargs;
  544         struct setuid_args suidargs;
  545 
  546         /*
  547          * There are five cases, and we attempt to emulate them in
  548          * the following fashion:
  549          * -1, -1: return 0. This is correct emulation.
  550          * -1,  N: call seteuid(N). This is correct emulation.
  551          *  N, -1: if we called setuid(N), our euid would be changed
  552          *         to N as well. the theory is that we don't want to
  553          *         revoke root access yet, so we call seteuid(N)
  554          *         instead. This is incorrect emulation, but often
  555          *         suffices enough for binary compatibility.
  556          *  N,  N: call setuid(N). This is correct emulation.
  557          *  N,  M: call setuid(N). This is close to correct emulation.
  558          */
  559         if (uap->ruid == (uid_t)-1) {
  560                 if (uap->euid == (uid_t)-1)
  561                         return (0);                             /* -1, -1 */
  562                 seuidargs.euid = uap->euid;     /* -1,  N */
  563                 return (seteuid(p, &seuidargs, retval));
  564         }
  565         if (uap->euid == (uid_t)-1) {
  566                 seuidargs.euid = uap->ruid;     /* N, -1 */
  567                 return (seteuid(p, &seuidargs, retval));
  568         }
  569         suidargs.uid = uap->ruid;       /* N, N and N, M */
  570         return (setuid(p, &suidargs, retval));
  571 }
  572 
  573 struct osetregid_args {
  574         int     rgid;
  575         int egid;
  576 };
  577 /* ARGSUSED */
  578 osetregid(p, uap, retval)
  579         register struct proc *p;
  580         struct osetregid_args *uap;
  581         register_t *retval;
  582 {
  583         struct setegid_args segidargs;
  584         struct setgid_args sgidargs;
  585 
  586         /*
  587          * There are five cases, described above in osetreuid()
  588          */
  589         if (uap->rgid == (gid_t)-1) {
  590                 if (uap->egid == (gid_t)-1)
  591                         return (0);                             /* -1, -1 */
  592                 segidargs.egid = uap->egid;     /* -1,  N */
  593                 return (setegid(p, &segidargs, retval));
  594         }
  595         if (uap->egid == (gid_t)-1) {
  596                 segidargs.egid = uap->rgid;     /* N, -1 */
  597                 return (setegid(p, &segidargs, retval));
  598         }
  599         sgidargs.gid = uap->rgid;       /* N, N and N, M */
  600         return (setgid(p, &sgidargs, retval));
  601 }
  602 #endif /* COMPAT_43 */
  603 
  604 /*
  605  * Check if gid is a member of the group set.
  606  */
  607 groupmember(gid, cred)
  608         gid_t gid;
  609         register struct ucred *cred;
  610 {
  611         register gid_t *gp;
  612         gid_t *egp;
  613 
  614         egp = &(cred->cr_groups[cred->cr_ngroups]);
  615         for (gp = cred->cr_groups; gp < egp; gp++)
  616                 if (*gp == gid)
  617                         return (1);
  618         return (0);
  619 }
  620 
  621 /*
  622  * Test whether the specified credentials imply "super-user"
  623  * privilege; if so, and we have accounting info, set the flag
  624  * indicating use of super-powers.
  625  * Returns 0 or error.
  626  */
  627 suser(cred, acflag)
  628         struct ucred *cred;
  629         u_short *acflag;
  630 {
  631 #if DIAGNOSTIC
  632         if (cred == NOCRED || cred == FSCRED)
  633                 panic("suser");
  634 #endif
  635         if (cred->cr_uid == 0) {
  636                 if (acflag)
  637                         *acflag |= ASU;
  638                 return (0);
  639         }
  640         return (EPERM);
  641 }
  642 
  643 int
  644 is_suser(void)
  645 {
  646         struct proc *p = current_proc();
  647 
  648         if (!p)
  649                 return (0);
  650 
  651         return (suser(p->p_ucred, &p->p_acflag) == 0);
  652 }
  653 
  654 int
  655 is_suser1(void)
  656 {
  657         struct proc *p = current_proc();
  658 
  659         if (!p)
  660                 return (0);
  661 
  662         return (suser(p->p_ucred, &p->p_acflag) == 0 ||
  663                         p->p_cred->p_ruid == 0 || p->p_cred->p_svuid == 0);
  664 }
  665 
  666 /*
  667  * Allocate a zeroed cred structure.
  668  */
  669 struct ucred *
  670 crget()
  671 {
  672         register struct ucred *cr;
  673 
  674         MALLOC_ZONE(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
  675         bzero((caddr_t)cr, sizeof(*cr));
  676         cr->cr_ref = 1;
  677         return (cr);
  678 }
  679 
  680 /*
  681  * Free a cred structure.
  682  * Throws away space when ref count gets to 0.
  683  */
  684 void
  685 crfree(cr)
  686         struct ucred *cr;
  687 {
  688 #if DIAGNOSTIC
  689         if (cr == NOCRED || cr == FSCRED)
  690                 panic("crfree");
  691 #endif
  692         if (--cr->cr_ref == 0)
  693                 FREE_ZONE((caddr_t)cr, sizeof *cr, M_CRED);
  694 }
  695 
  696 /*
  697  * Copy cred structure to a new one and free the old one.
  698  */
  699 struct ucred *
  700 crcopy(cr)
  701         struct ucred *cr;
  702 {
  703         struct ucred *newcr;
  704 
  705 #if DIAGNOSTIC
  706         if (cr == NOCRED || cr == FSCRED)
  707                 panic("crcopy");
  708 #endif
  709         if (cr->cr_ref == 1)
  710                 return (cr);
  711         newcr = crget();
  712         *newcr = *cr;
  713         crfree(cr);
  714         newcr->cr_ref = 1;
  715         return (newcr);
  716 }
  717 
  718 /*
  719  * Dup cred struct to a new held one.
  720  */
  721 struct ucred *
  722 crdup(cr)
  723         struct ucred *cr;
  724 {
  725         struct ucred *newcr;
  726 
  727 #if DIAGNOSTIC
  728         if (cr == NOCRED || cr == FSCRED)
  729                 panic("crdup");
  730 #endif
  731         newcr = crget();
  732         *newcr = *cr;
  733         newcr->cr_ref = 1;
  734         return (newcr);
  735 }
  736 
  737 /*
  738  * compare two cred structs
  739  */
  740 int
  741 crcmp(cr1, cr2)
  742         struct ucred *cr1;
  743         struct ucred *cr2;
  744 {
  745         int i;
  746 
  747         if (cr1 == cr2)
  748                 return 0;
  749         if (cr1 == NOCRED || cr1 == FSCRED ||
  750             cr2 == NOCRED || cr2 == FSCRED)
  751                 return 1;
  752         if (cr1->cr_uid != cr2->cr_uid)
  753                 return 1;
  754         if (cr1->cr_ngroups != cr2->cr_ngroups)
  755                 return 1;
  756         // XXX assumes groups will always be listed in some order
  757         for (i=0; i < cr1->cr_ngroups; i++)
  758                 if (cr1->cr_groups[i] != cr2->cr_groups[i])
  759                         return 1;
  760         return (0);
  761 }
  762 
  763 /*
  764  * Get login name, if available.
  765  */
  766 struct getlogin_args {
  767         char    *namebuf;
  768         u_int   namelen;
  769 };
  770 /* ARGSUSED */
  771 getlogin(p, uap, retval)
  772         struct proc *p;
  773         struct getlogin_args *uap;
  774         register_t *retval;
  775 {
  776 
  777         if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
  778                 uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
  779         return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
  780             (caddr_t)uap->namebuf, uap->namelen));
  781 }
  782 
  783 /*
  784  * Set login name.
  785  */
  786 struct setlogin_args {
  787         char    *namebuf;
  788 };
  789 /* ARGSUSED */
  790 setlogin(p, uap, retval)
  791         struct proc *p;
  792         struct setlogin_args *uap;
  793         register_t *retval;
  794 {
  795         int error;
  796         int dummy=0;
  797 
  798         if (error = suser(p->p_ucred, &p->p_acflag))
  799                 return (error);
  800          
  801         error = copyinstr((caddr_t) uap->namebuf,
  802             (caddr_t) p->p_pgrp->pg_session->s_login,
  803             sizeof (p->p_pgrp->pg_session->s_login) - 1, (size_t *)&dummy);
  804         if (error == ENAMETOOLONG)
  805                 error = EINVAL;
  806         return (error);
  807 }
  808 
  809 
  810 /* Set the secrity token of the task with current euid and eguid */
  811 kern_return_t
  812 set_security_token(struct proc * p)
  813 {
  814         security_token_t sec_token;
  815         audit_token_t    audit_token;
  816 
  817         sec_token.val[0] = p->p_ucred->cr_uid;
  818         sec_token.val[1] = p->p_ucred->cr_gid;
  819         audit_token.val[0] = p->p_au->ai_auid;
  820         audit_token.val[1] = p->p_au->ai_asid;
  821         /* use au_tid for now, until au_tid_addr is put to use */
  822         audit_token.val[2] = p->p_au->ai_termid.port;
  823         audit_token.val[3] = p->p_au->ai_termid.machine;
  824         audit_token.val[4] = 0; 
  825         audit_token.val[5] = 0;
  826         audit_token.val[6] = 0;
  827         audit_token.val[7] = 0;
  828         return host_security_set_task_token(host_security_self(),
  829                                            p->task,
  830                                            sec_token,
  831                                            audit_token,
  832                                            (sec_token.val[0]) ?
  833                                                 HOST_PRIV_NULL :
  834                                                 host_priv_self());
  835 }
  836 
  837 
  838 /*
  839  * Fill in a struct xucred based on a struct ucred.
  840  */
  841 __private_extern__
  842 void
  843 cru2x(struct ucred *cr, struct xucred *xcr)
  844 {
  845 
  846         bzero(xcr, sizeof(*xcr));
  847         xcr->cr_version = XUCRED_VERSION;
  848         xcr->cr_uid = cr->cr_uid;
  849         xcr->cr_ngroups = cr->cr_ngroups;
  850         bcopy(cr->cr_groups, xcr->cr_groups, sizeof(xcr->cr_groups));
  851 }

Cache object: f092a5437a2d2c92f3b23eae09b30909


[ 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.