Merge commit '4ec4134be29a3b00791f6d70074168a6a3ff4fb3'
[unleashed.git] / kernel / syscall / ucredsys.c
blob215c210019c382e70482eb04a5046d4cddf45599
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>
40 #include <c2/audit.h>
43 * Getpeerucred system call implementation.
45 static int
46 getpeerucred(int fd, void *buf)
48 file_t *fp;
49 struct ucred_s *uc;
50 vnode_t *vp;
51 k_peercred_t kpc;
52 int err;
53 int32_t rval;
55 kpc.pc_cr = NULL;
56 kpc.pc_cpid = -1;
58 if ((fp = getf(fd)) == NULL)
59 return (set_errno(EBADF));
61 vp = fp->f_vnode;
63 switch (vp->v_type) {
64 case VFIFO:
65 case VSOCK:
66 err = fop_ioctl(vp, _I_GETPEERCRED, (intptr_t)&kpc,
67 FKIOCTL, CRED(), &rval, NULL);
68 break;
69 case VCHR: {
70 struct strioctl strioc;
72 if (vp->v_stream == NULL) {
73 err = ENOTSUP;
74 break;
76 strioc.ic_cmd = _I_GETPEERCRED;
77 strioc.ic_timout = INFTIM;
78 strioc.ic_len = (int)sizeof (k_peercred_t);
79 strioc.ic_dp = (char *)&kpc;
81 err = strdoioctl(vp->v_stream, &strioc, FNATIVE|FKIOCTL,
82 STR_NOSIG|K_TO_K, CRED(), &rval);
85 * Map all unexpected error codes to ENOTSUP.
87 switch (err) {
88 case 0:
89 case ENOTSUP:
90 case ENOTCONN:
91 case ENOMEM:
92 break;
93 default:
94 err = ENOTSUP;
95 break;
97 break;
99 default:
100 err = ENOTSUP;
101 break;
103 releasef(fd);
106 * If someone gave us a credential, err will be 0.
108 if (kpc.pc_cr != NULL) {
109 ASSERT(err == 0);
111 uc = cred2ucred(kpc.pc_cr, kpc.pc_cpid, NULL, CRED());
113 crfree(kpc.pc_cr);
115 err = copyout(uc, buf, uc->uc_size);
117 kmem_free(uc, uc->uc_size);
119 if (err != 0)
120 return (set_errno(EFAULT));
122 return (0);
124 return (set_errno(err));
127 static int
128 ucred_get(pid_t pid, void *ubuf)
130 proc_t *p;
131 cred_t *pcr;
132 int err;
133 struct ucred_s *uc;
134 uint32_t auditing = AU_AUDITING();
136 if (pid == P_MYID || pid == curproc->p_pid) {
137 pcr = CRED();
138 crhold(pcr);
139 pid = curproc->p_pid;
140 } else {
141 cred_t *updcred = NULL;
143 if (pid < 0)
144 return (set_errno(EINVAL));
146 if (auditing)
147 updcred = cralloc();
149 mutex_enter(&pidlock);
150 p = prfind(pid);
152 if (p == NULL) {
153 mutex_exit(&pidlock);
154 if (updcred != NULL)
155 crfree(updcred);
156 return (set_errno(ESRCH));
160 * Assure that audit data in cred is up-to-date.
161 * updcred will be used or freed.
163 if (auditing)
164 audit_update_context(p, updcred);
166 err = priv_proc_cred_perm(CRED(), p, &pcr, VREAD);
167 mutex_exit(&pidlock);
169 if (err != 0)
170 return (set_errno(err));
173 uc = cred2ucred(pcr, pid, NULL, CRED());
175 crfree(pcr);
177 err = copyout(uc, ubuf, uc->uc_size);
179 kmem_free(uc, uc->uc_size);
181 if (err)
182 return (set_errno(EFAULT));
184 return (0);
188 ucredsys(int code, int obj, void *buf)
190 switch (code) {
191 case UCREDSYS_UCREDGET:
192 return (ucred_get((pid_t)obj, buf));
193 case UCREDSYS_GETPEERUCRED:
194 return (getpeerucred(obj, buf));
195 default:
196 return (set_errno(EINVAL));
200 #ifdef _SYSCALL32_IMPL
202 ucredsys32(int arg1, int arg2, caddr32_t arg3)
204 return (ucredsys(arg1, arg2, (void *)(uintptr_t)arg3));
206 #endif