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.
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.
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]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
29 #include <bsm/devices.h>
30 #include <bsm/devalloc.h>
32 extern char *_strdup_null(char *);
34 static struct _dabuff
{
35 FILE *_daf
; /* pointer into /etc/security/device_allocate */
36 devalloc_t _interpdevalloc
;
37 char _interpdaline
[DA_BUFSIZE
+ 1];
41 #define daf (_da->_daf)
42 #define interpdevalloc (_da->_interpdevalloc)
43 #define interpdaline (_da->_interpdaline)
44 #define DEVALLOC_FILE (_da->_DEVALLOC)
45 static devalloc_t
*da_interpret(char *);
47 int da_matchname(devalloc_t
*, char *);
48 int da_matchtype(devalloc_t
*, char *);
52 * trims off leading and trailing white space from input string.
53 * The leading white space is skipped by moving the pointer forward.
54 * The trailing white space is removed by nulling the white space
56 * returns pointer to non-white string, else returns NULL if input string
57 * is null or if the resulting string has zero length.
68 tptr
= ptr
+ strlen(ptr
);
69 while (tptr
!= ptr
&& isspace(tptr
[-1]))
80 * trims off multiple occurrences of white space from input string.
81 * returns the number of spaces retained
92 while (isspace(*tptr
))
95 while ((ch
= *tptr
) != '\0' && !isspace(ch
)) {
99 while (isspace(*tptr
))
113 * reads one device_alloc/device_maps line from stream into buff of len
114 * bytes. Continued lines from stream are concatenated into one line in
115 * buff. Comments are removed from buff.
116 * returns the number of characters in buff, else returns 0 if no
117 * characters are read or an error occurred.
120 getdadmline(char *buff
, int len
, FILE *stream
)
134 if (fgets(cp
, len
- charcnt
, stream
) == NULL
) {
138 ccp
= strchr(cp
, '\n');
140 if (ccp
!= cp
&& ccp
[-1] == '\\') {
151 } while ((contline
) || (charcnt
== 0));
152 ccp
= strpbrk(buff
, "#");
155 charcnt
= strlen(buff
);
156 } while ((fileerr
== 0) && (charcnt
== 0));
158 if (fileerr
&& !charcnt
)
166 * allocates common buffers and structures.
167 * returns pointer to the new structure, else returns NULL on error.
169 static struct _dabuff
*
172 struct _dabuff
*_da
= __dabuff
;
175 _da
= (struct _dabuff
*)calloc((unsigned)1,
176 (unsigned)sizeof (*__dabuff
));
179 DEVALLOC_FILE
= "/etc/security/device_allocate";
189 * gets individual fields separated by skip in ptr.
192 getdadmfield(char *ptr
, char *skip
)
194 static char *tptr
= NULL
;
197 /* check for a continuing search */
200 /* check for source end */
201 if (ptr
== NULL
|| *ptr
== '\0')
203 /* find terminator */
204 pend
= strpbrk(ptr
, skip
);
205 /* terminate and set continuation pointer */
212 * trim off any surrounding white space, return what's left
215 return (trim_white(ptr
));
220 * rewinds the device_allocate file to the begining.
226 struct _dabuff
*_da
= _daalloc();
231 daf
= fopen(DEVALLOC_FILE
, "rF");
238 * closes device_allocate file.
244 struct _dabuff
*_da
= _daalloc();
256 * changes the default device_allocate file to the one specified.
257 * It does not close the previous file. If this is desired, enddaent
258 * should be called prior to setdafile.
261 setdafile(char *file
)
263 struct _dabuff
*_da
= _daalloc();
271 DEVALLOC_FILE
= file
;
275 freedaent(devalloc_t
*dap
)
279 _kva_free(dap
->da_devopts
);
280 dap
->da_devopts
= NULL
;
285 * checks if device_allocate has string DEVICE_ALLOCATION=ON or
286 * DEVICE_ALLOCATION=OFF string in it.
287 * returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is
288 * DEVICE_ALLOCATION=OFF, -1 if neither string present.
294 char line1
[DA_BUFSIZE
+ 1];
295 struct _dabuff
*_da
= _daalloc();
298 if ((_da
== NULL
) || (daf
== NULL
)) {
302 while (getdadmline(line1
, (int)sizeof (line1
), daf
) != 0) {
303 if (strncmp(line1
, DA_ON_STR
, (strlen(DA_ON_STR
) - 1)) == 0) {
306 } else if (strncmp(line1
, DA_OFF_STR
,
307 (strlen(DA_OFF_STR
) - 1)) == 0) {
319 * When first called, returns a pointer to the first devalloc_t
320 * structure in device_allocate; thereafter, it returns a pointer to the
321 * next devalloc_t structure in the file. Thus, successive calls can be
322 * used to search the entire file.
323 * call to getdaent should be bracketed by setdaent and enddaent.
324 * returns NULL on error.
329 char line1
[DA_BUFSIZE
+ 1];
331 struct _dabuff
*_da
= _daalloc();
333 if ((_da
== 0) || (daf
== NULL
))
336 while (getdadmline(line1
, (int)sizeof (line1
), daf
) != 0) {
337 if ((strncmp(line1
, DA_ON_STR
, (strlen(DA_ON_STR
) - 1)) == 0) ||
338 (strncmp(line1
, DA_OFF_STR
, (strlen(DA_OFF_STR
) - 1)) == 0))
340 if ((da
= da_interpret(line1
)) == NULL
)
350 * searches from the beginning of device_allocate for the device specified
352 * call to getdanam should be bracketed by setdaent and enddaent.
353 * returns pointer to devalloc_t for the device if it is found, else
354 * returns NULL if device not found or in case of error.
359 char line
[DA_BUFSIZE
+ 1];
361 struct _dabuff
*_da
= _daalloc();
363 if ((name
== NULL
) || (_da
== 0) || (daf
== NULL
))
366 while (getdadmline(line
, (int)sizeof (line
), daf
) != 0) {
367 if (strstr(line
, name
) == NULL
)
369 if ((da
= da_interpret(line
)) == NULL
)
371 if (da_matchname(da
, name
)) {
383 * searches from the beginning of device_allocate for the device specified
385 * call to getdatype should be bracketed by setdaent and enddaent.
386 * returns pointer to devalloc_t for the device if it is found, else
387 * returns NULL if device not found or in case of error.
390 getdatype(char *type
)
392 char line1
[DA_BUFSIZE
+ 1];
394 struct _dabuff
*_da
= _daalloc();
396 if ((type
== NULL
) || (_da
== NULL
) || (daf
== NULL
))
399 while (getdadmline(line1
, (int)sizeof (line1
), daf
) != 0) {
400 if (strstr(line1
, type
) == NULL
)
402 if ((da
= da_interpret(line1
)) == NULL
)
404 if (da_matchtype(da
, type
))
414 * checks if the specified devalloc_t is for the device specified.
415 * returns 1 if it is, else returns 0.
418 da_matchname(devalloc_t
*dap
, char *name
)
420 if (dap
->da_devname
== NULL
)
423 return ((strcmp(dap
->da_devname
, name
) == 0));
428 * checks if the specified devalloc_t is for the device type specified.
429 * returns 1 if match found, else, returns 0.
432 da_matchtype(devalloc_t
*da
, char *type
)
434 if (da
->da_devtype
== NULL
)
437 return ((strcmp(da
->da_devtype
, type
) == 0));
442 * calls da_matchname or da_matchdev as appropriate.
445 da_match(devalloc_t
*dap
, da_args
*dargs
)
447 if (dargs
->devinfo
->devname
)
448 return (da_matchname(dap
, dargs
->devinfo
->devname
));
449 else if (dargs
->devinfo
->devtype
)
450 return (da_matchtype(dap
, dargs
->devinfo
->devtype
));
457 * parses val and initializes pointers in devalloc_t.
458 * returns pointer to parsed devalloc_t entry, else returns NULL on error.
461 da_interpret(char *val
)
463 struct _dabuff
*_da
= _daalloc();
472 (void) strcpy(interpdaline
, val
);
473 interpdevalloc
.da_devname
= getdadmfield(interpdaline
, KV_DELIMITER
);
474 interpdevalloc
.da_devtype
= getdadmfield(NULL
, KV_DELIMITER
);
475 opts
= getdadmfield(NULL
, KV_DELIMITER
);
476 (void) getdadmfield(NULL
, KV_DELIMITER
); /* reserved field */
477 interpdevalloc
.da_devauth
= getdadmfield(NULL
, KV_DELIMITER
);
478 interpdevalloc
.da_devexec
= getdadmfield(NULL
, KV_DELIMITER
);
479 interpdevalloc
.da_devopts
= NULL
;
480 if (interpdevalloc
.da_devname
== NULL
||
481 interpdevalloc
.da_devtype
== NULL
)
483 if ((opts
!= NULL
) &&
484 (strncmp(opts
, DA_RESERVED
, strlen(DA_RESERVED
)) != 0)) {
485 interpdevalloc
.da_devopts
=
486 _str2kva(opts
, KV_ASSIGN
, KV_TOKEN_DELIMIT
);
488 /* remove any extraneous whitespace in the options */
489 if ((kvap
= interpdevalloc
.da_devopts
) != NULL
) {
490 for (i
= 0, kvp
= kvap
->data
; i
< kvap
->length
; i
++, kvp
++) {
491 (void) pack_white(kvp
->key
);
492 (void) pack_white(kvp
->value
);
496 return (&interpdevalloc
);