xref: /titanic_50/usr/src/lib/libc/port/gen/klpdlib.c (revision 7257d1b4d25bfac0c802847390e98a464fd787ac)
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 
27ddf7fe95Scasper #pragma ident	"%Z%%M%	%I%	%E% SMI"
28ddf7fe95Scasper 
29*7257d1b4Sraf #include "lint.h"
30ddf7fe95Scasper #include "priv_private.h"
31ddf7fe95Scasper #include "mtlib.h"
32ddf7fe95Scasper #include "libc.h"
33ddf7fe95Scasper #include <door.h>
34ddf7fe95Scasper #include <errno.h>
35ddf7fe95Scasper #include <priv.h>
36ddf7fe95Scasper #include <klpd.h>
37ddf7fe95Scasper #include <stdio.h>
38ddf7fe95Scasper #include <stdlib.h>
39ddf7fe95Scasper #include <string.h>
40ddf7fe95Scasper #include <sys/klpd.h>
41ddf7fe95Scasper #include <sys/param.h>
42ddf7fe95Scasper #include <sys/syscall.h>
43ddf7fe95Scasper #include <unistd.h>
44ddf7fe95Scasper #include <netinet/in.h>
45ddf7fe95Scasper 
46ddf7fe95Scasper typedef struct klpd_data {
47ddf7fe95Scasper 	boolean_t	(*kd_callback)(void *, const priv_set_t *, void *);
48ddf7fe95Scasper 	void		*kd_user_cookie;
49ddf7fe95Scasper 	int		kd_doorfd;
50ddf7fe95Scasper } klpd_data_t;
51ddf7fe95Scasper 
52ddf7fe95Scasper typedef struct klpd_ctxt {
53ddf7fe95Scasper 	klpd_data_t	*kc_data;
54ddf7fe95Scasper 	char		*kc_path;
55ddf7fe95Scasper 	int		kc_int;
56ddf7fe95Scasper 	int		kc_type;
57ddf7fe95Scasper } klpd_ctxt_t;
58ddf7fe95Scasper 
59ddf7fe95Scasper /* ARGSUSED */
60ddf7fe95Scasper static void
klpd_door_callback(void * kd_cookie,char * argp,size_t arg_size,door_desc_t * dp,uint_t ndesc)61ddf7fe95Scasper klpd_door_callback(void *kd_cookie, char *argp, size_t arg_size,
62ddf7fe95Scasper     door_desc_t *dp, uint_t ndesc)
63ddf7fe95Scasper {
64ddf7fe95Scasper 	klpd_data_t *p = kd_cookie;
65ddf7fe95Scasper 	int res;
66ddf7fe95Scasper 	klpd_ctxt_t ctx;
67ddf7fe95Scasper 	klpd_head_t *klh;
68ddf7fe95Scasper 	klpd_arg_t *ka;
69ddf7fe95Scasper 	priv_set_t *pset;
70ddf7fe95Scasper 
71ddf7fe95Scasper 	if (argp == DOOR_UNREF_DATA) {
72ddf7fe95Scasper 		(void) p->kd_callback(p->kd_user_cookie, NULL, NULL);
73ddf7fe95Scasper 		(void) door_return(NULL, 0, NULL, 0);
74ddf7fe95Scasper 	}
75ddf7fe95Scasper 
76ddf7fe95Scasper 	klh = (void *)argp;
77ddf7fe95Scasper 	ka = KLH_ARG(klh);
78ddf7fe95Scasper 	pset = KLH_PRIVSET(klh);
79ddf7fe95Scasper 
80ddf7fe95Scasper 	ctx.kc_type = ka == NULL ? KLPDARG_NONE : ka->kla_type;
81ddf7fe95Scasper 
82ddf7fe95Scasper 	switch (ctx.kc_type) {
83ddf7fe95Scasper 	case KLPDARG_NONE:
84ddf7fe95Scasper 		ctx.kc_path = NULL;
85ddf7fe95Scasper 		ctx.kc_int = -1;
86ddf7fe95Scasper 		break;
87ddf7fe95Scasper 	case KLPDARG_VNODE:
88ddf7fe95Scasper 		ctx.kc_path = ka->kla_str;
89ddf7fe95Scasper 		ctx.kc_int = -1;
90ddf7fe95Scasper 		break;
91ddf7fe95Scasper 	default:
92ddf7fe95Scasper 		ctx.kc_int = ka->kla_int;
93ddf7fe95Scasper 		ctx.kc_path = NULL;
94ddf7fe95Scasper 		break;
95ddf7fe95Scasper 	}
96ddf7fe95Scasper 
97ddf7fe95Scasper 	ctx.kc_data = p;
98ddf7fe95Scasper 
99ddf7fe95Scasper 	if (p->kd_callback(p->kd_user_cookie, pset, &ctx))
100ddf7fe95Scasper 		res = 0;
101ddf7fe95Scasper 	else
102ddf7fe95Scasper 		res = 1;
103ddf7fe95Scasper 
104ddf7fe95Scasper 	(void) door_return((char *)&res, sizeof (res), NULL, 0);
105ddf7fe95Scasper }
106ddf7fe95Scasper 
107ddf7fe95Scasper void *
klpd_create(boolean_t (* callback)(void *,const priv_set_t *,void *),void * cookie)108ddf7fe95Scasper klpd_create(boolean_t (*callback)(void *, const priv_set_t *, void *),
109ddf7fe95Scasper     void *cookie)
110ddf7fe95Scasper {
111ddf7fe95Scasper 	klpd_data_t *p = malloc(sizeof (klpd_data_t));
112ddf7fe95Scasper 
113ddf7fe95Scasper 	if (p == NULL)
114ddf7fe95Scasper 		return (NULL);
115ddf7fe95Scasper 
116ddf7fe95Scasper 	p->kd_doorfd = door_create(klpd_door_callback, p,
117ddf7fe95Scasper 	    DOOR_REFUSE_DESC | DOOR_UNREF);
118ddf7fe95Scasper 	if (p->kd_doorfd == -1)
119ddf7fe95Scasper 		goto out;
120ddf7fe95Scasper 
121ddf7fe95Scasper 	p->kd_user_cookie = cookie;
122ddf7fe95Scasper 	p->kd_callback = callback;
123ddf7fe95Scasper 
124ddf7fe95Scasper 	return (p);
125ddf7fe95Scasper 
126ddf7fe95Scasper out:
127ddf7fe95Scasper 	free(p);
128ddf7fe95Scasper 	return (NULL);
129ddf7fe95Scasper }
130ddf7fe95Scasper 
131ddf7fe95Scasper int
klpd_register_id(const priv_set_t * set,void * handle,idtype_t type,id_t id)132ddf7fe95Scasper klpd_register_id(const priv_set_t *set, void *handle, idtype_t type, id_t id)
133ddf7fe95Scasper {
134ddf7fe95Scasper 	klpd_data_t *p = handle;
135ddf7fe95Scasper 	priv_data_t *d;
136ddf7fe95Scasper 
137ddf7fe95Scasper 	LOADPRIVDATA(d);
138ddf7fe95Scasper 
139ddf7fe95Scasper 	/* We really need to have the privilege set as argument here */
140ddf7fe95Scasper 	if (syscall(SYS_privsys, PRIVSYS_KLPD_REG, p->kd_doorfd, id,
141ddf7fe95Scasper 	    set, d->pd_setsize, type) == -1)
142ddf7fe95Scasper 		return (-1);
143ddf7fe95Scasper 
144ddf7fe95Scasper 	/* Registration for the current process?  Then do the thing. */
145ddf7fe95Scasper 	if (type == P_PID && (id == 0 || (pid_t)id == getpid())) {
146ddf7fe95Scasper 		(void) setppriv(PRIV_OFF, PRIV_INHERITABLE, set);
147ddf7fe95Scasper 		(void) setpflags(PRIV_XPOLICY, 1);
148ddf7fe95Scasper 	}
149ddf7fe95Scasper 	return (0);
150ddf7fe95Scasper }
151ddf7fe95Scasper 
152ddf7fe95Scasper int
klpd_register(const priv_set_t * set,void * handle)153ddf7fe95Scasper klpd_register(const priv_set_t *set, void *handle)
154ddf7fe95Scasper {
155ddf7fe95Scasper 	return (klpd_register_id(set, handle, P_PID, -1));
156ddf7fe95Scasper }
157ddf7fe95Scasper 
158ddf7fe95Scasper int
klpd_unregister_id(void * handle,idtype_t type,id_t id)159ddf7fe95Scasper klpd_unregister_id(void *handle, idtype_t type, id_t id)
160ddf7fe95Scasper {
161ddf7fe95Scasper 	klpd_data_t *p = handle;
162ddf7fe95Scasper 	int err;
163ddf7fe95Scasper 
164ddf7fe95Scasper 	err = syscall(SYS_privsys, PRIVSYS_KLPD_UNREG, p->kd_doorfd, id,
165ddf7fe95Scasper 	    (void *)NULL, 0L, type);
166ddf7fe95Scasper 	if (close(p->kd_doorfd) != 0)
167ddf7fe95Scasper 		err = -1;
168ddf7fe95Scasper 	free(p);
169ddf7fe95Scasper 	return (err);
170ddf7fe95Scasper }
171ddf7fe95Scasper 
172ddf7fe95Scasper int
klpd_unregister(void * handle)173ddf7fe95Scasper klpd_unregister(void *handle)
174ddf7fe95Scasper {
175ddf7fe95Scasper 	return (klpd_unregister_id(handle, P_PID, -1));
176ddf7fe95Scasper }
177ddf7fe95Scasper 
178ddf7fe95Scasper const char *
klpd_getpath(void * context)179ddf7fe95Scasper klpd_getpath(void *context)
180ddf7fe95Scasper {
181ddf7fe95Scasper 	klpd_ctxt_t *p = context;
182ddf7fe95Scasper 
183ddf7fe95Scasper 	if (p->kc_type != KLPDARG_VNODE)
184ddf7fe95Scasper 		errno = EINVAL;
185ddf7fe95Scasper 	return (p->kc_path);
186ddf7fe95Scasper }
187ddf7fe95Scasper 
188ddf7fe95Scasper int
klpd_getport(void * context,int * proto)189ddf7fe95Scasper klpd_getport(void *context, int *proto)
190ddf7fe95Scasper {
191ddf7fe95Scasper 	klpd_ctxt_t *p = context;
192ddf7fe95Scasper 
193ddf7fe95Scasper 	switch (p->kc_type) {
194ddf7fe95Scasper 	case KLPDARG_TCPPORT:
195ddf7fe95Scasper 		*proto = IPPROTO_TCP;
196ddf7fe95Scasper 		break;
197ddf7fe95Scasper 	case KLPDARG_UDPPORT:
198ddf7fe95Scasper 		*proto = IPPROTO_UDP;
199ddf7fe95Scasper 		break;
200ddf7fe95Scasper 	case KLPDARG_SCTPPORT:
201ddf7fe95Scasper 		*proto = IPPROTO_SCTP;
202ddf7fe95Scasper 		break;
203ddf7fe95Scasper 	case KLPDARG_SDPPORT:
204ddf7fe95Scasper 		*proto = PROTO_SDP;
205ddf7fe95Scasper 		break;
206ddf7fe95Scasper 	default:
207ddf7fe95Scasper 		errno = EINVAL;
208ddf7fe95Scasper 		return (-1);
209ddf7fe95Scasper 	}
210ddf7fe95Scasper 	return (p->kc_int);
211ddf7fe95Scasper }
212ddf7fe95Scasper 
213ddf7fe95Scasper /*ARGSUSED*/
214ddf7fe95Scasper int
klpd_getucred(ucred_t ** uc,void * context)215ddf7fe95Scasper klpd_getucred(ucred_t **uc, void *context)
216ddf7fe95Scasper {
217ddf7fe95Scasper 	return (door_ucred(uc));
218ddf7fe95Scasper }
219