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