Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
8429d022 MK |
2 | * Copyright (c) 1982, 1986, 1989, 1990, 1991 Regents of the University |
3 | * of California. All rights reserved. | |
da7c5cc6 | 4 | * |
dbf0c423 | 5 | * %sccs.include.redist.c% |
88a39492 | 6 | * |
fe3a8e65 | 7 | * @(#)kern_prot.c 7.30 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
a05af100 BJ |
9 | |
10 | /* | |
4147b3f6 | 11 | * System calls related to processes and protection |
a05af100 BJ |
12 | */ |
13 | ||
a39c04c8 KM |
14 | #include <sys/param.h> |
15 | #include <sys/acct.h> | |
16 | #include <sys/systm.h> | |
17 | #include <sys/ucred.h> | |
18 | #include <sys/proc.h> | |
19 | #include <sys/timeb.h> | |
20 | #include <sys/times.h> | |
21 | #include <sys/malloc.h> | |
a05af100 | 22 | |
9e97623a CT |
23 | struct args { |
24 | int dummy; | |
25 | }; | |
26 | ||
d5dc47bf MK |
27 | /* ARGSUSED */ |
28 | getpid(p, uap, retval) | |
29 | struct proc *p; | |
9e97623a | 30 | struct args *uap; |
d5dc47bf | 31 | int *retval; |
4147b3f6 BJ |
32 | { |
33 | ||
d5dc47bf | 34 | *retval = p->p_pid; |
f9819382 | 35 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) |
8429d022 | 36 | retval[1] = p->p_pptr->p_pid; |
d5dc47bf | 37 | #endif |
d9c2f47f | 38 | return (0); |
4147b3f6 BJ |
39 | } |
40 | ||
d5dc47bf MK |
41 | /* ARGSUSED */ |
42 | getppid(p, uap, retval) | |
43 | struct proc *p; | |
9e97623a | 44 | struct args *uap; |
d5dc47bf | 45 | int *retval; |
4147b3f6 | 46 | { |
d5dc47bf | 47 | |
8429d022 | 48 | *retval = p->p_pptr->p_pid; |
d9c2f47f | 49 | return (0); |
d5dc47bf MK |
50 | } |
51 | ||
8429d022 | 52 | /* Get process group ID; note that POSIX getpgrp takes no parameter */ |
d5dc47bf MK |
53 | getpgrp(p, uap, retval) |
54 | struct proc *p; | |
9e97623a | 55 | struct args *uap; |
d5dc47bf MK |
56 | int *retval; |
57 | { | |
4147b3f6 | 58 | |
d5dc47bf | 59 | *retval = p->p_pgrp->pg_id; |
d9c2f47f | 60 | return (0); |
4147b3f6 BJ |
61 | } |
62 | ||
d5dc47bf MK |
63 | /* ARGSUSED */ |
64 | getuid(p, uap, retval) | |
65 | struct proc *p; | |
9e97623a | 66 | struct args *uap; |
d5dc47bf | 67 | int *retval; |
a05af100 BJ |
68 | { |
69 | ||
8429d022 | 70 | *retval = p->p_cred->p_ruid; |
f9819382 | 71 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) |
8429d022 | 72 | retval[1] = p->p_ucred->cr_uid; |
d5dc47bf | 73 | #endif |
d9c2f47f | 74 | return (0); |
a05af100 BJ |
75 | } |
76 | ||
d5dc47bf MK |
77 | /* ARGSUSED */ |
78 | geteuid(p, uap, retval) | |
79 | struct proc *p; | |
9e97623a | 80 | struct args *uap; |
d5dc47bf | 81 | int *retval; |
4147b3f6 BJ |
82 | { |
83 | ||
8429d022 | 84 | *retval = p->p_ucred->cr_uid; |
d9c2f47f | 85 | return (0); |
4147b3f6 BJ |
86 | } |
87 | ||
d5dc47bf MK |
88 | /* ARGSUSED */ |
89 | getgid(p, uap, retval) | |
90 | struct proc *p; | |
9e97623a | 91 | struct args *uap; |
d5dc47bf MK |
92 | int *retval; |
93 | { | |
94 | ||
8429d022 | 95 | *retval = p->p_cred->p_rgid; |
f9819382 | 96 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) |
8429d022 | 97 | retval[1] = p->p_ucred->cr_groups[0]; |
d5dc47bf | 98 | #endif |
d9c2f47f | 99 | return (0); |
d5dc47bf MK |
100 | } |
101 | ||
102 | /* | |
0712db82 KB |
103 | * Get effective group ID. The "egid" is groups[0], and could be obtained |
104 | * via getgroups. This syscall exists because it is somewhat painful to do | |
105 | * correctly in a library function. | |
d5dc47bf MK |
106 | */ |
107 | /* ARGSUSED */ | |
108 | getegid(p, uap, retval) | |
109 | struct proc *p; | |
9e97623a | 110 | struct args *uap; |
d5dc47bf | 111 | int *retval; |
4147b3f6 | 112 | { |
8429d022 MK |
113 | |
114 | *retval = p->p_ucred->cr_groups[0]; | |
d9c2f47f | 115 | return (0); |
d5dc47bf MK |
116 | } |
117 | ||
9e97623a CT |
118 | struct getgroups_args { |
119 | u_int gidsetsize; | |
5a492ee2 | 120 | gid_t *gidset; |
9e97623a | 121 | }; |
d5dc47bf MK |
122 | getgroups(p, uap, retval) |
123 | struct proc *p; | |
9e97623a | 124 | register struct getgroups_args *uap; |
d5dc47bf MK |
125 | int *retval; |
126 | { | |
8429d022 | 127 | register struct pcred *pc = p->p_cred; |
fca91c15 | 128 | register u_int ngrp; |
d5dc47bf | 129 | int error; |
4147b3f6 | 130 | |
fca91c15 | 131 | if ((ngrp = uap->gidsetsize) == 0) { |
8429d022 | 132 | *retval = pc->pc_ucred->cr_ngroups; |
d9c2f47f | 133 | return (0); |
197da11b | 134 | } |
8429d022 | 135 | if (ngrp < pc->pc_ucred->cr_ngroups) |
d9c2f47f | 136 | return (EINVAL); |
8429d022 | 137 | ngrp = pc->pc_ucred->cr_ngroups; |
5a492ee2 KM |
138 | if (error = copyout((caddr_t)pc->pc_ucred->cr_groups, |
139 | (caddr_t)uap->gidset, ngrp * sizeof(gid_t))) | |
d9c2f47f | 140 | return (error); |
fca91c15 | 141 | *retval = ngrp; |
d9c2f47f | 142 | return (0); |
4147b3f6 BJ |
143 | } |
144 | ||
d5dc47bf MK |
145 | /* ARGSUSED */ |
146 | setsid(p, uap, retval) | |
8429d022 | 147 | register struct proc *p; |
9e97623a | 148 | struct args *uap; |
d5dc47bf | 149 | int *retval; |
8fe87cbb | 150 | { |
8fe87cbb | 151 | |
d5dc47bf | 152 | if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) { |
d9c2f47f | 153 | return (EPERM); |
d5dc47bf | 154 | } else { |
fe3a8e65 | 155 | (void)enterpgrp(p, p->p_pid, 1); |
d5dc47bf | 156 | *retval = p->p_pid; |
d9c2f47f | 157 | return (0); |
8fe87cbb | 158 | } |
8fe87cbb MT |
159 | } |
160 | ||
161 | /* | |
8429d022 | 162 | * set process group (setpgid/old setpgrp) |
8fe87cbb | 163 | * |
049b1521 | 164 | * caller does setpgid(targpid, targpgid) |
164c0f54 MK |
165 | * |
166 | * pid must be caller or child of caller (ESRCH) | |
167 | * if a child | |
168 | * pid must be in same session (EPERM) | |
169 | * pid can't have done an exec (EACCES) | |
170 | * if pgid != pid | |
171 | * there must exist some pid in same session having pgid (EPERM) | |
172 | * pid must not be session leader (EPERM) | |
8fe87cbb | 173 | */ |
9e97623a CT |
174 | struct setpgid_args { |
175 | int pid; /* target process id */ | |
176 | int pgid; /* target pgrp id */ | |
177 | }; | |
d5dc47bf | 178 | /* ARGSUSED */ |
049b1521 MT |
179 | setpgid(curp, uap, retval) |
180 | struct proc *curp; | |
9e97623a | 181 | register struct setpgid_args *uap; |
d5dc47bf MK |
182 | int *retval; |
183 | { | |
049b1521 | 184 | register struct proc *targp; /* target process */ |
ff63251b | 185 | register struct pgrp *pgrp; /* target pgrp */ |
4147b3f6 | 186 | |
ff63251b MK |
187 | if (uap->pid != 0 && uap->pid != curp->p_pid) { |
188 | if ((targp = pfind(uap->pid)) == 0 || !inferior(targp)) | |
d9c2f47f | 189 | return (ESRCH); |
049b1521 | 190 | if (targp->p_session != curp->p_session) |
d9c2f47f | 191 | return (EPERM); |
049b1521 | 192 | if (targp->p_flag&SEXEC) |
d9c2f47f | 193 | return (EACCES); |
d5dc47bf | 194 | } else |
049b1521 MT |
195 | targp = curp; |
196 | if (SESS_LEADER(targp)) | |
d9c2f47f | 197 | return (EPERM); |
ff63251b MK |
198 | if (uap->pgid == 0) |
199 | uap->pgid = targp->p_pid; | |
200 | else if (uap->pgid != targp->p_pid) | |
201 | if ((pgrp = pgfind(uap->pgid)) == 0 || | |
202 | pgrp->pg_session != curp->p_session) | |
0712db82 | 203 | return (EPERM); |
fe3a8e65 | 204 | return (enterpgrp(targp, uap->pgid, 0)); |
4147b3f6 BJ |
205 | } |
206 | ||
9e97623a | 207 | struct setuid_args { |
5a492ee2 | 208 | uid_t uid; |
9e97623a | 209 | }; |
d5dc47bf MK |
210 | /* ARGSUSED */ |
211 | setuid(p, uap, retval) | |
8429d022 | 212 | struct proc *p; |
9e97623a | 213 | struct setuid_args *uap; |
d5dc47bf | 214 | int *retval; |
4f083fd7 | 215 | { |
8429d022 | 216 | register struct pcred *pc = p->p_cred; |
d5dc47bf MK |
217 | register uid_t uid; |
218 | int error; | |
219 | ||
220 | uid = uap->uid; | |
8429d022 MK |
221 | if (uid != pc->p_ruid && |
222 | (error = suser(pc->pc_ucred, &p->p_acflag))) | |
d9c2f47f | 223 | return (error); |
d5dc47bf | 224 | /* |
9025be02 KM |
225 | * Everything's okay, do it. |
226 | * Transfer proc count to new user. | |
227 | * Copy credentials so other references do not see our changes. | |
d5dc47bf | 228 | */ |
9025be02 KM |
229 | (void)chgproccnt(pc->p_ruid, -1); |
230 | (void)chgproccnt(uid, 1); | |
8429d022 MK |
231 | pc->pc_ucred = crcopy(pc->pc_ucred); |
232 | pc->pc_ucred->cr_uid = uid; | |
233 | pc->p_ruid = uid; | |
234 | pc->p_svuid = uid; | |
3c4414e1 | 235 | p->p_flag |= SUGID; |
d9c2f47f | 236 | return (0); |
d5dc47bf MK |
237 | } |
238 | ||
9e97623a | 239 | struct seteuid_args { |
5a492ee2 | 240 | uid_t euid; |
9e97623a | 241 | }; |
d5dc47bf MK |
242 | /* ARGSUSED */ |
243 | seteuid(p, uap, retval) | |
8429d022 | 244 | struct proc *p; |
9e97623a | 245 | struct seteuid_args *uap; |
d5dc47bf MK |
246 | int *retval; |
247 | { | |
8429d022 | 248 | register struct pcred *pc = p->p_cred; |
d5dc47bf MK |
249 | register uid_t euid; |
250 | int error; | |
4f083fd7 | 251 | |
4f083fd7 | 252 | euid = uap->euid; |
8429d022 MK |
253 | if (euid != pc->p_ruid && euid != pc->p_svuid && |
254 | (error = suser(pc->pc_ucred, &p->p_acflag))) | |
d9c2f47f | 255 | return (error); |
4f083fd7 | 256 | /* |
0712db82 KB |
257 | * Everything's okay, do it. Copy credentials so other references do |
258 | * not see our changes. | |
4f083fd7 | 259 | */ |
8429d022 MK |
260 | pc->pc_ucred = crcopy(pc->pc_ucred); |
261 | pc->pc_ucred->cr_uid = euid; | |
3c4414e1 | 262 | p->p_flag |= SUGID; |
d9c2f47f | 263 | return (0); |
4f083fd7 SL |
264 | } |
265 | ||
9e97623a | 266 | struct setgid_args { |
5a492ee2 | 267 | gid_t gid; |
9e97623a | 268 | }; |
d5dc47bf MK |
269 | /* ARGSUSED */ |
270 | setgid(p, uap, retval) | |
271 | struct proc *p; | |
9e97623a | 272 | struct setgid_args *uap; |
d5dc47bf | 273 | int *retval; |
4f083fd7 | 274 | { |
8429d022 | 275 | register struct pcred *pc = p->p_cred; |
d5dc47bf MK |
276 | register gid_t gid; |
277 | int error; | |
278 | ||
279 | gid = uap->gid; | |
8429d022 | 280 | if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag))) |
d9c2f47f | 281 | return (error); |
8429d022 MK |
282 | pc->pc_ucred = crcopy(pc->pc_ucred); |
283 | pc->pc_ucred->cr_groups[0] = gid; | |
284 | pc->p_rgid = gid; | |
285 | pc->p_svgid = gid; /* ??? */ | |
3c4414e1 | 286 | p->p_flag |= SUGID; |
d9c2f47f | 287 | return (0); |
d5dc47bf MK |
288 | } |
289 | ||
9e97623a | 290 | struct setegid_args { |
5a492ee2 | 291 | gid_t egid; |
9e97623a | 292 | }; |
d5dc47bf MK |
293 | /* ARGSUSED */ |
294 | setegid(p, uap, retval) | |
295 | struct proc *p; | |
9e97623a | 296 | struct setegid_args *uap; |
d5dc47bf MK |
297 | int *retval; |
298 | { | |
8429d022 | 299 | register struct pcred *pc = p->p_cred; |
d5dc47bf MK |
300 | register gid_t egid; |
301 | int error; | |
4f083fd7 | 302 | |
4f083fd7 | 303 | egid = uap->egid; |
8429d022 MK |
304 | if (egid != pc->p_rgid && egid != pc->p_svgid && |
305 | (error = suser(pc->pc_ucred, &p->p_acflag))) | |
d9c2f47f | 306 | return (error); |
8429d022 MK |
307 | pc->pc_ucred = crcopy(pc->pc_ucred); |
308 | pc->pc_ucred->cr_groups[0] = egid; | |
3c4414e1 | 309 | p->p_flag |= SUGID; |
d9c2f47f | 310 | return (0); |
d5dc47bf MK |
311 | } |
312 | ||
9e97623a CT |
313 | struct setgroups_args { |
314 | u_int gidsetsize; | |
5a492ee2 | 315 | gid_t *gidset; |
9e97623a | 316 | }; |
d5dc47bf MK |
317 | /* ARGSUSED */ |
318 | setgroups(p, uap, retval) | |
319 | struct proc *p; | |
9e97623a | 320 | struct setgroups_args *uap; |
d5dc47bf MK |
321 | int *retval; |
322 | { | |
8429d022 | 323 | register struct pcred *pc = p->p_cred; |
fca91c15 | 324 | register u_int ngrp; |
5a492ee2 | 325 | int error; |
4147b3f6 | 326 | |
8429d022 | 327 | if (error = suser(pc->pc_ucred, &p->p_acflag)) |
d9c2f47f | 328 | return (error); |
fca91c15 | 329 | if ((ngrp = uap->gidsetsize) > NGROUPS) |
d9c2f47f | 330 | return (EINVAL); |
8429d022 | 331 | pc->pc_ucred = crcopy(pc->pc_ucred); |
5a492ee2 KM |
332 | if (error = copyin((caddr_t)uap->gidset, |
333 | (caddr_t)pc->pc_ucred->cr_groups, ngrp * sizeof(gid_t))) | |
334 | return (error); | |
8429d022 | 335 | pc->pc_ucred->cr_ngroups = ngrp; |
3c4414e1 | 336 | p->p_flag |= SUGID; |
d9c2f47f | 337 | return (0); |
4147b3f6 BJ |
338 | } |
339 | ||
5894ff37 KM |
340 | #if defined(COMPAT_43) || defined(COMPAT_SUNOS) |
341 | struct setreuid_args { | |
342 | int ruid; | |
343 | int euid; | |
344 | }; | |
345 | /* ARGSUSED */ | |
346 | osetreuid(p, uap, retval) | |
347 | register struct proc *p; | |
348 | struct setreuid_args *uap; | |
349 | int *retval; | |
350 | { | |
351 | register struct pcred *pc = p->p_cred; | |
352 | struct seteuid_args args; | |
353 | ||
354 | /* | |
355 | * we assume that the intent of setting ruid is to be able to get | |
356 | * back ruid priviledge. So we make sure that we will be able to | |
357 | * do so, but do not actually set the ruid. | |
358 | */ | |
359 | if (uap->ruid != -1 && uap->ruid != pc->p_ruid && | |
360 | uap->ruid != pc->p_svuid) | |
361 | return (EPERM); | |
362 | if (uap->euid == -1) | |
363 | return (0); | |
364 | args.euid = uap->euid; | |
365 | return (seteuid(p, &args, retval)); | |
366 | } | |
367 | ||
368 | struct setregid_args { | |
369 | int rgid; | |
370 | int egid; | |
371 | }; | |
372 | /* ARGSUSED */ | |
373 | osetregid(p, uap, retval) | |
374 | register struct proc *p; | |
375 | struct setregid_args *uap; | |
376 | int *retval; | |
377 | { | |
378 | register struct pcred *pc = p->p_cred; | |
379 | struct setegid_args args; | |
380 | ||
381 | /* | |
382 | * we assume that the intent of setting rgid is to be able to get | |
383 | * back rgid priviledge. So we make sure that we will be able to | |
384 | * do so, but do not actually set the rgid. | |
385 | */ | |
386 | if (uap->rgid != -1 && uap->rgid != pc->p_rgid && | |
387 | uap->rgid != pc->p_svgid) | |
388 | return (EPERM); | |
389 | if (uap->egid == -1) | |
390 | return (0); | |
391 | args.egid = uap->egid; | |
392 | return (setegid(p, &args, retval)); | |
393 | } | |
394 | #endif /* defined(COMPAT_43) || defined(COMPAT_SUNOS) */ | |
395 | ||
f926daf9 | 396 | /* |
88a39492 | 397 | * Check if gid is a member of the group set. |
f926daf9 | 398 | */ |
88a39492 | 399 | groupmember(gid, cred) |
90731a34 | 400 | gid_t gid; |
88a39492 | 401 | register struct ucred *cred; |
197da11b | 402 | { |
38b6104c | 403 | register gid_t *gp; |
88a39492 | 404 | gid_t *egp; |
197da11b | 405 | |
88a39492 KM |
406 | egp = &(cred->cr_groups[cred->cr_ngroups]); |
407 | for (gp = cred->cr_groups; gp < egp; gp++) | |
197da11b | 408 | if (*gp == gid) |
88a39492 KM |
409 | return (1); |
410 | return (0); | |
197da11b BJ |
411 | } |
412 | ||
f926daf9 | 413 | /* |
f242743a MK |
414 | * Test whether the specified credentials imply "super-user" |
415 | * privilege; if so, and we have accounting info, set the flag | |
416 | * indicating use of super-powers. | |
417 | * Returns 0 or error. | |
f926daf9 | 418 | */ |
88a39492 KM |
419 | suser(cred, acflag) |
420 | struct ucred *cred; | |
421 | short *acflag; | |
197da11b | 422 | { |
88a39492 KM |
423 | if (cred->cr_uid == 0) { |
424 | if (acflag) | |
425 | *acflag |= ASU; | |
426 | return (0); | |
38b6104c | 427 | } |
88a39492 | 428 | return (EPERM); |
197da11b | 429 | } |
f926daf9 SL |
430 | |
431 | /* | |
88a39492 | 432 | * Allocate a zeroed cred structure. |
f926daf9 | 433 | */ |
88a39492 KM |
434 | struct ucred * |
435 | crget() | |
f926daf9 | 436 | { |
88a39492 | 437 | register struct ucred *cr; |
f926daf9 | 438 | |
88a39492 KM |
439 | MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK); |
440 | bzero((caddr_t)cr, sizeof(*cr)); | |
441 | cr->cr_ref = 1; | |
d5dc47bf | 442 | return (cr); |
88a39492 KM |
443 | } |
444 | ||
445 | /* | |
446 | * Free a cred structure. | |
447 | * Throws away space when ref count gets to 0. | |
448 | */ | |
449 | crfree(cr) | |
450 | struct ucred *cr; | |
451 | { | |
8429d022 | 452 | int s = splimp(); /* ??? */ |
88a39492 KM |
453 | |
454 | if (--cr->cr_ref != 0) { | |
455 | (void) splx(s); | |
456 | return; | |
457 | } | |
458 | FREE((caddr_t)cr, M_CRED); | |
459 | (void) splx(s); | |
460 | } | |
461 | ||
462 | /* | |
463 | * Copy cred structure to a new one and free the old one. | |
464 | */ | |
465 | struct ucred * | |
466 | crcopy(cr) | |
467 | struct ucred *cr; | |
468 | { | |
469 | struct ucred *newcr; | |
470 | ||
0712db82 KB |
471 | if (cr->cr_ref == 1) |
472 | return (cr); | |
88a39492 KM |
473 | newcr = crget(); |
474 | *newcr = *cr; | |
475 | crfree(cr); | |
476 | newcr->cr_ref = 1; | |
d5dc47bf | 477 | return (newcr); |
88a39492 KM |
478 | } |
479 | ||
480 | /* | |
481 | * Dup cred struct to a new held one. | |
482 | */ | |
483 | struct ucred * | |
484 | crdup(cr) | |
485 | struct ucred *cr; | |
486 | { | |
487 | struct ucred *newcr; | |
488 | ||
489 | newcr = crget(); | |
490 | *newcr = *cr; | |
491 | newcr->cr_ref = 1; | |
d5dc47bf | 492 | return (newcr); |
f926daf9 | 493 | } |
5b6ee178 KF |
494 | |
495 | /* | |
164c0f54 | 496 | * Get login name, if available. |
5b6ee178 | 497 | */ |
9e97623a CT |
498 | struct getlogin_args { |
499 | char *namebuf; | |
500 | u_int namelen; | |
501 | }; | |
d5dc47bf MK |
502 | /* ARGSUSED */ |
503 | getlogin(p, uap, retval) | |
504 | struct proc *p; | |
9e97623a | 505 | struct getlogin_args *uap; |
d5dc47bf MK |
506 | int *retval; |
507 | { | |
5b6ee178 | 508 | |
8429d022 MK |
509 | if (uap->namelen > sizeof (p->p_pgrp->pg_session->s_login)) |
510 | uap->namelen = sizeof (p->p_pgrp->pg_session->s_login); | |
511 | return (copyout((caddr_t) p->p_pgrp->pg_session->s_login, | |
512 | (caddr_t) uap->namebuf, uap->namelen)); | |
5b6ee178 KF |
513 | } |
514 | ||
515 | /* | |
164c0f54 | 516 | * Set login name. |
5b6ee178 | 517 | */ |
9e97623a CT |
518 | struct setlogin_args { |
519 | char *namebuf; | |
520 | }; | |
d5dc47bf MK |
521 | /* ARGSUSED */ |
522 | setlogin(p, uap, retval) | |
523 | struct proc *p; | |
9e97623a | 524 | struct setlogin_args *uap; |
d5dc47bf MK |
525 | int *retval; |
526 | { | |
164c0f54 | 527 | int error; |
5b6ee178 | 528 | |
8429d022 | 529 | if (error = suser(p->p_ucred, &p->p_acflag)) |
d9c2f47f | 530 | return (error); |
8429d022 MK |
531 | error = copyinstr((caddr_t) uap->namebuf, |
532 | (caddr_t) p->p_pgrp->pg_session->s_login, | |
533 | sizeof (p->p_pgrp->pg_session->s_login) - 1, (u_int *)0); | |
534 | if (error == ENAMETOOLONG) | |
164c0f54 | 535 | error = EINVAL; |
d9c2f47f | 536 | return (error); |
5b6ee178 | 537 | } |