xref: /onnv-gate/usr/src/lib/libc/port/gen/klpdlib.c (revision 6134:27ee74117a16)
1*6134Scasper /*
2*6134Scasper  * CDDL HEADER START
3*6134Scasper  *
4*6134Scasper  * The contents of this file are subject to the terms of the
5*6134Scasper  * Common Development and Distribution License (the "License").
6*6134Scasper  * You may not use this file except in compliance with the License.
7*6134Scasper  *
8*6134Scasper  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*6134Scasper  * or http://www.opensolaris.org/os/licensing.
10*6134Scasper  * See the License for the specific language governing permissions
11*6134Scasper  * and limitations under the License.
12*6134Scasper  *
13*6134Scasper  * When distributing Covered Code, include this CDDL HEADER in each
14*6134Scasper  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*6134Scasper  * If applicable, add the following below this CDDL HEADER, with the
16*6134Scasper  * fields enclosed by brackets "[]" replaced with your own identifying
17*6134Scasper  * information: Portions Copyright [yyyy] [name of copyright owner]
18*6134Scasper  *
19*6134Scasper  * CDDL HEADER END
20*6134Scasper  */
21*6134Scasper 
22*6134Scasper /*
23*6134Scasper  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*6134Scasper  * Use is subject to license terms.
25*6134Scasper  */
26*6134Scasper 
27*6134Scasper #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*6134Scasper 
29*6134Scasper #include "synonyms.h"
30*6134Scasper 
31*6134Scasper #include "priv_private.h"
32*6134Scasper #include "mtlib.h"
33*6134Scasper #include "libc.h"
34*6134Scasper 
35*6134Scasper #include <door.h>
36*6134Scasper #include <errno.h>
37*6134Scasper #include <priv.h>
38*6134Scasper #include <klpd.h>
39*6134Scasper #include <stdio.h>
40*6134Scasper #include <stdlib.h>
41*6134Scasper #include <string.h>
42*6134Scasper #include <sys/klpd.h>
43*6134Scasper #include <sys/param.h>
44*6134Scasper #include <sys/syscall.h>
45*6134Scasper #include <unistd.h>
46*6134Scasper #include <netinet/in.h>
47*6134Scasper 
48*6134Scasper typedef struct klpd_data {
49*6134Scasper 	boolean_t	(*kd_callback)(void *, const priv_set_t *, void *);
50*6134Scasper 	void		*kd_user_cookie;
51*6134Scasper 	int		kd_doorfd;
52*6134Scasper } klpd_data_t;
53*6134Scasper 
54*6134Scasper typedef struct klpd_ctxt {
55*6134Scasper 	klpd_data_t	*kc_data;
56*6134Scasper 	char		*kc_path;
57*6134Scasper 	int		kc_int;
58*6134Scasper 	int		kc_type;
59*6134Scasper } klpd_ctxt_t;
60*6134Scasper 
61*6134Scasper /* ARGSUSED */
62*6134Scasper static void
63*6134Scasper klpd_door_callback(void *kd_cookie, char *argp, size_t arg_size,
64*6134Scasper     door_desc_t *dp, uint_t ndesc)
65*6134Scasper {
66*6134Scasper 	klpd_data_t *p = kd_cookie;
67*6134Scasper 	int res;
68*6134Scasper 	klpd_ctxt_t ctx;
69*6134Scasper 	klpd_head_t *klh;
70*6134Scasper 	klpd_arg_t *ka;
71*6134Scasper 	priv_set_t *pset;
72*6134Scasper 
73*6134Scasper 	if (argp == DOOR_UNREF_DATA) {
74*6134Scasper 		(void) p->kd_callback(p->kd_user_cookie, NULL, NULL);
75*6134Scasper 		(void) door_return(NULL, 0, NULL, 0);
76*6134Scasper 	}
77*6134Scasper 
78*6134Scasper 	klh = (void *)argp;
79*6134Scasper 	ka = KLH_ARG(klh);
80*6134Scasper 	pset = KLH_PRIVSET(klh);
81*6134Scasper 
82*6134Scasper 	ctx.kc_type = ka == NULL ? KLPDARG_NONE : ka->kla_type;
83*6134Scasper 
84*6134Scasper 	switch (ctx.kc_type) {
85*6134Scasper 	case KLPDARG_NONE:
86*6134Scasper 		ctx.kc_path = NULL;
87*6134Scasper 		ctx.kc_int = -1;
88*6134Scasper 		break;
89*6134Scasper 	case KLPDARG_VNODE:
90*6134Scasper 		ctx.kc_path = ka->kla_str;
91*6134Scasper 		ctx.kc_int = -1;
92*6134Scasper 		break;
93*6134Scasper 	default:
94*6134Scasper 		ctx.kc_int = ka->kla_int;
95*6134Scasper 		ctx.kc_path = NULL;
96*6134Scasper 		break;
97*6134Scasper 	}
98*6134Scasper 
99*6134Scasper 	ctx.kc_data = p;
100*6134Scasper 
101*6134Scasper 	if (p->kd_callback(p->kd_user_cookie, pset, &ctx))
102*6134Scasper 		res = 0;
103*6134Scasper 	else
104*6134Scasper 		res = 1;
105*6134Scasper 
106*6134Scasper 	(void) door_return((char *)&res, sizeof (res), NULL, 0);
107*6134Scasper }
108*6134Scasper 
109*6134Scasper void *
110*6134Scasper klpd_create(boolean_t (*callback)(void *, const priv_set_t *, void *),
111*6134Scasper     void *cookie)
112*6134Scasper {
113*6134Scasper 	klpd_data_t *p = malloc(sizeof (klpd_data_t));
114*6134Scasper 
115*6134Scasper 	if (p == NULL)
116*6134Scasper 		return (NULL);
117*6134Scasper 
118*6134Scasper 	p->kd_doorfd = door_create(klpd_door_callback, p,
119*6134Scasper 	    DOOR_REFUSE_DESC | DOOR_UNREF);
120*6134Scasper 	if (p->kd_doorfd == -1)
121*6134Scasper 		goto out;
122*6134Scasper 
123*6134Scasper 	p->kd_user_cookie = cookie;
124*6134Scasper 	p->kd_callback = callback;
125*6134Scasper 
126*6134Scasper 	return (p);
127*6134Scasper 
128*6134Scasper out:
129*6134Scasper 	free(p);
130*6134Scasper 	return (NULL);
131*6134Scasper }
132*6134Scasper 
133*6134Scasper int
134*6134Scasper klpd_register_id(const priv_set_t *set, void *handle, idtype_t type, id_t id)
135*6134Scasper {
136*6134Scasper 	klpd_data_t *p = handle;
137*6134Scasper 	priv_data_t *d;
138*6134Scasper 
139*6134Scasper 	LOADPRIVDATA(d);
140*6134Scasper 
141*6134Scasper 	/* We really need to have the privilege set as argument here */
142*6134Scasper 	if (syscall(SYS_privsys, PRIVSYS_KLPD_REG, p->kd_doorfd, id,
143*6134Scasper 	    set, d->pd_setsize, type) == -1)
144*6134Scasper 		return (-1);
145*6134Scasper 
146*6134Scasper 	/* Registration for the current process?  Then do the thing. */
147*6134Scasper 	if (type == P_PID && (id == 0 || (pid_t)id == getpid())) {
148*6134Scasper 		(void) setppriv(PRIV_OFF, PRIV_INHERITABLE, set);
149*6134Scasper 		(void) setpflags(PRIV_XPOLICY, 1);
150*6134Scasper 	}
151*6134Scasper 	return (0);
152*6134Scasper }
153*6134Scasper 
154*6134Scasper int
155*6134Scasper klpd_register(const priv_set_t *set, void *handle)
156*6134Scasper {
157*6134Scasper 	return (klpd_register_id(set, handle, P_PID, -1));
158*6134Scasper }
159*6134Scasper 
160*6134Scasper int
161*6134Scasper klpd_unregister_id(void *handle, idtype_t type, id_t id)
162*6134Scasper {
163*6134Scasper 	klpd_data_t *p = handle;
164*6134Scasper 	int err;
165*6134Scasper 
166*6134Scasper 	err = syscall(SYS_privsys, PRIVSYS_KLPD_UNREG, p->kd_doorfd, id,
167*6134Scasper 	    (void *)NULL, 0L, type);
168*6134Scasper 	if (close(p->kd_doorfd) != 0)
169*6134Scasper 		err = -1;
170*6134Scasper 	free(p);
171*6134Scasper 	return (err);
172*6134Scasper }
173*6134Scasper 
174*6134Scasper int
175*6134Scasper klpd_unregister(void *handle)
176*6134Scasper {
177*6134Scasper 	return (klpd_unregister_id(handle, P_PID, -1));
178*6134Scasper }
179*6134Scasper 
180*6134Scasper const char *
181*6134Scasper klpd_getpath(void *context)
182*6134Scasper {
183*6134Scasper 	klpd_ctxt_t *p = context;
184*6134Scasper 
185*6134Scasper 	if (p->kc_type != KLPDARG_VNODE)
186*6134Scasper 		errno = EINVAL;
187*6134Scasper 	return (p->kc_path);
188*6134Scasper }
189*6134Scasper 
190*6134Scasper int
191*6134Scasper klpd_getport(void *context, int *proto)
192*6134Scasper {
193*6134Scasper 	klpd_ctxt_t *p = context;
194*6134Scasper 
195*6134Scasper 	switch (p->kc_type) {
196*6134Scasper 	case KLPDARG_TCPPORT:
197*6134Scasper 		*proto = IPPROTO_TCP;
198*6134Scasper 		break;
199*6134Scasper 	case KLPDARG_UDPPORT:
200*6134Scasper 		*proto = IPPROTO_UDP;
201*6134Scasper 		break;
202*6134Scasper 	case KLPDARG_SCTPPORT:
203*6134Scasper 		*proto = IPPROTO_SCTP;
204*6134Scasper 		break;
205*6134Scasper 	case KLPDARG_SDPPORT:
206*6134Scasper 		*proto = PROTO_SDP;
207*6134Scasper 		break;
208*6134Scasper 	default:
209*6134Scasper 		errno = EINVAL;
210*6134Scasper 		return (-1);
211*6134Scasper 	}
212*6134Scasper 	return (p->kc_int);
213*6134Scasper }
214*6134Scasper 
215*6134Scasper /*ARGSUSED*/
216*6134Scasper int
217*6134Scasper klpd_getucred(ucred_t **uc, void *context)
218*6134Scasper {
219*6134Scasper 	return (door_ucred(uc));
220*6134Scasper }
221