Merge illumos-gate
[unleashed.git] / kernel / syscall / ucredsys.c
blobfa7e6c81cdb9cb3aac5595f17992600aeede486e
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <sys/ucred.h>
29 #include <sys/file.h>
30 #include <sys/errno.h>
31 #include <sys/systm.h>
32 #include <sys/stream.h>
33 #include <sys/strsun.h>
34 #include <sys/stropts.h>
35 #include <sys/vfs.h>
36 #include <sys/vnode.h>
37 #include <sys/cmn_err.h>
38 #include <sys/socket.h>
39 #include <sys/strsubr.h>
42 * Getpeerucred system call implementation.
44 static int
45 getpeerucred(int fd, void *buf)
47 file_t *fp;
48 struct ucred_s *uc;
49 vnode_t *vp;
50 k_peercred_t kpc;
51 int err;
52 int32_t rval;
54 kpc.pc_cr = NULL;
55 kpc.pc_cpid = -1;
57 if ((fp = getf(fd)) == NULL)
58 return (set_errno(EBADF));
60 vp = fp->f_vnode;
62 switch (vp->v_type) {
63 case VFIFO:
64 case VSOCK:
65 err = fop_ioctl(vp, _I_GETPEERCRED, (intptr_t)&kpc,
66 FKIOCTL, CRED(), &rval, NULL);
67 break;
68 case VCHR: {
69 struct strioctl strioc;
71 if (vp->v_stream == NULL) {
72 err = ENOTSUP;
73 break;
75 strioc.ic_cmd = _I_GETPEERCRED;
76 strioc.ic_timout = INFTIM;
77 strioc.ic_len = (int)sizeof (k_peercred_t);
78 strioc.ic_dp = (char *)&kpc;
80 err = strdoioctl(vp->v_stream, &strioc, FNATIVE|FKIOCTL,
81 STR_NOSIG|K_TO_K, CRED(), &rval);
84 * Map all unexpected error codes to ENOTSUP.
86 switch (err) {
87 case 0:
88 case ENOTSUP:
89 case ENOTCONN:
90 case ENOMEM:
91 break;
92 default:
93 err = ENOTSUP;
94 break;
96 break;
98 default:
99 err = ENOTSUP;
100 break;
102 releasef(fd);
105 * If someone gave us a credential, err will be 0.
107 if (kpc.pc_cr != NULL) {
108 ASSERT(err == 0);
110 uc = cred2ucred(kpc.pc_cr, kpc.pc_cpid, NULL, CRED());
112 crfree(kpc.pc_cr);
114 err = copyout(uc, buf, uc->uc_size);
116 kmem_free(uc, uc->uc_size);
118 if (err != 0)
119 return (set_errno(EFAULT));
121 return (0);
123 return (set_errno(err));
126 static int
127 ucred_get(pid_t pid, void *ubuf)
129 proc_t *p;
130 cred_t *pcr;
131 int err;
132 struct ucred_s *uc;
134 if (pid == P_MYID || pid == curproc->p_pid) {
135 pcr = CRED();
136 crhold(pcr);
137 pid = curproc->p_pid;
138 } else {
139 cred_t *updcred = NULL;
141 if (pid < 0)
142 return (set_errno(EINVAL));
144 mutex_enter(&pidlock);
145 p = prfind(pid);
147 if (p == NULL) {
148 mutex_exit(&pidlock);
149 if (updcred != NULL)
150 crfree(updcred);
151 return (set_errno(ESRCH));
154 err = priv_proc_cred_perm(CRED(), p, &pcr, VREAD);
155 mutex_exit(&pidlock);
157 if (err != 0)
158 return (set_errno(err));
161 uc = cred2ucred(pcr, pid, NULL, CRED());
163 crfree(pcr);
165 err = copyout(uc, ubuf, uc->uc_size);
167 kmem_free(uc, uc->uc_size);
169 if (err)
170 return (set_errno(EFAULT));
172 return (0);
176 ucredsys(int code, int obj, void *buf)
178 switch (code) {
179 case UCREDSYS_UCREDGET:
180 return (ucred_get((pid_t)obj, buf));
181 case UCREDSYS_GETPEERUCRED:
182 return (getpeerucred(obj, buf));
183 default:
184 return (set_errno(EINVAL));
188 #ifdef _SYSCALL32_IMPL
190 ucredsys32(int arg1, int arg2, caddr32_t arg3)
192 return (ucredsys(arg1, arg2, (void *)(uintptr_t)arg3));
194 #endif