xref: /onnv-gate/usr/src/lib/libc/port/gen/klpdlib.c (revision 6812:febeba71273d)
16134Scasper /*
26134Scasper  * CDDL HEADER START
36134Scasper  *
46134Scasper  * The contents of this file are subject to the terms of the
56134Scasper  * Common Development and Distribution License (the "License").
66134Scasper  * You may not use this file except in compliance with the License.
76134Scasper  *
86134Scasper  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96134Scasper  * or http://www.opensolaris.org/os/licensing.
106134Scasper  * See the License for the specific language governing permissions
116134Scasper  * and limitations under the License.
126134Scasper  *
136134Scasper  * When distributing Covered Code, include this CDDL HEADER in each
146134Scasper  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156134Scasper  * If applicable, add the following below this CDDL HEADER, with the
166134Scasper  * fields enclosed by brackets "[]" replaced with your own identifying
176134Scasper  * information: Portions Copyright [yyyy] [name of copyright owner]
186134Scasper  *
196134Scasper  * CDDL HEADER END
206134Scasper  */
216134Scasper 
226134Scasper /*
236134Scasper  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
246134Scasper  * Use is subject to license terms.
256134Scasper  */
266134Scasper 
276134Scasper #pragma ident	"%Z%%M%	%I%	%E% SMI"
286134Scasper 
29*6812Sraf #include "lint.h"
306134Scasper #include "priv_private.h"
316134Scasper #include "mtlib.h"
326134Scasper #include "libc.h"
336134Scasper #include <door.h>
346134Scasper #include <errno.h>
356134Scasper #include <priv.h>
366134Scasper #include <klpd.h>
376134Scasper #include <stdio.h>
386134Scasper #include <stdlib.h>
396134Scasper #include <string.h>
406134Scasper #include <sys/klpd.h>
416134Scasper #include <sys/param.h>
426134Scasper #include <sys/syscall.h>
436134Scasper #include <unistd.h>
446134Scasper #include <netinet/in.h>
456134Scasper 
466134Scasper typedef struct klpd_data {
476134Scasper 	boolean_t	(*kd_callback)(void *, const priv_set_t *, void *);
486134Scasper 	void		*kd_user_cookie;
496134Scasper 	int		kd_doorfd;
506134Scasper } klpd_data_t;
516134Scasper 
526134Scasper typedef struct klpd_ctxt {
536134Scasper 	klpd_data_t	*kc_data;
546134Scasper 	char		*kc_path;
556134Scasper 	int		kc_int;
566134Scasper 	int		kc_type;
576134Scasper } klpd_ctxt_t;
586134Scasper 
596134Scasper /* ARGSUSED */
606134Scasper static void
klpd_door_callback(void * kd_cookie,char * argp,size_t arg_size,door_desc_t * dp,uint_t ndesc)616134Scasper klpd_door_callback(void *kd_cookie, char *argp, size_t arg_size,
626134Scasper     door_desc_t *dp, uint_t ndesc)
636134Scasper {
646134Scasper 	klpd_data_t *p = kd_cookie;
656134Scasper 	int res;
666134Scasper 	klpd_ctxt_t ctx;
676134Scasper 	klpd_head_t *klh;
686134Scasper 	klpd_arg_t *ka;
696134Scasper 	priv_set_t *pset;
706134Scasper 
716134Scasper 	if (argp == DOOR_UNREF_DATA) {
726134Scasper 		(void) p->kd_callback(p->kd_user_cookie, NULL, NULL);
736134Scasper 		(void) door_return(NULL, 0, NULL, 0);
746134Scasper 	}
756134Scasper 
766134Scasper 	klh = (void *)argp;
776134Scasper 	ka = KLH_ARG(klh);
786134Scasper 	pset = KLH_PRIVSET(klh);
796134Scasper 
806134Scasper 	ctx.kc_type = ka == NULL ? KLPDARG_NONE : ka->kla_type;
816134Scasper 
826134Scasper 	switch (ctx.kc_type) {
836134Scasper 	case KLPDARG_NONE:
846134Scasper 		ctx.kc_path = NULL;
856134Scasper 		ctx.kc_int = -1;
866134Scasper 		break;
876134Scasper 	case KLPDARG_VNODE:
886134Scasper 		ctx.kc_path = ka->kla_str;
896134Scasper 		ctx.kc_int = -1;
906134Scasper 		break;
916134Scasper 	default:
926134Scasper 		ctx.kc_int = ka->kla_int;
936134Scasper 		ctx.kc_path = NULL;
946134Scasper 		break;
956134Scasper 	}
966134Scasper 
976134Scasper 	ctx.kc_data = p;
986134Scasper 
996134Scasper 	if (p->kd_callback(p->kd_user_cookie, pset, &ctx))
1006134Scasper 		res = 0;
1016134Scasper 	else
1026134Scasper 		res = 1;
1036134Scasper 
1046134Scasper 	(void) door_return((char *)&res, sizeof (res), NULL, 0);
1056134Scasper }
1066134Scasper 
1076134Scasper void *
klpd_create(boolean_t (* callback)(void *,const priv_set_t *,void *),void * cookie)1086134Scasper klpd_create(boolean_t (*callback)(void *, const priv_set_t *, void *),
1096134Scasper     void *cookie)
1106134Scasper {
1116134Scasper 	klpd_data_t *p = malloc(sizeof (klpd_data_t));
1126134Scasper 
1136134Scasper 	if (p == NULL)
1146134Scasper 		return (NULL);
1156134Scasper 
1166134Scasper 	p->kd_doorfd = door_create(klpd_door_callback, p,
1176134Scasper 	    DOOR_REFUSE_DESC | DOOR_UNREF);
1186134Scasper 	if (p->kd_doorfd == -1)
1196134Scasper 		goto out;
1206134Scasper 
1216134Scasper 	p->kd_user_cookie = cookie;
1226134Scasper 	p->kd_callback = callback;
1236134Scasper 
1246134Scasper 	return (p);
1256134Scasper 
1266134Scasper out:
1276134Scasper 	free(p);
1286134Scasper 	return (NULL);
1296134Scasper }
1306134Scasper 
1316134Scasper int
klpd_register_id(const priv_set_t * set,void * handle,idtype_t type,id_t id)1326134Scasper klpd_register_id(const priv_set_t *set, void *handle, idtype_t type, id_t id)
1336134Scasper {
1346134Scasper 	klpd_data_t *p = handle;
1356134Scasper 	priv_data_t *d;
1366134Scasper 
1376134Scasper 	LOADPRIVDATA(d);
1386134Scasper 
1396134Scasper 	/* We really need to have the privilege set as argument here */
1406134Scasper 	if (syscall(SYS_privsys, PRIVSYS_KLPD_REG, p->kd_doorfd, id,
1416134Scasper 	    set, d->pd_setsize, type) == -1)
1426134Scasper 		return (-1);
1436134Scasper 
1446134Scasper 	/* Registration for the current process?  Then do the thing. */
1456134Scasper 	if (type == P_PID && (id == 0 || (pid_t)id == getpid())) {
1466134Scasper 		(void) setppriv(PRIV_OFF, PRIV_INHERITABLE, set);
1476134Scasper 		(void) setpflags(PRIV_XPOLICY, 1);
1486134Scasper 	}
1496134Scasper 	return (0);
1506134Scasper }
1516134Scasper 
1526134Scasper int
klpd_register(const priv_set_t * set,void * handle)1536134Scasper klpd_register(const priv_set_t *set, void *handle)
1546134Scasper {
1556134Scasper 	return (klpd_register_id(set, handle, P_PID, -1));
1566134Scasper }
1576134Scasper 
1586134Scasper int
klpd_unregister_id(void * handle,idtype_t type,id_t id)1596134Scasper klpd_unregister_id(void *handle, idtype_t type, id_t id)
1606134Scasper {
1616134Scasper 	klpd_data_t *p = handle;
1626134Scasper 	int err;
1636134Scasper 
1646134Scasper 	err = syscall(SYS_privsys, PRIVSYS_KLPD_UNREG, p->kd_doorfd, id,
1656134Scasper 	    (void *)NULL, 0L, type);
1666134Scasper 	if (close(p->kd_doorfd) != 0)
1676134Scasper 		err = -1;
1686134Scasper 	free(p);
1696134Scasper 	return (err);
1706134Scasper }
1716134Scasper 
1726134Scasper int
klpd_unregister(void * handle)1736134Scasper klpd_unregister(void *handle)
1746134Scasper {
1756134Scasper 	return (klpd_unregister_id(handle, P_PID, -1));
1766134Scasper }
1776134Scasper 
1786134Scasper const char *
klpd_getpath(void * context)1796134Scasper klpd_getpath(void *context)
1806134Scasper {
1816134Scasper 	klpd_ctxt_t *p = context;
1826134Scasper 
1836134Scasper 	if (p->kc_type != KLPDARG_VNODE)
1846134Scasper 		errno = EINVAL;
1856134Scasper 	return (p->kc_path);
1866134Scasper }
1876134Scasper 
1886134Scasper int
klpd_getport(void * context,int * proto)1896134Scasper klpd_getport(void *context, int *proto)
1906134Scasper {
1916134Scasper 	klpd_ctxt_t *p = context;
1926134Scasper 
1936134Scasper 	switch (p->kc_type) {
1946134Scasper 	case KLPDARG_TCPPORT:
1956134Scasper 		*proto = IPPROTO_TCP;
1966134Scasper 		break;
1976134Scasper 	case KLPDARG_UDPPORT:
1986134Scasper 		*proto = IPPROTO_UDP;
1996134Scasper 		break;
2006134Scasper 	case KLPDARG_SCTPPORT:
2016134Scasper 		*proto = IPPROTO_SCTP;
2026134Scasper 		break;
2036134Scasper 	case KLPDARG_SDPPORT:
2046134Scasper 		*proto = PROTO_SDP;
2056134Scasper 		break;
2066134Scasper 	default:
2076134Scasper 		errno = EINVAL;
2086134Scasper 		return (-1);
2096134Scasper 	}
2106134Scasper 	return (p->kc_int);
2116134Scasper }
2126134Scasper 
2136134Scasper /*ARGSUSED*/
2146134Scasper int
klpd_getucred(ucred_t ** uc,void * context)2156134Scasper klpd_getucred(ucred_t **uc, void *context)
2166134Scasper {
2176134Scasper 	return (door_ucred(uc));
2186134Scasper }
219