|
|
1.1 root 1: /* sys4.c 4.10 81/07/04 */
2:
3: #include "sys/param.h"
4: #include "sys/systm.h"
5: #include "sys/user.h"
6: #include "sys/inode.h"
7: #include "sys/proc.h"
8: #include "sys/clock.h"
9: #include "sys/timeb.h"
10: #include "sys/times.h"
11: #include "sys/file.h"
12:
13: /*
14: * Everything in this file is a routine implementing a system call.
15: */
16:
17: /*
18: * return the current time (old-style entry)
19: */
20: gtime()
21: {
22: u.u_r.r_time = time;
23: clkcheck();
24: }
25:
26: /*
27: * New time entry-- return TOD with milliseconds, timezone,
28: * DST flag
29: */
30: ftime()
31: {
32: register struct a {
33: struct timeb *tp;
34: } *uap;
35: struct timeb t;
36: register unsigned ms;
37: extern int timezone, dstflag;
38:
39: uap = (struct a *)u.u_ap;
40: (void) spl7();
41: t.time = time;
42: ms = lbolt;
43: (void) spl0();
44: if (ms > HZ) {
45: ms -= HZ;
46: t.time++;
47: }
48: t.millitm = (1000*ms)/HZ;
49: t.timezone = timezone;
50: t.dstflag = dstflag;
51: if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t)))
52: u.u_error = EFAULT;
53: clkcheck();
54: }
55:
56: /*
57: * Set the time
58: */
59: stime()
60: {
61: register struct a {
62: time_t time;
63: } *uap;
64: extern time_t bootime;
65:
66: uap = (struct a *)u.u_ap;
67: if(suser()) {
68: bootime += uap->time - time; /* silly */
69: time = uap->time;
70: clkset();
71: }
72: }
73:
74: setuid()
75: {
76: register uid;
77: register struct a {
78: int uid;
79: } *uap;
80:
81: uap = (struct a *)u.u_ap;
82: uid = uap->uid;
83: if(u.u_ruid == uid || u.u_uid == uid || suser()) {
84: u.u_uid = uid;
85: u.u_procp->p_uid = uid;
86: u.u_ruid = uid;
87: }
88: }
89:
90: getuid()
91: {
92:
93: u.u_r.r_val1 = u.u_ruid;
94: u.u_r.r_val2 = u.u_uid;
95: }
96:
97: setruid()
98: {
99: register uid;
100: register struct a {
101: int uid;
102: } *uap;
103:
104: uap = (struct a *)u.u_ap;
105: uid = uap->uid;
106: if(suser())
107: u.u_ruid = uid;
108: }
109:
110: setgid()
111: {
112: register gid;
113: register struct a {
114: int gid;
115: } *uap;
116:
117: uap = (struct a *)u.u_ap;
118: gid = uap->gid;
119: if(u.u_rgid == gid || u.u_gid == gid || suser()) {
120: u.u_gid = gid;
121: u.u_rgid = gid;
122: }
123: }
124:
125: getgid()
126: {
127:
128: u.u_r.r_val1 = u.u_rgid;
129: u.u_r.r_val2 = u.u_gid;
130: }
131:
132: setgroups()
133: {
134: register struct a {
135: u_int gidsetsize;
136: short *gidset;
137: } *uap = (struct a *)u.u_ap;
138: register short *gp;
139:
140: if (!suser())
141: return;
142: if (uap->gidsetsize > sizeof u.u_groups / sizeof u.u_groups[0]) {
143: u.u_error = EINVAL;
144: return;
145: }
146: if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups,
147: uap->gidsetsize * sizeof u.u_groups[0]) < 0) {
148: u.u_error = EFAULT;
149: return;
150: }
151: for (gp = &u.u_groups[uap->gidsetsize] ; gp < &u.u_groups[NGROUPS]; gp++)
152: *gp = NOGROUP;
153: }
154:
155: /*
156: * Check if gid is a member of the group set.
157: */
158: groupmember(gid)
159: short gid;
160: {
161: register short *gp;
162:
163: if (u.u_gid == gid)
164: return (1);
165: for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
166: if (*gp == gid)
167: return (1);
168: return (0);
169: }
170:
171: getgroups()
172: {
173: register struct a {
174: u_int gidsetsize;
175: short *gidset;
176: } *uap = (struct a *)u.u_ap;
177: register short *gp;
178:
179: for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--)
180: if (gp[-1] != NOGROUP)
181: break;
182: if (uap->gidsetsize < gp - u.u_groups) {
183: u.u_error = EINVAL;
184: return;
185: }
186: uap->gidsetsize = gp - u.u_groups;
187: if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset,
188: uap->gidsetsize * sizeof u.u_groups[0]) < 0) {
189: u.u_error = EFAULT;
190: return;
191: }
192: u.u_r.r_val1 = uap->gidsetsize;
193: }
194:
195: getpid()
196: {
197: u.u_r.r_val1 = u.u_procp->p_pid;
198: u.u_r.r_val2 = u.u_procp->p_ppid;
199: }
200:
201: sync()
202: {
203:
204: update();
205: }
206:
207: nice()
208: {
209: register n;
210: register struct a {
211: int niceness;
212: } *uap;
213:
214: uap = (struct a *)u.u_ap;
215: n = uap->niceness + u.u_procp->p_nice;
216: if(n >= 2*NZERO)
217: n = 2*NZERO -1;
218: if(n < 0)
219: n = 0;
220: if (n < u.u_procp->p_nice && !suser())
221: return;
222: u.u_procp->p_nice = n;
223: }
224:
225: /*
226: * Unlink system call.
227: * Hard to avoid races here, especially
228: * in unlinking directories.
229: */
230: unlink()
231: {
232: struct a {
233: char *fname;
234: };
235: struct argnamei nmarg;
236:
237: nmarg = nilargnamei;
238: nmarg.flag = NI_DEL;
239: (void) namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nmarg, 0);
240: }
241: chdir()
242: {
243: chdirec(&u.u_cdir);
244: }
245:
246: chroot()
247: {
248: if (suser())
249: chdirec(&u.u_rdir);
250: }
251:
252: chdirec(ipp)
253: register struct inode **ipp;
254: {
255: register struct inode *ip;
256: struct a {
257: char *fname;
258: };
259:
260: ip = namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nilargnamei, 1);
261: if(ip == NULL)
262: return;
263: if((ip->i_mode&IFMT) != IFDIR) {
264: u.u_error = ENOTDIR;
265: goto bad;
266: }
267: if(access(ip, IEXEC))
268: goto bad;
269: prele(ip);
270: if (*ipp) {
271: plock(*ipp);
272: iput(*ipp);
273: }
274: *ipp = ip;
275: return;
276:
277: bad:
278: iput(ip);
279: }
280:
281: fchmod()
282: { register struct file *fp;
283: register struct a {
284: int fd;
285: int fmode;
286: } *uap;
287:
288: uap = (struct a *)u.u_ap;
289: if((fp = getf(uap->fd)) == NULL) {
290: u.u_error = EBADF;
291: return;
292: }
293: chmod1(fp->f_inode, uap->fmode);
294: }
295:
296: chmod()
297: {
298: register struct inode *ip;
299: register struct a {
300: char *fname;
301: int fmode;
302: } *uap;
303:
304: uap = (struct a *)u.u_ap;
305: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL)
306: return;
307: chmod1(ip, uap->fmode);
308: iput(ip);
309: }
310:
311: chmod1(ip, mode)
312: register struct inode *ip;
313: {
314:
315: if (accowner(ip) == 0)
316: return;
317: ip->i_mode &= ~07777;
318: if (!(mode&ICONC) && u.u_uid!=0 && !groupmember(ip->i_gid))
319: mode &= ~ISGID;
320: ip->i_mode |= mode&07777;
321: ip->i_flag |= ICHG;
322: iupdat(ip, &time, &time, 0);
323: }
324:
325: /* chown with file descriptor*/
326: fchown()
327: { register struct file *fp;
328: register struct a {
329: int fd;
330: int uid;
331: int gid;
332: } *uap;
333:
334: uap = (struct a *)u.u_ap;
335: if((fp = getf(uap->fd)) == NULL) {
336: u.u_error = EBADF;
337: return;
338: }
339: chown1(fp->f_inode, uap->uid, uap->gid);
340: }
341:
342: chown()
343: {
344: register struct inode *ip;
345: register struct a {
346: char *fname;
347: int uid;
348: int gid;
349: } *uap;
350:
351: uap = (struct a *)u.u_ap;
352: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL)
353: return;
354: chown1(ip, uap->uid, uap->gid);
355: iput(ip);
356: }
357:
358: chown1(ip, uid, gid)
359: register struct inode *ip;
360: {
361:
362: if (accowner(ip) == 0)
363: return;
364: if(u.u_uid){
365: if((ip->i_uid != uid) || !groupmember(gid)){
366: u.u_error = EPERM;
367: return;
368: }
369: if((ip->i_mode&ICONC)==0 && gid != ip->i_gid)
370: ip->i_mode &=~ ISGID;
371: }
372: ip->i_uid = uid;
373: ip->i_gid = gid;
374: ip->i_flag |= ICHG;
375: iupdat(ip, &time, &time, 0);
376: }
377:
378: ssig()
379: {
380: register int (*f)();
381: struct a {
382: int signo;
383: int (*fun)();
384: } *uap;
385: register struct proc *p = u.u_procp;
386: register a;
387: register long sigmask;
388:
389: uap = (struct a *)u.u_ap;
390: a = uap->signo & SIGNUMMASK;
391: f = uap->fun;
392: if(a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP) {
393: u.u_error = EINVAL;
394: return;
395: }
396: u.u_r.r_val1 = (int)u.u_signal[a];
397: sigmask = SIGMASK(a);
398: (void) spl6();
399: if (u.u_signal[a] == SIG_IGN)
400: p->p_sig &= ~sigmask; /* never to be seen again */
401: u.u_signal[a] = f;
402: if (f == SIG_DFL)
403: P_SETDFL(p, sigmask);
404: else if (f == SIG_IGN)
405: P_SETIGN(p, sigmask);
406: else if (f == SIG_HOLD)
407: P_SETHOLD(p, sigmask);
408: else
409: P_SETCATCH(p, sigmask);
410: (void) spl0();
411: if (uap->signo & SIGDOPAUSE)
412: pause();
413: }
414:
415: kill()
416: {
417: register struct a {
418: int pid;
419: int signo;
420: } *uap;
421:
422: u.u_error = ESRCH; /* default error */
423: uap = (struct a *)u.u_ap;
424: if (uap->signo > NSIG || uap->signo < 0) {
425: u.u_error = EINVAL;
426: return;
427: }
428: if (uap->pid == -1)
429: killall(uap->signo);
430: else if(uap->pid > 0)
431: killproc(uap->pid, uap->signo);
432: else if (uap->pid < 0)
433: killpgrp(-uap->pid, uap->signo);
434: else
435: killpgrp(u.u_procp->p_pgrp, uap->signo);
436: }
437:
438: /*
439: * kill a single process
440: */
441: killproc(pid, sig)
442: register int pid, sig;
443: {
444: register struct proc *p;
445:
446: for (p = proc; p < procNPROC; p++)
447: if (p->p_stat && p->p_pid == pid)
448: break;
449: if (p == procNPROC)
450: return;
451: if (u.u_uid && u.u_uid != p->p_uid) { /* no permission */
452: u.u_error = EPERM;
453: return;
454: }
455: if (sig != 0) /* real signal? */
456: psignal(p, sig); /* yes, send it */
457: u.u_error = 0;
458: }
459:
460: /*
461: * Kill all processes within a process group but not system processes.
462: * SIGCONT may be sent to any descendants (can you say hack?).
463: */
464: killpgrp(pgrp, sig)
465: register int pgrp, sig;
466: {
467: register struct proc *p;
468:
469: for(p = proc; p < procNPROC; p++) {
470: if(p->p_stat == 0)
471: continue; /* non-existent */
472: if (p->p_pgrp!=pgrp || p->p_flag&SSYS)
473: continue;
474: if(u.u_uid != 0 && u.u_uid != p->p_uid &&
475: (sig != SIGCONT || !inferior(p)))
476: continue;
477: u.u_error = 0;
478: if (sig != 0) /* real signal? */
479: psignal(p, sig); /* yes, send it */
480: }
481: }
482:
483: /*
484: * Kill all processes except the system processes and the current process
485: */
486: killall(sig)
487: register int sig;
488: {
489: register struct proc *p;
490:
491: if (!suser())
492: return;
493: for(p = proc; p < procNPROC; p++) {
494: if(p->p_stat == 0)
495: continue;
496: if (p->p_flag&SSYS || p==u.u_procp)
497: continue;
498: u.u_error = 0;
499: psignal(p, sig);
500: }
501: }
502:
503: times()
504: {
505: register struct a {
506: time_t (*times)[4];
507: } *uap;
508: struct tms tms;
509:
510: tms.tms_utime = u.u_vm.vm_utime;
511: tms.tms_stime = u.u_vm.vm_stime;
512: tms.tms_cutime = u.u_cvm.vm_utime;
513: tms.tms_cstime = u.u_cvm.vm_stime;
514: uap = (struct a *)u.u_ap;
515: if (copyout((caddr_t)&tms, (caddr_t)uap->times, sizeof(struct tms)) < 0)
516: u.u_error = EFAULT;
517: }
518:
519: profil()
520: {
521: register struct a {
522: short *bufbase;
523: unsigned bufsize;
524: unsigned pcoffset;
525: unsigned pcscale;
526: } *uap;
527:
528: uap = (struct a *)u.u_ap;
529: u.u_prof.pr_base = uap->bufbase;
530: u.u_prof.pr_size = uap->bufsize;
531: u.u_prof.pr_off = uap->pcoffset;
532: u.u_prof.pr_scale = uap->pcscale;
533: }
534:
535: /*
536: * alarm clock signal
537: */
538: alarm()
539: {
540: register struct proc *p;
541: register c;
542: register struct a {
543: int deltat;
544: } *uap;
545:
546: uap = (struct a *)u.u_ap;
547: p = u.u_procp;
548: c = p->p_clktim;
549: if (uap->deltat > 65535L)
550: uap->deltat = 65535;
551: p->p_clktim = uap->deltat;
552: u.u_r.r_val1 = c;
553: }
554:
555: /*
556: * indefinite wait.
557: * no one should wakeup(&u)
558: */
559: pause()
560: {
561:
562: for(;;)
563: sleep((caddr_t)&u, PSLEP);
564: }
565:
566: /*
567: * mode mask for creation of files
568: */
569: umask()
570: {
571: register struct a {
572: int mask;
573: } *uap;
574: register t;
575:
576: uap = (struct a *)u.u_ap;
577: t = u.u_cmask;
578: u.u_cmask = uap->mask & 0777;
579: u.u_r.r_val1 = t;
580: }
581:
582: /*
583: * Set IUPD and IACC times on file.
584: * Can't set ICHG.
585: */
586: utime()
587: {
588: register struct a {
589: char *fname;
590: time_t *tptr;
591: } *uap;
592: register struct inode *ip;
593: time_t tv[2];
594:
595: uap = (struct a *)u.u_ap;
596: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL)
597: return;
598: if (accowner(ip) == 0) {
599: iput(ip);
600: return;
601: }
602: if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) {
603: u.u_error = EFAULT;
604: } else {
605: ip->i_flag |= IACC|IUPD|ICHG;
606: iupdat(ip, &tv[0], &tv[1], 0);
607: }
608: iput(ip);
609: }
610:
611: /*
612: * Setpgrp on specified process and its descendants.
613: * Pid of zero implies current process.
614: * Pgrp -1 is getpgrp system call returning
615: * current process group.
616: */
617: setpgrp()
618: {
619: register struct proc *top;
620: register struct a {
621: int pid;
622: int pgrp;
623: } *uap;
624:
625: uap = (struct a *)u.u_ap;
626: uap->pid = (short)uap->pid; /* else 0x10000 would make pgrp 0 */
627: uap->pgrp = (short)uap->pgrp;
628: if (uap->pid == 0)
629: top = u.u_procp;
630: else {
631: top = pfind(uap->pid);
632: if (top == 0) {
633: u.u_error = ESRCH;
634: return;
635: }
636: }
637: if (uap->pgrp == 0 && !suser())
638: return;
639:
640: if (uap->pgrp < 0) {
641: u.u_r.r_val1 = top->p_pgrp;
642: return;
643: }
644: if (top->p_uid != u.u_uid && u.u_uid && !inferior(top))
645: u.u_error = EPERM;
646: else
647: top->p_pgrp = uap->pgrp;
648: }
649:
650: spgrp(top, npgrp)
651: register struct proc *top;
652: {
653: register struct proc *pp, *p;
654: int f = 0;
655:
656: for (p = top; npgrp == -1 || u.u_uid == p->p_uid ||
657: !u.u_uid || inferior(p); p = pp) {
658: if (npgrp == -1) {
659: #define bit(a) (1<<(a-1))
660: p->p_sig &= ~(bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU));
661: } else
662: p->p_pgrp = npgrp;
663: f++;
664: /*
665: * Search for children.
666: */
667: for (pp = proc; pp < procNPROC; pp++)
668: if (pp->p_stat != 0 && pp->p_pptr == p)
669: goto cont;
670: /*
671: * Search for siblings.
672: */
673: for (; p != top; p = p->p_pptr)
674: for (pp = p + 1; pp < procNPROC; pp++)
675: if (pp->p_stat != 0 && pp->p_pptr == p->p_pptr)
676: goto cont;
677: break;
678: cont:
679: ;
680: }
681: return (f);
682: }
683:
684: /*
685: * Is p an inferior of the current process?
686: */
687: inferior(p)
688: register struct proc *p;
689: {
690:
691: for (; p != u.u_procp; p = p->p_pptr)
692: if (p < &proc[SYSPIDS])
693: return (0);
694: return (1);
695: }
696:
697: sysboot()
698: {
699: register struct a {
700: int opt;
701: };
702:
703: if (suser())
704: boot(((struct a *)u.u_ap)->opt);
705: }
706:
707: /*
708: * lock user into core as much
709: * as possible. swapping may still
710: * occur if core grows.
711: */
712: syslock()
713: {
714: register struct proc *p;
715: register struct a {
716: int flag;
717: } *uap;
718:
719: uap = (struct a *)u.u_ap;
720: if(suser()) {
721: p = u.u_procp;
722: p->p_flag &= ~SULOCK;
723: if(uap->flag)
724: p->p_flag |= SULOCK;
725: }
726: }
727:
728: /*
729: * nap for n clock ticks
730: */
731: #define MAXNAP 120
732: nap()
733: {
734: register struct a {
735: int nticks;
736: } *uap;
737: register int n;
738:
739: uap = (struct a *)u.u_ap;
740: n = uap->nticks;
741: if (n < 0)
742: n = 0;
743: if (n > MAXNAP)
744: n = MAXNAP;
745: delay (n);
746: }
747:
748: /*
749: * get/set user's login name
750: */
751:
752: getlogname()
753: {
754: register struct a {
755: char *name;
756: int flag;
757: } *uap;
758:
759: uap = (struct a *)u.u_ap;
760: if (uap->flag == 0) {
761: if (copyout((caddr_t)u.u_logname, (caddr_t)uap->name, sizeof(u.u_logname)) < 0)
762: u.u_error = EFAULT;
763: return;
764: }
765: if (suser() == 0)
766: return;
767: if (copyin((caddr_t)uap->name, (caddr_t)u.u_logname, sizeof(u.u_logname)))
768: u.u_error = EFAULT;
769: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.