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