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 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 * 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 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 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 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 173ddf7fe95Scasper klpd_unregister(void *handle) 174ddf7fe95Scasper { 175ddf7fe95Scasper return (klpd_unregister_id(handle, P_PID, -1)); 176ddf7fe95Scasper } 177ddf7fe95Scasper 178ddf7fe95Scasper const char * 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 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 215ddf7fe95Scasper klpd_getucred(ucred_t **uc, void *context) 216ddf7fe95Scasper { 217ddf7fe95Scasper return (door_ucred(uc)); 218ddf7fe95Scasper } 219