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