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