|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986, 1989, 1990, 1991 Regents of the University
3: * of California. All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
1.1.1.3 ! root 33: * from: @(#)kern_prot.c 7.21 (Berkeley) 5/3/91
! 34: * kern_prot.c,v 1.4 1993/07/13 22:13:23 cgd Exp
1.1 root 35: */
36:
37: /*
38: * System calls related to processes and protection
39: */
40:
41: #include "param.h"
42: #include "acct.h"
43: #include "systm.h"
44: #include "ucred.h"
45: #include "proc.h"
46: #include "timeb.h"
47: #include "times.h"
48: #include "malloc.h"
49:
50: /* ARGSUSED */
1.1.1.3 ! root 51: int
1.1 root 52: getpid(p, uap, retval)
53: struct proc *p;
54: void *uap;
55: int *retval;
56: {
57:
58: *retval = p->p_pid;
59: #ifdef COMPAT_43
60: retval[1] = p->p_pptr->p_pid;
61: #endif
62: return (0);
63: }
64:
65: /* ARGSUSED */
1.1.1.3 ! root 66: int
1.1 root 67: getppid(p, uap, retval)
68: struct proc *p;
69: void *uap;
70: int *retval;
71: {
72:
73: *retval = p->p_pptr->p_pid;
74: return (0);
75: }
76:
77: /* Get process group ID; note that POSIX getpgrp takes no parameter */
1.1.1.3 ! root 78: int
1.1 root 79: getpgrp(p, uap, retval)
80: struct proc *p;
81: void *uap;
82: int *retval;
83: {
84:
85: *retval = p->p_pgrp->pg_id;
86: return (0);
87: }
88:
89: /* ARGSUSED */
1.1.1.3 ! root 90: int
1.1 root 91: getuid(p, uap, retval)
92: struct proc *p;
93: void *uap;
94: int *retval;
95: {
96:
97: *retval = p->p_cred->p_ruid;
98: #ifdef COMPAT_43
99: retval[1] = p->p_ucred->cr_uid;
100: #endif
101: return (0);
102: }
103:
104: /* ARGSUSED */
1.1.1.3 ! root 105: int
1.1 root 106: geteuid(p, uap, retval)
107: struct proc *p;
108: void *uap;
109: int *retval;
110: {
111:
112: *retval = p->p_ucred->cr_uid;
113: return (0);
114: }
115:
116: /* ARGSUSED */
1.1.1.3 ! root 117: int
1.1 root 118: getgid(p, uap, retval)
119: struct proc *p;
120: void *uap;
121: int *retval;
122: {
123:
124: *retval = p->p_cred->p_rgid;
125: #ifdef COMPAT_43
126: retval[1] = p->p_ucred->cr_groups[0];
127: #endif
128: return (0);
129: }
130:
131: /*
132: * Get effective group ID. The "egid" is groups[0], and could be obtained
133: * via getgroups. This syscall exists because it is somewhat painful to do
134: * correctly in a library function.
135: */
136: /* ARGSUSED */
1.1.1.3 ! root 137: int
1.1 root 138: getegid(p, uap, retval)
139: struct proc *p;
140: void *uap;
141: int *retval;
142: {
143:
144: *retval = p->p_ucred->cr_groups[0];
145: return (0);
146: }
147:
1.1.1.3 ! root 148: struct getgroups_args {
! 149: u_int gidsetsize;
! 150: int *gidset; /* XXX not yet POSIX */
! 151: };
! 152:
! 153: int
1.1 root 154: getgroups(p, uap, retval)
155: struct proc *p;
1.1.1.3 ! root 156: register struct getgroups_args *uap;
1.1 root 157: int *retval;
158: {
159: register struct pcred *pc = p->p_cred;
160: register gid_t *gp;
161: register int *lp;
162: register u_int ngrp;
163: int groups[NGROUPS];
164: int error;
165:
166: if ((ngrp = uap->gidsetsize) == 0) {
167: *retval = pc->pc_ucred->cr_ngroups;
168: return (0);
169: }
170: if (ngrp < pc->pc_ucred->cr_ngroups)
171: return (EINVAL);
172: ngrp = pc->pc_ucred->cr_ngroups;
173: for (gp = pc->pc_ucred->cr_groups, lp = groups; lp < &groups[ngrp]; )
174: *lp++ = *gp++;
175: if (error = copyout((caddr_t)groups, (caddr_t)uap->gidset,
176: ngrp * sizeof (groups[0])))
177: return (error);
178: *retval = ngrp;
179: return (0);
180: }
181:
182: /* ARGSUSED */
1.1.1.3 ! root 183: int
1.1 root 184: setsid(p, uap, retval)
185: register struct proc *p;
186: void *uap;
187: int *retval;
188: {
189:
190: if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
191: return (EPERM);
192: } else {
193: enterpgrp(p, p->p_pid, 1);
194: *retval = p->p_pid;
195: return (0);
196: }
197: }
198:
199: /*
200: * set process group (setpgid/old setpgrp)
201: *
202: * caller does setpgid(targpid, targpgid)
203: *
204: * pid must be caller or child of caller (ESRCH)
205: * if a child
206: * pid must be in same session (EPERM)
207: * pid can't have done an exec (EACCES)
208: * if pgid != pid
209: * there must exist some pid in same session having pgid (EPERM)
210: * pid must not be session leader (EPERM)
211: */
1.1.1.3 ! root 212:
! 213: struct setpgid_args {
! 214: int pid; /* target process id */
! 215: int pgid; /* target pgrp id */
! 216: };
! 217:
1.1 root 218: /* ARGSUSED */
1.1.1.3 ! root 219: int
1.1 root 220: setpgid(curp, uap, retval)
221: struct proc *curp;
1.1.1.3 ! root 222: register struct setpgid_args *uap;
1.1 root 223: int *retval;
224: {
225: register struct proc *targp; /* target process */
226: register struct pgrp *pgrp; /* target pgrp */
227:
228: if (uap->pid != 0 && uap->pid != curp->p_pid) {
229: if ((targp = pfind(uap->pid)) == 0 || !inferior(targp))
230: return (ESRCH);
231: if (targp->p_session != curp->p_session)
232: return (EPERM);
233: if (targp->p_flag&SEXEC)
234: return (EACCES);
235: } else
236: targp = curp;
237: if (SESS_LEADER(targp))
238: return (EPERM);
239: if (uap->pgid == 0)
240: uap->pgid = targp->p_pid;
241: else if (uap->pgid != targp->p_pid)
242: if ((pgrp = pgfind(uap->pgid)) == 0 ||
243: pgrp->pg_session != curp->p_session)
244: return (EPERM);
245: enterpgrp(targp, uap->pgid, 0);
246: return (0);
247: }
248:
1.1.1.3 ! root 249: struct setuid_args {
! 250: int uid;
! 251: };
! 252:
1.1 root 253: /* ARGSUSED */
1.1.1.3 ! root 254: int
1.1 root 255: setuid(p, uap, retval)
256: struct proc *p;
1.1.1.3 ! root 257: struct setuid_args *uap;
1.1 root 258: int *retval;
259: {
260: register struct pcred *pc = p->p_cred;
261: register uid_t uid;
262: int error;
263:
264: uid = uap->uid;
265: if (uid != pc->p_ruid &&
266: (error = suser(pc->pc_ucred, &p->p_acflag)))
267: return (error);
268: /*
269: * Everything's okay, do it. Copy credentials so other references do
270: * not see our changes.
271: */
272: pc->pc_ucred = crcopy(pc->pc_ucred);
273: pc->pc_ucred->cr_uid = uid;
274: pc->p_ruid = uid;
275: pc->p_svuid = uid;
276: return (0);
277: }
278:
1.1.1.3 ! root 279: struct seteuid_args {
! 280: int euid;
! 281: };
! 282:
1.1 root 283: /* ARGSUSED */
1.1.1.3 ! root 284: int
1.1 root 285: seteuid(p, uap, retval)
286: struct proc *p;
1.1.1.3 ! root 287: struct seteuid_args *uap;
1.1 root 288: int *retval;
289: {
290: register struct pcred *pc = p->p_cred;
291: register uid_t euid;
292: int error;
293:
294: euid = uap->euid;
295: if (euid != pc->p_ruid && euid != pc->p_svuid &&
296: (error = suser(pc->pc_ucred, &p->p_acflag)))
297: return (error);
298: /*
299: * Everything's okay, do it. Copy credentials so other references do
300: * not see our changes.
301: */
302: pc->pc_ucred = crcopy(pc->pc_ucred);
303: pc->pc_ucred->cr_uid = euid;
304: return (0);
305: }
306:
1.1.1.3 ! root 307: struct setgid_args {
! 308: int gid;
! 309: };
! 310:
1.1 root 311: /* ARGSUSED */
1.1.1.3 ! root 312: int
1.1 root 313: setgid(p, uap, retval)
314: struct proc *p;
1.1.1.3 ! root 315: struct setgid_args *uap;
1.1 root 316: int *retval;
317: {
318: register struct pcred *pc = p->p_cred;
319: register gid_t gid;
320: int error;
321:
322: gid = uap->gid;
323: if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
324: return (error);
325: pc->pc_ucred = crcopy(pc->pc_ucred);
326: pc->pc_ucred->cr_groups[0] = gid;
327: pc->p_rgid = gid;
328: pc->p_svgid = gid; /* ??? */
329: return (0);
330: }
331:
1.1.1.3 ! root 332: struct setegid_args {
! 333: int egid;
! 334: };
! 335:
1.1 root 336: /* ARGSUSED */
1.1.1.3 ! root 337: int
1.1 root 338: setegid(p, uap, retval)
339: struct proc *p;
1.1.1.3 ! root 340: struct setegid_args *uap;
1.1 root 341: int *retval;
342: {
343: register struct pcred *pc = p->p_cred;
344: register gid_t egid;
345: int error;
346:
347: egid = uap->egid;
348: if (egid != pc->p_rgid && egid != pc->p_svgid &&
349: (error = suser(pc->pc_ucred, &p->p_acflag)))
350: return (error);
351: pc->pc_ucred = crcopy(pc->pc_ucred);
352: pc->pc_ucred->cr_groups[0] = egid;
353: return (0);
354: }
355:
356: #ifdef COMPAT_43
1.1.1.3 ! root 357:
! 358: struct osetreuid_args {
! 359: int ruid;
! 360: int euid;
! 361: };
! 362:
1.1 root 363: /* ARGSUSED */
1.1.1.3 ! root 364: int
1.1 root 365: osetreuid(p, uap, retval)
366: register struct proc *p;
1.1.1.3 ! root 367: struct osetreuid_args *uap;
1.1 root 368: int *retval;
369: {
370: register struct pcred *pc = p->p_cred;
371: register uid_t ruid, euid;
372: int error;
373:
374: if (uap->ruid == -1)
375: ruid = pc->p_ruid;
376: else
377: ruid = uap->ruid;
378: /*
379: * Allow setting real uid to previous effective, for swapping real and
380: * effective. This should be:
381: *
382: * if (ruid != pc->p_ruid &&
383: * (error = suser(pc->pc_ucred, &p->p_acflag)))
384: */
385: if (ruid != pc->p_ruid && ruid != pc->pc_ucred->cr_uid /* XXX */ &&
386: (error = suser(pc->pc_ucred, &p->p_acflag)))
387: return (error);
388: if (uap->euid == -1)
389: euid = pc->pc_ucred->cr_uid;
390: else
391: euid = uap->euid;
392: if (euid != pc->pc_ucred->cr_uid && euid != pc->p_ruid &&
393: euid != pc->p_svuid && (error = suser(pc->pc_ucred, &p->p_acflag)))
394: return (error);
395: /*
396: * Everything's okay, do it. Copy credentials so other references do
397: * not see our changes.
398: */
399: pc->pc_ucred = crcopy(pc->pc_ucred);
400: pc->pc_ucred->cr_uid = euid;
401: pc->p_ruid = ruid;
402: return (0);
403: }
404:
1.1.1.3 ! root 405: struct osetregid_args {
! 406: int rgid;
! 407: int egid;
! 408: };
! 409:
1.1 root 410: /* ARGSUSED */
1.1.1.3 ! root 411: int
1.1 root 412: osetregid(p, uap, retval)
413: register struct proc *p;
1.1.1.3 ! root 414: struct osetregid_args *uap;
1.1 root 415: int *retval;
416: {
417: register struct pcred *pc = p->p_cred;
418: register gid_t rgid, egid;
419: int error;
420:
421: if (uap->rgid == -1)
422: rgid = pc->p_rgid;
423: else
424: rgid = uap->rgid;
425: /*
426: * Allow setting real gid to previous effective, for swapping real and
427: * effective. This didn't really work correctly in 4.[23], but is
428: * preserved so old stuff doesn't fail. This should be:
429: *
430: * if (rgid != pc->p_rgid &&
431: * (error = suser(pc->pc_ucred, &p->p_acflag)))
432: */
433: if (rgid != pc->p_rgid && rgid != pc->pc_ucred->cr_groups[0] /* XXX */ &&
434: (error = suser(pc->pc_ucred, &p->p_acflag)))
435: return (error);
436: if (uap->egid == -1)
437: egid = pc->pc_ucred->cr_groups[0];
438: else
439: egid = uap->egid;
440: if (egid != pc->pc_ucred->cr_groups[0] && egid != pc->p_rgid &&
441: egid != pc->p_svgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
442: return (error);
443: pc->pc_ucred = crcopy(pc->pc_ucred);
444: pc->pc_ucred->cr_groups[0] = egid;
445: pc->p_rgid = rgid;
446: return (0);
447: }
448: #endif
449:
1.1.1.3 ! root 450: struct setgroups_args {
! 451: u_int gidsetsize;
! 452: int *gidset;
! 453: };
! 454:
1.1 root 455: /* ARGSUSED */
1.1.1.3 ! root 456: int
1.1 root 457: setgroups(p, uap, retval)
458: struct proc *p;
1.1.1.3 ! root 459: struct setgroups_args *uap;
1.1 root 460: int *retval;
461: {
462: register struct pcred *pc = p->p_cred;
463: register gid_t *gp;
464: register u_int ngrp;
465: register int *lp;
466: int error, groups[NGROUPS];
467:
468: if (error = suser(pc->pc_ucred, &p->p_acflag))
469: return (error);
470: if ((ngrp = uap->gidsetsize) > NGROUPS)
471: return (EINVAL);
472: if (error = copyin((caddr_t)uap->gidset, (caddr_t)groups,
473: ngrp * sizeof (groups[0])))
474: return (error);
475: pc->pc_ucred = crcopy(pc->pc_ucred);
476: pc->pc_ucred->cr_ngroups = ngrp;
477: /* convert from int's to gid_t's */
478: for (gp = pc->pc_ucred->cr_groups, lp = groups; ngrp--; )
479: *gp++ = *lp++;
480: return (0);
481: }
482:
483: /*
484: * Check if gid is a member of the group set.
485: */
1.1.1.3 ! root 486: int
1.1 root 487: groupmember(gid, cred)
488: gid_t gid;
489: register struct ucred *cred;
490: {
491: register gid_t *gp;
492: gid_t *egp;
493:
494: egp = &(cred->cr_groups[cred->cr_ngroups]);
495: for (gp = cred->cr_groups; gp < egp; gp++)
496: if (*gp == gid)
497: return (1);
498: return (0);
499: }
500:
501: /*
502: * Test whether the specified credentials imply "super-user"
503: * privilege; if so, and we have accounting info, set the flag
504: * indicating use of super-powers.
505: * Returns 0 or error.
506: */
1.1.1.3 ! root 507: int
1.1 root 508: suser(cred, acflag)
509: struct ucred *cred;
1.1.1.2 root 510: u_short *acflag;
1.1 root 511: {
512: if (cred->cr_uid == 0) {
513: if (acflag)
514: *acflag |= ASU;
515: return (0);
516: }
517: return (EPERM);
518: }
519:
520: /*
521: * Allocate a zeroed cred structure.
522: */
523: struct ucred *
524: crget()
525: {
526: register struct ucred *cr;
527:
528: MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
529: bzero((caddr_t)cr, sizeof(*cr));
530: cr->cr_ref = 1;
531: return (cr);
532: }
533:
534: /*
535: * Free a cred structure.
536: * Throws away space when ref count gets to 0.
537: */
1.1.1.3 ! root 538: void
1.1 root 539: crfree(cr)
540: struct ucred *cr;
541: {
542: int s = splimp(); /* ??? */
543:
544: if (--cr->cr_ref != 0) {
545: (void) splx(s);
546: return;
547: }
548: FREE((caddr_t)cr, M_CRED);
549: (void) splx(s);
550: }
551:
552: /*
553: * Copy cred structure to a new one and free the old one.
554: */
555: struct ucred *
556: crcopy(cr)
557: struct ucred *cr;
558: {
559: struct ucred *newcr;
560:
561: if (cr->cr_ref == 1)
562: return (cr);
563: newcr = crget();
564: *newcr = *cr;
565: crfree(cr);
566: newcr->cr_ref = 1;
567: return (newcr);
568: }
569:
570: /*
571: * Dup cred struct to a new held one.
572: */
573: struct ucred *
574: crdup(cr)
575: struct ucred *cr;
576: {
577: struct ucred *newcr;
578:
579: newcr = crget();
580: *newcr = *cr;
581: newcr->cr_ref = 1;
582: return (newcr);
583: }
584:
585: /*
586: * Get login name, if available.
587: */
1.1.1.3 ! root 588:
! 589: struct getlogin_args {
! 590: char *namebuf;
! 591: u_int namelen;
! 592: };
! 593:
1.1 root 594: /* ARGSUSED */
1.1.1.3 ! root 595: int
1.1 root 596: getlogin(p, uap, retval)
597: struct proc *p;
1.1.1.3 ! root 598: struct getlogin_args *uap;
1.1 root 599: int *retval;
600: {
601:
602: if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login))
603: uap->namelen = sizeof (p->p_pgrp->pg_session->s_login);
604: return (copyout((caddr_t) p->p_pgrp->pg_session->s_login,
605: (caddr_t) uap->namebuf, uap->namelen));
606: }
607:
608: /*
609: * Set login name.
610: */
1.1.1.3 ! root 611:
! 612: struct setlogin_args {
! 613: char *namebuf;
! 614: };
! 615:
1.1 root 616: /* ARGSUSED */
1.1.1.3 ! root 617: int
1.1 root 618: setlogin(p, uap, retval)
619: struct proc *p;
1.1.1.3 ! root 620: struct setlogin_args *uap;
1.1 root 621: int *retval;
622: {
623: int error;
624:
625: if (error = suser(p->p_ucred, &p->p_acflag))
626: return (error);
627: error = copyinstr((caddr_t) uap->namebuf,
628: (caddr_t) p->p_pgrp->pg_session->s_login,
629: sizeof (p->p_pgrp->pg_session->s_login) - 1, (u_int *)0);
630: if (error == ENAMETOOLONG)
631: error = EINVAL;
632: return (error);
633: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.