1*0ba2cbe9Sxc151355 /* 2*0ba2cbe9Sxc151355 * CDDL HEADER START 3*0ba2cbe9Sxc151355 * 4*0ba2cbe9Sxc151355 * The contents of this file are subject to the terms of the 5*0ba2cbe9Sxc151355 * Common Development and Distribution License (the "License"). 6*0ba2cbe9Sxc151355 * You may not use this file except in compliance with the License. 7*0ba2cbe9Sxc151355 * 8*0ba2cbe9Sxc151355 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*0ba2cbe9Sxc151355 * or http://www.opensolaris.org/os/licensing. 10*0ba2cbe9Sxc151355 * See the License for the specific language governing permissions 11*0ba2cbe9Sxc151355 * and limitations under the License. 12*0ba2cbe9Sxc151355 * 13*0ba2cbe9Sxc151355 * When distributing Covered Code, include this CDDL HEADER in each 14*0ba2cbe9Sxc151355 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*0ba2cbe9Sxc151355 * If applicable, add the following below this CDDL HEADER, with the 16*0ba2cbe9Sxc151355 * fields enclosed by brackets "[]" replaced with your own identifying 17*0ba2cbe9Sxc151355 * information: Portions Copyright [yyyy] [name of copyright owner] 18*0ba2cbe9Sxc151355 * 19*0ba2cbe9Sxc151355 * CDDL HEADER END 20*0ba2cbe9Sxc151355 */ 21*0ba2cbe9Sxc151355 /* 22*0ba2cbe9Sxc151355 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*0ba2cbe9Sxc151355 * Use is subject to license terms. 24*0ba2cbe9Sxc151355 */ 25*0ba2cbe9Sxc151355 26*0ba2cbe9Sxc151355 #pragma ident "%Z%%M% %I% %E% SMI" 27*0ba2cbe9Sxc151355 28*0ba2cbe9Sxc151355 #include <unistd.h> 29*0ba2cbe9Sxc151355 #include <stdlib.h> 30*0ba2cbe9Sxc151355 #include <strings.h> 31*0ba2cbe9Sxc151355 #include <errno.h> 32*0ba2cbe9Sxc151355 #include <ctype.h> 33*0ba2cbe9Sxc151355 #include <fcntl.h> 34*0ba2cbe9Sxc151355 #include <sys/stat.h> 35*0ba2cbe9Sxc151355 #include <sys/dld.h> 36*0ba2cbe9Sxc151355 #include <libinetutil.h> 37*0ba2cbe9Sxc151355 #include <libdladm_impl.h> 38*0ba2cbe9Sxc151355 39*0ba2cbe9Sxc151355 static dladm_status_t i_dladm_set_secobj_db(const char *, 40*0ba2cbe9Sxc151355 dladm_secobj_class_t, uint8_t *, uint_t); 41*0ba2cbe9Sxc151355 static dladm_status_t i_dladm_get_secobj_db(const char *, 42*0ba2cbe9Sxc151355 dladm_secobj_class_t *, uint8_t *, uint_t *); 43*0ba2cbe9Sxc151355 static dladm_status_t i_dladm_unset_secobj_db(const char *); 44*0ba2cbe9Sxc151355 static dladm_status_t i_dladm_walk_secobj_db(void *, 45*0ba2cbe9Sxc151355 boolean_t (*)(void *, const char *)); 46*0ba2cbe9Sxc151355 47*0ba2cbe9Sxc151355 typedef struct secobj_class_info { 48*0ba2cbe9Sxc151355 const char *sc_name; 49*0ba2cbe9Sxc151355 dld_secobj_class_t sc_dldclass; 50*0ba2cbe9Sxc151355 } secobj_class_info_t; 51*0ba2cbe9Sxc151355 52*0ba2cbe9Sxc151355 static secobj_class_info_t secobj_class_table[] = { 53*0ba2cbe9Sxc151355 {"wep", DLD_SECOBJ_CLASS_WEP} 54*0ba2cbe9Sxc151355 }; 55*0ba2cbe9Sxc151355 56*0ba2cbe9Sxc151355 #define NSECOBJCLASS \ 57*0ba2cbe9Sxc151355 (sizeof (secobj_class_table) / sizeof (secobj_class_info_t)) 58*0ba2cbe9Sxc151355 59*0ba2cbe9Sxc151355 static boolean_t 60*0ba2cbe9Sxc151355 dladm_check_secobjclass(dladm_secobj_class_t class) 61*0ba2cbe9Sxc151355 { 62*0ba2cbe9Sxc151355 return (class >= 0 && class < NSECOBJCLASS); 63*0ba2cbe9Sxc151355 } 64*0ba2cbe9Sxc151355 65*0ba2cbe9Sxc151355 dladm_status_t 66*0ba2cbe9Sxc151355 dladm_str2secobjclass(const char *str, dladm_secobj_class_t *class) 67*0ba2cbe9Sxc151355 { 68*0ba2cbe9Sxc151355 int i; 69*0ba2cbe9Sxc151355 secobj_class_info_t *sp; 70*0ba2cbe9Sxc151355 71*0ba2cbe9Sxc151355 for (i = 0; i < NSECOBJCLASS; i++) { 72*0ba2cbe9Sxc151355 sp = &secobj_class_table[i]; 73*0ba2cbe9Sxc151355 if (strcasecmp(str, sp->sc_name) == 0) { 74*0ba2cbe9Sxc151355 *class = i; 75*0ba2cbe9Sxc151355 return (DLADM_STATUS_OK); 76*0ba2cbe9Sxc151355 } 77*0ba2cbe9Sxc151355 } 78*0ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 79*0ba2cbe9Sxc151355 } 80*0ba2cbe9Sxc151355 81*0ba2cbe9Sxc151355 const char * 82*0ba2cbe9Sxc151355 dladm_secobjclass2str(dladm_secobj_class_t class, char *buf) 83*0ba2cbe9Sxc151355 { 84*0ba2cbe9Sxc151355 const char *s; 85*0ba2cbe9Sxc151355 86*0ba2cbe9Sxc151355 if (!dladm_check_secobjclass(class)) 87*0ba2cbe9Sxc151355 s = ""; 88*0ba2cbe9Sxc151355 else 89*0ba2cbe9Sxc151355 s = secobj_class_table[class].sc_name; 90*0ba2cbe9Sxc151355 91*0ba2cbe9Sxc151355 (void) snprintf(buf, DLADM_STRSIZE, "%s", s); 92*0ba2cbe9Sxc151355 return (buf); 93*0ba2cbe9Sxc151355 } 94*0ba2cbe9Sxc151355 95*0ba2cbe9Sxc151355 static boolean_t 96*0ba2cbe9Sxc151355 dladm_convert_secobjclass(dladm_secobj_class_t class, 97*0ba2cbe9Sxc151355 dld_secobj_class_t *dldclass) 98*0ba2cbe9Sxc151355 { 99*0ba2cbe9Sxc151355 if (!dladm_check_secobjclass(class)) 100*0ba2cbe9Sxc151355 return (B_FALSE); 101*0ba2cbe9Sxc151355 102*0ba2cbe9Sxc151355 *dldclass = secobj_class_table[class].sc_dldclass; 103*0ba2cbe9Sxc151355 return (B_TRUE); 104*0ba2cbe9Sxc151355 } 105*0ba2cbe9Sxc151355 106*0ba2cbe9Sxc151355 static boolean_t 107*0ba2cbe9Sxc151355 dladm_convert_dldsecobjclass(dld_secobj_class_t dldclass, 108*0ba2cbe9Sxc151355 dladm_secobj_class_t *class) 109*0ba2cbe9Sxc151355 { 110*0ba2cbe9Sxc151355 int i; 111*0ba2cbe9Sxc151355 secobj_class_info_t *sp; 112*0ba2cbe9Sxc151355 113*0ba2cbe9Sxc151355 for (i = 0; i < NSECOBJCLASS; i++) { 114*0ba2cbe9Sxc151355 sp = &secobj_class_table[i]; 115*0ba2cbe9Sxc151355 if (dldclass == sp->sc_dldclass) { 116*0ba2cbe9Sxc151355 *class = i; 117*0ba2cbe9Sxc151355 return (B_TRUE); 118*0ba2cbe9Sxc151355 } 119*0ba2cbe9Sxc151355 } 120*0ba2cbe9Sxc151355 return (B_FALSE); 121*0ba2cbe9Sxc151355 } 122*0ba2cbe9Sxc151355 123*0ba2cbe9Sxc151355 dladm_status_t 124*0ba2cbe9Sxc151355 dladm_set_secobj(const char *obj_name, dladm_secobj_class_t class, 125*0ba2cbe9Sxc151355 uint8_t *obj_val, uint_t obj_len, uint_t flags) 126*0ba2cbe9Sxc151355 { 127*0ba2cbe9Sxc151355 int fd; 128*0ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 129*0ba2cbe9Sxc151355 dld_ioc_secobj_set_t secobj_set; 130*0ba2cbe9Sxc151355 dld_secobj_t *objp; 131*0ba2cbe9Sxc151355 132*0ba2cbe9Sxc151355 if (!dladm_check_secobjclass(class) || flags == 0 || 133*0ba2cbe9Sxc151355 obj_name == NULL || strlen(obj_name) > DLD_SECOBJ_NAME_MAX || 134*0ba2cbe9Sxc151355 obj_val == NULL || obj_len == 0 || obj_len > DLD_SECOBJ_VAL_MAX) 135*0ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 136*0ba2cbe9Sxc151355 137*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_TEMP) == 0) 138*0ba2cbe9Sxc151355 goto persist; 139*0ba2cbe9Sxc151355 140*0ba2cbe9Sxc151355 bzero(&secobj_set, sizeof (secobj_set)); 141*0ba2cbe9Sxc151355 objp = &secobj_set.ss_obj; 142*0ba2cbe9Sxc151355 if (!dladm_convert_secobjclass(class, &objp->so_class)) 143*0ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 144*0ba2cbe9Sxc151355 145*0ba2cbe9Sxc151355 (void) strlcpy(objp->so_name, obj_name, DLD_SECOBJ_NAME_MAX); 146*0ba2cbe9Sxc151355 bcopy(obj_val, objp->so_val, obj_len); 147*0ba2cbe9Sxc151355 objp->so_len = obj_len; 148*0ba2cbe9Sxc151355 149*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_CREATE) != 0) 150*0ba2cbe9Sxc151355 secobj_set.ss_flags = DLD_SECOBJ_OPT_CREATE; 151*0ba2cbe9Sxc151355 152*0ba2cbe9Sxc151355 if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) 153*0ba2cbe9Sxc151355 return (dladm_errno2status(errno)); 154*0ba2cbe9Sxc151355 155*0ba2cbe9Sxc151355 if (i_dladm_ioctl(fd, DLDIOCSECOBJSET, &secobj_set, 156*0ba2cbe9Sxc151355 sizeof (secobj_set)) < 0) 157*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 158*0ba2cbe9Sxc151355 159*0ba2cbe9Sxc151355 (void) close(fd); 160*0ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 161*0ba2cbe9Sxc151355 return (status); 162*0ba2cbe9Sxc151355 163*0ba2cbe9Sxc151355 persist: 164*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) { 165*0ba2cbe9Sxc151355 status = i_dladm_set_secobj_db(obj_name, class, 166*0ba2cbe9Sxc151355 obj_val, obj_len); 167*0ba2cbe9Sxc151355 } 168*0ba2cbe9Sxc151355 return (status); 169*0ba2cbe9Sxc151355 } 170*0ba2cbe9Sxc151355 171*0ba2cbe9Sxc151355 dladm_status_t 172*0ba2cbe9Sxc151355 dladm_get_secobj(const char *obj_name, dladm_secobj_class_t *classp, 173*0ba2cbe9Sxc151355 uint8_t *obj_val, uint_t *obj_lenp, uint_t flags) 174*0ba2cbe9Sxc151355 { 175*0ba2cbe9Sxc151355 int fd; 176*0ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 177*0ba2cbe9Sxc151355 dld_ioc_secobj_get_t secobj_get; 178*0ba2cbe9Sxc151355 dld_secobj_t *objp; 179*0ba2cbe9Sxc151355 180*0ba2cbe9Sxc151355 if (obj_name == NULL || strlen(obj_name) > DLD_SECOBJ_NAME_MAX || 181*0ba2cbe9Sxc151355 obj_val == NULL || obj_lenp == NULL || *obj_lenp == 0 || 182*0ba2cbe9Sxc151355 *obj_lenp > DLD_SECOBJ_VAL_MAX) 183*0ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 184*0ba2cbe9Sxc151355 185*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) { 186*0ba2cbe9Sxc151355 return (i_dladm_get_secobj_db(obj_name, classp, 187*0ba2cbe9Sxc151355 obj_val, obj_lenp)); 188*0ba2cbe9Sxc151355 } 189*0ba2cbe9Sxc151355 190*0ba2cbe9Sxc151355 bzero(&secobj_get, sizeof (secobj_get)); 191*0ba2cbe9Sxc151355 objp = &secobj_get.sg_obj; 192*0ba2cbe9Sxc151355 (void) strlcpy(objp->so_name, obj_name, DLD_SECOBJ_NAME_MAX); 193*0ba2cbe9Sxc151355 194*0ba2cbe9Sxc151355 if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) 195*0ba2cbe9Sxc151355 return (dladm_errno2status(errno)); 196*0ba2cbe9Sxc151355 197*0ba2cbe9Sxc151355 if (i_dladm_ioctl(fd, DLDIOCSECOBJGET, &secobj_get, 198*0ba2cbe9Sxc151355 sizeof (secobj_get)) < 0) 199*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 200*0ba2cbe9Sxc151355 201*0ba2cbe9Sxc151355 (void) close(fd); 202*0ba2cbe9Sxc151355 if (objp->so_len > *obj_lenp) 203*0ba2cbe9Sxc151355 return (DLADM_STATUS_TOOSMALL); 204*0ba2cbe9Sxc151355 205*0ba2cbe9Sxc151355 if (!dladm_convert_dldsecobjclass(objp->so_class, classp)) 206*0ba2cbe9Sxc151355 return (DLADM_STATUS_FAILED); 207*0ba2cbe9Sxc151355 208*0ba2cbe9Sxc151355 *obj_lenp = objp->so_len; 209*0ba2cbe9Sxc151355 bcopy(objp->so_val, obj_val, *obj_lenp); 210*0ba2cbe9Sxc151355 return (status); 211*0ba2cbe9Sxc151355 } 212*0ba2cbe9Sxc151355 213*0ba2cbe9Sxc151355 dladm_status_t 214*0ba2cbe9Sxc151355 dladm_unset_secobj(const char *obj_name, uint_t flags) 215*0ba2cbe9Sxc151355 { 216*0ba2cbe9Sxc151355 int fd; 217*0ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 218*0ba2cbe9Sxc151355 dld_ioc_secobj_unset_t secobj_unset; 219*0ba2cbe9Sxc151355 220*0ba2cbe9Sxc151355 if (obj_name == NULL || strlen(obj_name) > DLD_SECOBJ_NAME_MAX || 221*0ba2cbe9Sxc151355 flags == 0) 222*0ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG); 223*0ba2cbe9Sxc151355 224*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_TEMP) == 0) 225*0ba2cbe9Sxc151355 goto persist; 226*0ba2cbe9Sxc151355 227*0ba2cbe9Sxc151355 bzero(&secobj_unset, sizeof (secobj_unset)); 228*0ba2cbe9Sxc151355 (void) strlcpy(secobj_unset.su_name, obj_name, DLD_SECOBJ_NAME_MAX); 229*0ba2cbe9Sxc151355 if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) 230*0ba2cbe9Sxc151355 return (dladm_errno2status(errno)); 231*0ba2cbe9Sxc151355 232*0ba2cbe9Sxc151355 if (i_dladm_ioctl(fd, DLDIOCSECOBJUNSET, &secobj_unset, 233*0ba2cbe9Sxc151355 sizeof (secobj_unset)) < 0) 234*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 235*0ba2cbe9Sxc151355 236*0ba2cbe9Sxc151355 (void) close(fd); 237*0ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 238*0ba2cbe9Sxc151355 return (status); 239*0ba2cbe9Sxc151355 240*0ba2cbe9Sxc151355 persist: 241*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) 242*0ba2cbe9Sxc151355 status = i_dladm_unset_secobj_db(obj_name); 243*0ba2cbe9Sxc151355 244*0ba2cbe9Sxc151355 return (status); 245*0ba2cbe9Sxc151355 } 246*0ba2cbe9Sxc151355 247*0ba2cbe9Sxc151355 #define SECOBJ_BUFSZ 65536 248*0ba2cbe9Sxc151355 dladm_status_t 249*0ba2cbe9Sxc151355 dladm_walk_secobj(void *arg, boolean_t (*func)(void *, const char *), 250*0ba2cbe9Sxc151355 uint_t flags) 251*0ba2cbe9Sxc151355 { 252*0ba2cbe9Sxc151355 int fd = -1; 253*0ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 254*0ba2cbe9Sxc151355 dld_ioc_secobj_get_t *secobj_getp; 255*0ba2cbe9Sxc151355 dld_secobj_t *objp; 256*0ba2cbe9Sxc151355 257*0ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) 258*0ba2cbe9Sxc151355 return (i_dladm_walk_secobj_db(arg, func)); 259*0ba2cbe9Sxc151355 260*0ba2cbe9Sxc151355 secobj_getp = calloc(1, SECOBJ_BUFSZ); 261*0ba2cbe9Sxc151355 if (secobj_getp == NULL) 262*0ba2cbe9Sxc151355 return (DLADM_STATUS_NOMEM); 263*0ba2cbe9Sxc151355 264*0ba2cbe9Sxc151355 if ((fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0) { 265*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 266*0ba2cbe9Sxc151355 goto done; 267*0ba2cbe9Sxc151355 } 268*0ba2cbe9Sxc151355 if (i_dladm_ioctl(fd, DLDIOCSECOBJGET, secobj_getp, 269*0ba2cbe9Sxc151355 SECOBJ_BUFSZ) < 0) { 270*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 271*0ba2cbe9Sxc151355 goto done; 272*0ba2cbe9Sxc151355 } 273*0ba2cbe9Sxc151355 274*0ba2cbe9Sxc151355 objp = (dld_secobj_t *)(secobj_getp + 1); 275*0ba2cbe9Sxc151355 while (secobj_getp->sg_count > 0) { 276*0ba2cbe9Sxc151355 if (!func(arg, objp->so_name)) 277*0ba2cbe9Sxc151355 goto done; 278*0ba2cbe9Sxc151355 secobj_getp->sg_count--; 279*0ba2cbe9Sxc151355 objp++; 280*0ba2cbe9Sxc151355 } 281*0ba2cbe9Sxc151355 done: 282*0ba2cbe9Sxc151355 (void) close(fd); 283*0ba2cbe9Sxc151355 free(secobj_getp); 284*0ba2cbe9Sxc151355 return (status); 285*0ba2cbe9Sxc151355 } 286*0ba2cbe9Sxc151355 287*0ba2cbe9Sxc151355 /* 288*0ba2cbe9Sxc151355 * Data structures used for implementing persistent secure objects 289*0ba2cbe9Sxc151355 */ 290*0ba2cbe9Sxc151355 typedef struct secobj_info { 291*0ba2cbe9Sxc151355 const char *si_name; 292*0ba2cbe9Sxc151355 dladm_secobj_class_t *si_classp; 293*0ba2cbe9Sxc151355 uint8_t *si_val; 294*0ba2cbe9Sxc151355 uint_t *si_lenp; 295*0ba2cbe9Sxc151355 } secobj_info_t; 296*0ba2cbe9Sxc151355 297*0ba2cbe9Sxc151355 typedef struct secobj_name { 298*0ba2cbe9Sxc151355 char *sn_name; 299*0ba2cbe9Sxc151355 struct secobj_name *sn_next; 300*0ba2cbe9Sxc151355 } secobj_name_t; 301*0ba2cbe9Sxc151355 302*0ba2cbe9Sxc151355 typedef struct secobj_db_state secobj_db_state_t; 303*0ba2cbe9Sxc151355 304*0ba2cbe9Sxc151355 typedef boolean_t (*secobj_db_op_t)(struct secobj_db_state *, char *, 305*0ba2cbe9Sxc151355 secobj_info_t *, dladm_status_t *); 306*0ba2cbe9Sxc151355 307*0ba2cbe9Sxc151355 struct secobj_db_state { 308*0ba2cbe9Sxc151355 secobj_db_op_t ss_op; 309*0ba2cbe9Sxc151355 secobj_info_t ss_info; 310*0ba2cbe9Sxc151355 secobj_name_t **ss_namelist; 311*0ba2cbe9Sxc151355 }; 312*0ba2cbe9Sxc151355 313*0ba2cbe9Sxc151355 /* 314*0ba2cbe9Sxc151355 * Update or generate a secobj entry using the info in ssp->ss_info. 315*0ba2cbe9Sxc151355 */ 316*0ba2cbe9Sxc151355 /* ARGSUSED */ 317*0ba2cbe9Sxc151355 static boolean_t 318*0ba2cbe9Sxc151355 process_secobj_set(secobj_db_state_t *ssp, char *buf, secobj_info_t *sip, 319*0ba2cbe9Sxc151355 dladm_status_t *statusp) 320*0ba2cbe9Sxc151355 { 321*0ba2cbe9Sxc151355 char tmpbuf[MAXLINELEN]; 322*0ba2cbe9Sxc151355 char classbuf[DLADM_STRSIZE]; 323*0ba2cbe9Sxc151355 char *ptr = tmpbuf, *lim = tmpbuf + MAXLINELEN; 324*0ba2cbe9Sxc151355 int i; 325*0ba2cbe9Sxc151355 326*0ba2cbe9Sxc151355 sip = &ssp->ss_info; 327*0ba2cbe9Sxc151355 328*0ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", sip->si_name); 329*0ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", 330*0ba2cbe9Sxc151355 dladm_secobjclass2str(*sip->si_classp, classbuf)); 331*0ba2cbe9Sxc151355 332*0ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "0x"); 333*0ba2cbe9Sxc151355 for (i = 0; i < *sip->si_lenp; i++) { 334*0ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%02x", 335*0ba2cbe9Sxc151355 sip->si_val[i] & 0xff); 336*0ba2cbe9Sxc151355 } 337*0ba2cbe9Sxc151355 if (ptr > lim) { 338*0ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL; 339*0ba2cbe9Sxc151355 return (B_FALSE); 340*0ba2cbe9Sxc151355 } 341*0ba2cbe9Sxc151355 (void) snprintf(buf, MAXLINELEN, "%s\n", tmpbuf); 342*0ba2cbe9Sxc151355 return (B_FALSE); 343*0ba2cbe9Sxc151355 } 344*0ba2cbe9Sxc151355 345*0ba2cbe9Sxc151355 /* ARGSUSED */ 346*0ba2cbe9Sxc151355 static boolean_t 347*0ba2cbe9Sxc151355 process_secobj_get(secobj_db_state_t *ssp, char *buf, secobj_info_t *sip, 348*0ba2cbe9Sxc151355 dladm_status_t *statusp) 349*0ba2cbe9Sxc151355 { 350*0ba2cbe9Sxc151355 if (*sip->si_lenp > *ssp->ss_info.si_lenp) { 351*0ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL; 352*0ba2cbe9Sxc151355 return (B_FALSE); 353*0ba2cbe9Sxc151355 } 354*0ba2cbe9Sxc151355 bcopy(sip->si_val, ssp->ss_info.si_val, *sip->si_lenp); 355*0ba2cbe9Sxc151355 *ssp->ss_info.si_lenp = *sip->si_lenp; 356*0ba2cbe9Sxc151355 *ssp->ss_info.si_classp = *sip->si_classp; 357*0ba2cbe9Sxc151355 return (B_FALSE); 358*0ba2cbe9Sxc151355 } 359*0ba2cbe9Sxc151355 360*0ba2cbe9Sxc151355 /* ARGSUSED */ 361*0ba2cbe9Sxc151355 static boolean_t 362*0ba2cbe9Sxc151355 process_secobj_unset(secobj_db_state_t *ssp, char *buf, secobj_info_t *sip, 363*0ba2cbe9Sxc151355 dladm_status_t *statusp) 364*0ba2cbe9Sxc151355 { 365*0ba2cbe9Sxc151355 /* 366*0ba2cbe9Sxc151355 * Delete line. 367*0ba2cbe9Sxc151355 */ 368*0ba2cbe9Sxc151355 buf[0] = '\0'; 369*0ba2cbe9Sxc151355 return (B_FALSE); 370*0ba2cbe9Sxc151355 } 371*0ba2cbe9Sxc151355 372*0ba2cbe9Sxc151355 /* ARGSUSED */ 373*0ba2cbe9Sxc151355 static boolean_t 374*0ba2cbe9Sxc151355 process_secobj_walk(secobj_db_state_t *ssp, char *buf, secobj_info_t *sip, 375*0ba2cbe9Sxc151355 dladm_status_t *statusp) 376*0ba2cbe9Sxc151355 { 377*0ba2cbe9Sxc151355 secobj_name_t *snp; 378*0ba2cbe9Sxc151355 379*0ba2cbe9Sxc151355 if ((snp = malloc(sizeof (*snp))) == NULL) 380*0ba2cbe9Sxc151355 return (B_TRUE); 381*0ba2cbe9Sxc151355 382*0ba2cbe9Sxc151355 if ((snp->sn_name = strdup(sip->si_name)) == NULL) { 383*0ba2cbe9Sxc151355 free(snp); 384*0ba2cbe9Sxc151355 return (B_TRUE); 385*0ba2cbe9Sxc151355 } 386*0ba2cbe9Sxc151355 387*0ba2cbe9Sxc151355 snp->sn_next = NULL; 388*0ba2cbe9Sxc151355 *ssp->ss_namelist = snp; 389*0ba2cbe9Sxc151355 ssp->ss_namelist = &snp->sn_next; 390*0ba2cbe9Sxc151355 return (B_TRUE); 391*0ba2cbe9Sxc151355 } 392*0ba2cbe9Sxc151355 393*0ba2cbe9Sxc151355 /* ARGSUSED */ 394*0ba2cbe9Sxc151355 static boolean_t 395*0ba2cbe9Sxc151355 process_secobj_init(secobj_db_state_t *ssp, char *buf, secobj_info_t *sip, 396*0ba2cbe9Sxc151355 dladm_status_t *statusp) 397*0ba2cbe9Sxc151355 { 398*0ba2cbe9Sxc151355 *statusp = dladm_set_secobj(sip->si_name, *sip->si_classp, sip->si_val, 399*0ba2cbe9Sxc151355 *sip->si_lenp, DLADM_OPT_TEMP | DLADM_OPT_CREATE); 400*0ba2cbe9Sxc151355 return (B_TRUE); 401*0ba2cbe9Sxc151355 } 402*0ba2cbe9Sxc151355 403*0ba2cbe9Sxc151355 static int 404*0ba2cbe9Sxc151355 parse_secobj_val(char *buf, secobj_info_t *sip) 405*0ba2cbe9Sxc151355 { 406*0ba2cbe9Sxc151355 if (strncmp(buf, "0x", 2) != 0) 407*0ba2cbe9Sxc151355 return (EINVAL); 408*0ba2cbe9Sxc151355 409*0ba2cbe9Sxc151355 return (hexascii_to_octet(buf + 2, strlen(buf) - 2, 410*0ba2cbe9Sxc151355 sip->si_val, sip->si_lenp)); 411*0ba2cbe9Sxc151355 } 412*0ba2cbe9Sxc151355 413*0ba2cbe9Sxc151355 static boolean_t 414*0ba2cbe9Sxc151355 process_secobj_line(secobj_db_state_t *ssp, char *buf, 415*0ba2cbe9Sxc151355 dladm_status_t *statusp) 416*0ba2cbe9Sxc151355 { 417*0ba2cbe9Sxc151355 secobj_info_t sinfo; 418*0ba2cbe9Sxc151355 dladm_secobj_class_t class; 419*0ba2cbe9Sxc151355 uint8_t val[DLADM_SECOBJ_VAL_MAX]; 420*0ba2cbe9Sxc151355 uint_t vlen; 421*0ba2cbe9Sxc151355 int i, len, nlen; 422*0ba2cbe9Sxc151355 char *str, *lasts; 423*0ba2cbe9Sxc151355 424*0ba2cbe9Sxc151355 /* 425*0ba2cbe9Sxc151355 * Skip leading spaces, blank lines, and comments. 426*0ba2cbe9Sxc151355 */ 427*0ba2cbe9Sxc151355 len = strlen(buf); 428*0ba2cbe9Sxc151355 for (i = 0; i < len; i++) { 429*0ba2cbe9Sxc151355 if (!isspace(buf[i])) 430*0ba2cbe9Sxc151355 break; 431*0ba2cbe9Sxc151355 } 432*0ba2cbe9Sxc151355 if (i == len || buf[i] == '#') 433*0ba2cbe9Sxc151355 return (B_TRUE); 434*0ba2cbe9Sxc151355 435*0ba2cbe9Sxc151355 str = buf + i; 436*0ba2cbe9Sxc151355 if (ssp->ss_info.si_name != NULL) { 437*0ba2cbe9Sxc151355 /* 438*0ba2cbe9Sxc151355 * Skip objects we're not interested in. 439*0ba2cbe9Sxc151355 */ 440*0ba2cbe9Sxc151355 nlen = strlen(ssp->ss_info.si_name); 441*0ba2cbe9Sxc151355 if (strncmp(str, ssp->ss_info.si_name, nlen) != 0 || 442*0ba2cbe9Sxc151355 !isspace(str[nlen])) 443*0ba2cbe9Sxc151355 return (B_TRUE); 444*0ba2cbe9Sxc151355 445*0ba2cbe9Sxc151355 sinfo.si_name = ssp->ss_info.si_name; 446*0ba2cbe9Sxc151355 } else { 447*0ba2cbe9Sxc151355 /* 448*0ba2cbe9Sxc151355 * If an object is not specified, find the object name 449*0ba2cbe9Sxc151355 * and assign it to sinfo.si_name. 450*0ba2cbe9Sxc151355 */ 451*0ba2cbe9Sxc151355 if (strtok_r(str, " \n\t", &lasts) == NULL) 452*0ba2cbe9Sxc151355 goto fail; 453*0ba2cbe9Sxc151355 454*0ba2cbe9Sxc151355 nlen = strlen(str); 455*0ba2cbe9Sxc151355 sinfo.si_name = str; 456*0ba2cbe9Sxc151355 } 457*0ba2cbe9Sxc151355 str += nlen + 1; 458*0ba2cbe9Sxc151355 if (str >= buf + len) 459*0ba2cbe9Sxc151355 goto fail; 460*0ba2cbe9Sxc151355 461*0ba2cbe9Sxc151355 /* 462*0ba2cbe9Sxc151355 * Find the class name. 463*0ba2cbe9Sxc151355 */ 464*0ba2cbe9Sxc151355 if ((str = strtok_r(str, " \n\t", &lasts)) == NULL) 465*0ba2cbe9Sxc151355 goto fail; 466*0ba2cbe9Sxc151355 467*0ba2cbe9Sxc151355 *statusp = dladm_str2secobjclass(str, &class); 468*0ba2cbe9Sxc151355 if (*statusp != DLADM_STATUS_OK) 469*0ba2cbe9Sxc151355 goto fail; 470*0ba2cbe9Sxc151355 471*0ba2cbe9Sxc151355 /* 472*0ba2cbe9Sxc151355 * Find the object value. 473*0ba2cbe9Sxc151355 */ 474*0ba2cbe9Sxc151355 if ((str = strtok_r(NULL, " \n\t", &lasts)) == NULL) 475*0ba2cbe9Sxc151355 goto fail; 476*0ba2cbe9Sxc151355 477*0ba2cbe9Sxc151355 vlen = DLADM_SECOBJ_VAL_MAX; 478*0ba2cbe9Sxc151355 sinfo.si_classp = &class; 479*0ba2cbe9Sxc151355 sinfo.si_val = val; 480*0ba2cbe9Sxc151355 sinfo.si_lenp = &vlen; 481*0ba2cbe9Sxc151355 if (parse_secobj_val(str, &sinfo) != 0) 482*0ba2cbe9Sxc151355 goto fail; 483*0ba2cbe9Sxc151355 484*0ba2cbe9Sxc151355 return ((*ssp->ss_op)(ssp, buf, &sinfo, statusp)); 485*0ba2cbe9Sxc151355 486*0ba2cbe9Sxc151355 fail: 487*0ba2cbe9Sxc151355 /* 488*0ba2cbe9Sxc151355 * Delete corrupted line. 489*0ba2cbe9Sxc151355 */ 490*0ba2cbe9Sxc151355 buf[0] = '\0'; 491*0ba2cbe9Sxc151355 return (B_TRUE); 492*0ba2cbe9Sxc151355 } 493*0ba2cbe9Sxc151355 494*0ba2cbe9Sxc151355 static dladm_status_t 495*0ba2cbe9Sxc151355 process_secobj_db(void *arg, FILE *fp, FILE *nfp) 496*0ba2cbe9Sxc151355 { 497*0ba2cbe9Sxc151355 secobj_db_state_t *ssp = arg; 498*0ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK; 499*0ba2cbe9Sxc151355 char buf[MAXLINELEN]; 500*0ba2cbe9Sxc151355 boolean_t cont = B_TRUE; 501*0ba2cbe9Sxc151355 502*0ba2cbe9Sxc151355 /* 503*0ba2cbe9Sxc151355 * This loop processes each line of the configuration file. 504*0ba2cbe9Sxc151355 * buf can potentially be modified by process_secobj_line(). 505*0ba2cbe9Sxc151355 * If this is a write operation and buf is not truncated, buf will 506*0ba2cbe9Sxc151355 * be written to disk. process_secobj_line() will no longer be 507*0ba2cbe9Sxc151355 * called after it returns B_FALSE; at which point the remainder 508*0ba2cbe9Sxc151355 * of the file will continue to be read and, if necessary, written 509*0ba2cbe9Sxc151355 * to disk as well. 510*0ba2cbe9Sxc151355 */ 511*0ba2cbe9Sxc151355 while (fgets(buf, MAXLINELEN, fp) != NULL) { 512*0ba2cbe9Sxc151355 if (cont) 513*0ba2cbe9Sxc151355 cont = process_secobj_line(ssp, buf, &status); 514*0ba2cbe9Sxc151355 515*0ba2cbe9Sxc151355 if (nfp != NULL && buf[0] != '\0' && fputs(buf, nfp) == EOF) { 516*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 517*0ba2cbe9Sxc151355 break; 518*0ba2cbe9Sxc151355 } 519*0ba2cbe9Sxc151355 } 520*0ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK || !cont) 521*0ba2cbe9Sxc151355 return (status); 522*0ba2cbe9Sxc151355 523*0ba2cbe9Sxc151355 if (ssp->ss_op == process_secobj_set) { 524*0ba2cbe9Sxc151355 /* 525*0ba2cbe9Sxc151355 * If the specified object is not found above, we add the 526*0ba2cbe9Sxc151355 * object to the configuration file. 527*0ba2cbe9Sxc151355 */ 528*0ba2cbe9Sxc151355 (void) (*ssp->ss_op)(ssp, buf, NULL, &status); 529*0ba2cbe9Sxc151355 if (status == DLADM_STATUS_OK && fputs(buf, nfp) == EOF) 530*0ba2cbe9Sxc151355 status = dladm_errno2status(errno); 531*0ba2cbe9Sxc151355 } 532*0ba2cbe9Sxc151355 533*0ba2cbe9Sxc151355 if (ssp->ss_op == process_secobj_unset || 534*0ba2cbe9Sxc151355 ssp->ss_op == process_secobj_get) 535*0ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND; 536*0ba2cbe9Sxc151355 537*0ba2cbe9Sxc151355 return (status); 538*0ba2cbe9Sxc151355 } 539*0ba2cbe9Sxc151355 540*0ba2cbe9Sxc151355 #define SECOBJ_RW_DB(statep, writeop) \ 541*0ba2cbe9Sxc151355 (i_dladm_rw_db("/etc/dladm/secobj.conf", S_IRUSR | S_IWUSR, \ 542*0ba2cbe9Sxc151355 process_secobj_db, (statep), (writeop))) 543*0ba2cbe9Sxc151355 544*0ba2cbe9Sxc151355 static dladm_status_t 545*0ba2cbe9Sxc151355 i_dladm_set_secobj_db(const char *obj_name, dladm_secobj_class_t class, 546*0ba2cbe9Sxc151355 uint8_t *obj_val, uint_t obj_len) 547*0ba2cbe9Sxc151355 { 548*0ba2cbe9Sxc151355 secobj_db_state_t state; 549*0ba2cbe9Sxc151355 550*0ba2cbe9Sxc151355 state.ss_op = process_secobj_set; 551*0ba2cbe9Sxc151355 state.ss_info.si_name = obj_name; 552*0ba2cbe9Sxc151355 state.ss_info.si_classp = &class; 553*0ba2cbe9Sxc151355 state.ss_info.si_val = obj_val; 554*0ba2cbe9Sxc151355 state.ss_info.si_lenp = &obj_len; 555*0ba2cbe9Sxc151355 state.ss_namelist = NULL; 556*0ba2cbe9Sxc151355 557*0ba2cbe9Sxc151355 return (SECOBJ_RW_DB(&state, B_TRUE)); 558*0ba2cbe9Sxc151355 } 559*0ba2cbe9Sxc151355 560*0ba2cbe9Sxc151355 static dladm_status_t 561*0ba2cbe9Sxc151355 i_dladm_get_secobj_db(const char *obj_name, dladm_secobj_class_t *classp, 562*0ba2cbe9Sxc151355 uint8_t *obj_val, uint_t *obj_lenp) 563*0ba2cbe9Sxc151355 { 564*0ba2cbe9Sxc151355 secobj_db_state_t state; 565*0ba2cbe9Sxc151355 566*0ba2cbe9Sxc151355 state.ss_op = process_secobj_get; 567*0ba2cbe9Sxc151355 state.ss_info.si_name = obj_name; 568*0ba2cbe9Sxc151355 state.ss_info.si_classp = classp; 569*0ba2cbe9Sxc151355 state.ss_info.si_val = obj_val; 570*0ba2cbe9Sxc151355 state.ss_info.si_lenp = obj_lenp; 571*0ba2cbe9Sxc151355 state.ss_namelist = NULL; 572*0ba2cbe9Sxc151355 573*0ba2cbe9Sxc151355 return (SECOBJ_RW_DB(&state, B_FALSE)); 574*0ba2cbe9Sxc151355 } 575*0ba2cbe9Sxc151355 576*0ba2cbe9Sxc151355 static dladm_status_t 577*0ba2cbe9Sxc151355 i_dladm_unset_secobj_db(const char *obj_name) 578*0ba2cbe9Sxc151355 { 579*0ba2cbe9Sxc151355 secobj_db_state_t state; 580*0ba2cbe9Sxc151355 581*0ba2cbe9Sxc151355 state.ss_op = process_secobj_unset; 582*0ba2cbe9Sxc151355 state.ss_info.si_name = obj_name; 583*0ba2cbe9Sxc151355 state.ss_info.si_classp = NULL; 584*0ba2cbe9Sxc151355 state.ss_info.si_val = NULL; 585*0ba2cbe9Sxc151355 state.ss_info.si_lenp = NULL; 586*0ba2cbe9Sxc151355 state.ss_namelist = NULL; 587*0ba2cbe9Sxc151355 588*0ba2cbe9Sxc151355 return (SECOBJ_RW_DB(&state, B_TRUE)); 589*0ba2cbe9Sxc151355 } 590*0ba2cbe9Sxc151355 591*0ba2cbe9Sxc151355 static dladm_status_t 592*0ba2cbe9Sxc151355 i_dladm_walk_secobj_db(void *arg, boolean_t (*func)(void *, const char *)) 593*0ba2cbe9Sxc151355 { 594*0ba2cbe9Sxc151355 secobj_db_state_t state; 595*0ba2cbe9Sxc151355 secobj_name_t *snp = NULL, *fsnp; 596*0ba2cbe9Sxc151355 dladm_status_t status; 597*0ba2cbe9Sxc151355 boolean_t cont = B_TRUE; 598*0ba2cbe9Sxc151355 599*0ba2cbe9Sxc151355 state.ss_op = process_secobj_walk; 600*0ba2cbe9Sxc151355 state.ss_info.si_name = NULL; 601*0ba2cbe9Sxc151355 state.ss_info.si_classp = NULL; 602*0ba2cbe9Sxc151355 state.ss_info.si_val = NULL; 603*0ba2cbe9Sxc151355 state.ss_info.si_lenp = NULL; 604*0ba2cbe9Sxc151355 state.ss_namelist = &snp; 605*0ba2cbe9Sxc151355 606*0ba2cbe9Sxc151355 status = SECOBJ_RW_DB(&state, B_FALSE); 607*0ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK) 608*0ba2cbe9Sxc151355 return (status); 609*0ba2cbe9Sxc151355 610*0ba2cbe9Sxc151355 while (snp != NULL) { 611*0ba2cbe9Sxc151355 fsnp = snp; 612*0ba2cbe9Sxc151355 snp = snp->sn_next; 613*0ba2cbe9Sxc151355 if (cont) 614*0ba2cbe9Sxc151355 cont = func(arg, fsnp->sn_name); 615*0ba2cbe9Sxc151355 free(fsnp->sn_name); 616*0ba2cbe9Sxc151355 free(fsnp); 617*0ba2cbe9Sxc151355 } 618*0ba2cbe9Sxc151355 return (status); 619*0ba2cbe9Sxc151355 } 620*0ba2cbe9Sxc151355 621*0ba2cbe9Sxc151355 dladm_status_t 622*0ba2cbe9Sxc151355 dladm_init_secobj(void) 623*0ba2cbe9Sxc151355 { 624*0ba2cbe9Sxc151355 secobj_db_state_t state; 625*0ba2cbe9Sxc151355 626*0ba2cbe9Sxc151355 state.ss_op = process_secobj_init; 627*0ba2cbe9Sxc151355 state.ss_info.si_name = NULL; 628*0ba2cbe9Sxc151355 state.ss_info.si_classp = NULL; 629*0ba2cbe9Sxc151355 state.ss_info.si_val = NULL; 630*0ba2cbe9Sxc151355 state.ss_info.si_lenp = NULL; 631*0ba2cbe9Sxc151355 state.ss_namelist = NULL; 632*0ba2cbe9Sxc151355 633*0ba2cbe9Sxc151355 return (SECOBJ_RW_DB(&state, B_FALSE)); 634*0ba2cbe9Sxc151355 } 635