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