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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <arpa/inet.h>
36 #include <net/if_dl.h>
37 #include <netinet/in.h>
43 #include <sys/socket.h>
44 #include <sys/types.h>
47 #include "libnwam_impl.h"
48 #include <libnwam_priv.h>
52 * Utility functions for door access, common validation functions etc.
55 pthread_mutex_t door_mutex
= PTHREAD_MUTEX_INITIALIZER
;
56 int nwam_door_fd
= -1;
59 open_door(const char *door_name
, int *door_fdp
)
61 struct door_info dinfo
;
64 (void) pthread_mutex_lock(&door_mutex
);
66 if (*door_fdp
!= -1) {
67 /* Check door fd is not old (from previous nwamd). */
68 if (door_info(*door_fdp
, &dinfo
) != 0 ||
69 (dinfo
.di_attributes
& DOOR_REVOKED
) != 0) {
70 (void) close(*door_fdp
);
74 if (*door_fdp
== -1) {
75 *door_fdp
= open(door_name
, 0);
80 (void) pthread_mutex_unlock(&door_mutex
);
86 nwam_make_door_call(const char *door_name
, int *door_fdp
,
87 void *request
, size_t request_size
)
92 door_args
.data_ptr
= (void *)request
;
93 door_args
.data_size
= request_size
;
94 door_args
.desc_ptr
= NULL
;
95 door_args
.desc_num
= 0;
96 door_args
.rbuf
= (void *)request
;
97 door_args
.rsize
= request_size
;
99 if ((err
= open_door(door_name
, door_fdp
)) != 0)
102 if (door_call(*door_fdp
, &door_args
) == -1)
109 send_msg_to_nwam(nwamd_door_arg_t
*request
)
113 if ((err
= nwam_make_door_call(NWAM_DOOR
, &nwam_door_fd
,
114 request
, sizeof (nwamd_door_arg_t
))) != 0) {
116 return (NWAM_ERROR_BIND
);
117 return (nwam_errno_to_nwam_error(err
));
120 switch (request
->nwda_status
) {
121 case NWAM_REQUEST_STATUS_OK
:
122 return (NWAM_SUCCESS
);
123 case NWAM_REQUEST_STATUS_UNKNOWN
:
124 return (NWAM_INVALID_ARG
);
125 case NWAM_REQUEST_STATUS_ALREADY
:
126 return (NWAM_ENTITY_IN_USE
);
127 case NWAM_REQUEST_STATUS_FAILED
:
128 return (request
->nwda_error
);
130 return (NWAM_ERROR_INTERNAL
);
135 nwam_request_register_unregister(nwam_request_type_t type
,
136 const char *event_msg_file
)
138 nwamd_door_arg_t req
;
140 req
.nwda_type
= type
;
142 (void) strlcpy(req
.nwda_data
.nwdad_register_info
.nwdad_name
,
144 sizeof (req
.nwda_data
.nwdad_register_info
.nwdad_name
));
146 return (send_msg_to_nwam(&req
));
150 nwam_request_action(nwam_object_type_t object_type
,
151 const char *name
, const char *parent
, nwam_action_t action
)
153 nwamd_door_arg_t req
;
155 assert(name
!= NULL
);
157 req
.nwda_type
= NWAM_REQUEST_TYPE_ACTION
;
158 req
.nwda_data
.nwdad_object_action
.nwdad_object_type
= object_type
;
159 req
.nwda_data
.nwdad_object_action
.nwdad_action
= action
;
160 (void) strlcpy(req
.nwda_data
.nwdad_object_action
.nwdad_name
, name
,
161 sizeof (req
.nwda_data
.nwdad_object_action
.nwdad_name
));
162 if (parent
!= NULL
) {
163 (void) strlcpy(req
.nwda_data
.nwdad_object_action
.nwdad_parent
,
165 sizeof (req
.nwda_data
.nwdad_object_action
.nwdad_parent
));
167 req
.nwda_data
.nwdad_object_action
.nwdad_parent
[0] = '\0';
170 return (send_msg_to_nwam(&req
));
174 nwam_request_state(nwam_object_type_t object_type
, const char *name
,
175 const char *parent
, nwam_state_t
*statep
, nwam_aux_state_t
*auxp
)
177 nwamd_door_arg_t req
;
180 assert(name
!= NULL
&& statep
!= NULL
&& auxp
!= NULL
);
182 req
.nwda_type
= NWAM_REQUEST_TYPE_STATE
;
184 req
.nwda_data
.nwdad_object_state
.nwdad_object_type
= object_type
;
186 (void) strlcpy(req
.nwda_data
.nwdad_object_state
.nwdad_name
, name
,
187 sizeof (req
.nwda_data
.nwdad_object_state
.nwdad_name
));
188 if (parent
!= NULL
) {
189 (void) strlcpy(req
.nwda_data
.nwdad_object_state
.nwdad_parent
,
191 sizeof (req
.nwda_data
.nwdad_object_state
.nwdad_parent
));
194 err
= send_msg_to_nwam(&req
);
196 if (err
== NWAM_SUCCESS
) {
197 *statep
= req
.nwda_data
.nwdad_object_state
.nwdad_state
;
198 *auxp
= req
.nwda_data
.nwdad_object_state
.nwdad_aux_state
;
205 nwam_request_wlan(nwam_request_type_t type
, const char *name
,
206 const char *essid
, const char *bssid
, uint32_t security_mode
,
207 uint_t keyslot
, const char *key
, boolean_t add_to_known_wlans
)
209 nwamd_door_arg_t req
;
211 assert(name
!= NULL
);
213 req
.nwda_type
= type
;
215 (void) strlcpy(req
.nwda_data
.nwdad_wlan_info
.nwdad_name
, name
,
216 sizeof (req
.nwda_data
.nwdad_wlan_info
));
218 (void) strlcpy(req
.nwda_data
.nwdad_wlan_info
.nwdad_essid
, essid
,
219 sizeof (req
.nwda_data
.nwdad_wlan_info
.nwdad_essid
));
221 req
.nwda_data
.nwdad_wlan_info
.nwdad_essid
[0] = '\0';
224 (void) strlcpy(req
.nwda_data
.nwdad_wlan_info
.nwdad_bssid
, bssid
,
225 sizeof (req
.nwda_data
.nwdad_wlan_info
.nwdad_bssid
));
227 req
.nwda_data
.nwdad_wlan_info
.nwdad_bssid
[0] = '\0';
230 (void) strlcpy(req
.nwda_data
.nwdad_wlan_info
.nwdad_key
, key
,
231 sizeof (req
.nwda_data
.nwdad_wlan_info
.nwdad_key
));
232 req
.nwda_data
.nwdad_wlan_info
.nwdad_keyslot
= keyslot
;
234 req
.nwda_data
.nwdad_wlan_info
.nwdad_key
[0] = '\0';
237 req
.nwda_data
.nwdad_wlan_info
.nwdad_security_mode
= security_mode
;
238 req
.nwda_data
.nwdad_wlan_info
.nwdad_add_to_known_wlans
=
241 return (send_msg_to_nwam(&req
));
245 nwam_request_wlan_scan_results(const char *name
, uint_t
*num_wlansp
,
246 nwam_wlan_t
**wlansp
)
248 nwamd_door_arg_t req
;
251 assert(name
!= NULL
&& num_wlansp
!= NULL
&& wlansp
!= NULL
);
253 req
.nwda_type
= NWAM_REQUEST_TYPE_WLAN_SCAN_RESULTS
;
255 (void) strlcpy(req
.nwda_data
.nwdad_wlan_info
.nwdad_name
, name
,
256 sizeof (req
.nwda_data
.nwdad_wlan_info
.nwdad_name
));
258 if ((err
= send_msg_to_nwam(&req
)) != NWAM_SUCCESS
)
261 *num_wlansp
= req
.nwda_data
.nwdad_wlan_info
.nwdad_num_wlans
;
263 *wlansp
= calloc(*num_wlansp
, sizeof (nwam_wlan_t
));
265 return (NWAM_NO_MEMORY
);
267 (void) memcpy(*wlansp
, req
.nwda_data
.nwdad_wlan_info
.nwdad_wlans
,
268 *num_wlansp
* sizeof (nwam_wlan_t
));
270 return (NWAM_SUCCESS
);
274 nwam_request_active_priority_group(int64_t *priorityp
)
276 nwamd_door_arg_t req
;
279 assert(priorityp
!= NULL
);
281 req
.nwda_type
= NWAM_REQUEST_TYPE_PRIORITY_GROUP
;
282 err
= send_msg_to_nwam(&req
);
284 if (err
== NWAM_SUCCESS
)
286 req
.nwda_data
.nwdad_priority_group_info
.nwdad_priority
;
291 /* String conversion functions */
294 nwam_value_type_to_string(nwam_value_type_t type
)
297 case NWAM_VALUE_TYPE_BOOLEAN
:
299 case NWAM_VALUE_TYPE_INT64
:
301 case NWAM_VALUE_TYPE_UINT64
:
303 case NWAM_VALUE_TYPE_STRING
:
311 nwam_string_to_value_type(const char *typestr
)
313 if (strncmp(typestr
, nwam_value_type_to_string(NWAM_VALUE_TYPE_BOOLEAN
),
314 strlen(typestr
)) == 0)
315 return (NWAM_VALUE_TYPE_BOOLEAN
);
316 if (strncmp(typestr
, nwam_value_type_to_string(NWAM_VALUE_TYPE_INT64
),
317 strlen(typestr
)) == 0)
318 return (NWAM_VALUE_TYPE_INT64
);
319 if (strncmp(typestr
, nwam_value_type_to_string(NWAM_VALUE_TYPE_UINT64
),
320 strlen(typestr
)) == 0)
321 return (NWAM_VALUE_TYPE_UINT64
);
322 if (strncmp(typestr
, nwam_value_type_to_string(NWAM_VALUE_TYPE_STRING
),
323 strlen(typestr
)) == 0)
324 return (NWAM_VALUE_TYPE_STRING
);
325 return (NWAM_VALUE_TYPE_UNKNOWN
);
329 nwam_action_to_string(nwam_action_t action
)
332 case NWAM_ACTION_ADD
:
334 case NWAM_ACTION_REMOVE
:
336 case NWAM_ACTION_REFRESH
:
338 case NWAM_ACTION_ENABLE
:
340 case NWAM_ACTION_DISABLE
:
342 case NWAM_ACTION_DESTROY
:
350 nwam_event_type_to_string(int event_type
)
352 switch (event_type
) {
353 case NWAM_EVENT_TYPE_NOOP
:
355 case NWAM_EVENT_TYPE_INIT
:
357 case NWAM_EVENT_TYPE_SHUTDOWN
:
359 case NWAM_EVENT_TYPE_OBJECT_ACTION
:
360 return ("OBJECT_ACTION");
361 case NWAM_EVENT_TYPE_OBJECT_STATE
:
362 return ("OBJECT_STATE");
363 case NWAM_EVENT_TYPE_PRIORITY_GROUP
:
364 return ("PRIORITY_GROUP");
365 case NWAM_EVENT_TYPE_INFO
:
367 case NWAM_EVENT_TYPE_WLAN_SCAN_REPORT
:
368 return ("WLAN_SCAN_REPORT");
369 case NWAM_EVENT_TYPE_WLAN_NEED_CHOICE
:
370 return ("WLAN_NEED_CHOICE");
371 case NWAM_EVENT_TYPE_WLAN_NEED_KEY
:
372 return ("WLAN_NEED_KEY");
373 case NWAM_EVENT_TYPE_WLAN_CONNECTION_REPORT
:
374 return ("WLAN_CONNECTION_REPORT");
375 case NWAM_EVENT_TYPE_IF_ACTION
:
376 return ("IF_ACTION");
377 case NWAM_EVENT_TYPE_IF_STATE
:
379 case NWAM_EVENT_TYPE_LINK_ACTION
:
380 return ("LINK_ACTION");
381 case NWAM_EVENT_TYPE_LINK_STATE
:
382 return ("LINK_STATE");
389 nwam_state_to_string(nwam_state_t state
)
392 case NWAM_STATE_UNINITIALIZED
:
393 return ("uninitialized");
394 case NWAM_STATE_INITIALIZED
:
395 return ("initialized");
396 case NWAM_STATE_OFFLINE
:
398 case NWAM_STATE_OFFLINE_TO_ONLINE
:
400 case NWAM_STATE_ONLINE_TO_OFFLINE
:
402 case NWAM_STATE_ONLINE
:
404 case NWAM_STATE_MAINTENANCE
:
405 return ("maintenance");
406 case NWAM_STATE_DEGRADED
:
408 case NWAM_STATE_DISABLED
:
416 nwam_aux_state_to_string(nwam_aux_state_t aux_state
)
419 case NWAM_AUX_STATE_UNINITIALIZED
:
420 return ("uninitialized");
421 case NWAM_AUX_STATE_INITIALIZED
:
422 return ("(re)initialized but not configured");
423 case NWAM_AUX_STATE_CONDITIONS_NOT_MET
:
424 return ("conditions for activation are unmet");
425 case NWAM_AUX_STATE_MANUAL_DISABLE
:
426 return ("disabled by administrator");
427 case NWAM_AUX_STATE_METHOD_FAILED
:
428 return ("method/service failed");
429 case NWAM_AUX_STATE_METHOD_MISSING
:
430 return ("method or FMRI not specified");
431 case NWAM_AUX_STATE_INVALID_CONFIG
:
432 return ("invalid configuration values");
433 case NWAM_AUX_STATE_METHOD_RUNNING
:
434 return ("method/service executing");
435 case NWAM_AUX_STATE_ACTIVE
:
437 case NWAM_AUX_STATE_LINK_WIFI_SCANNING
:
438 return ("scanning for WiFi networks");
439 case NWAM_AUX_STATE_LINK_WIFI_NEED_SELECTION
:
440 return ("need WiFi network selection");
441 case NWAM_AUX_STATE_LINK_WIFI_NEED_KEY
:
442 return ("need WiFi security key");
443 case NWAM_AUX_STATE_LINK_WIFI_CONNECTING
:
444 return ("connecting to WiFi network");
445 case NWAM_AUX_STATE_IF_WAITING_FOR_ADDR
:
446 return ("waiting for IP address to be set");
447 case NWAM_AUX_STATE_IF_DHCP_TIMED_OUT
:
448 return ("DHCP wait timeout, still trying...");
449 case NWAM_AUX_STATE_IF_DUPLICATE_ADDR
:
450 return ("duplicate address detected");
451 case NWAM_AUX_STATE_UP
:
452 return ("interface/link is up");
453 case NWAM_AUX_STATE_DOWN
:
454 return ("interface/link is down");
455 case NWAM_AUX_STATE_NOT_FOUND
:
456 return ("interface/link not found");
463 nwam_object_type_to_string(nwam_object_type_t type
)
466 case NWAM_OBJECT_TYPE_NCP
:
468 case NWAM_OBJECT_TYPE_NCU
:
470 case NWAM_OBJECT_TYPE_LOC
:
472 case NWAM_OBJECT_TYPE_ENM
:
474 case NWAM_OBJECT_TYPE_KNOWN_WLAN
:
475 return ("known wlan");
482 nwam_string_to_object_type(const char *typestr
)
484 if (strcasecmp(typestr
,
485 nwam_object_type_to_string(NWAM_OBJECT_TYPE_NCP
)) == 0)
486 return (NWAM_OBJECT_TYPE_NCP
);
487 if (strcasecmp(typestr
,
488 nwam_object_type_to_string(NWAM_OBJECT_TYPE_NCU
)) == 0)
489 return (NWAM_OBJECT_TYPE_NCU
);
490 if (strcasecmp(typestr
,
491 nwam_object_type_to_string(NWAM_OBJECT_TYPE_LOC
)) == 0)
492 return (NWAM_OBJECT_TYPE_LOC
);
493 if (strcasecmp(typestr
,
494 nwam_object_type_to_string(NWAM_OBJECT_TYPE_ENM
)) == 0)
495 return (NWAM_OBJECT_TYPE_ENM
);
496 if (strcasecmp(typestr
,
497 nwam_object_type_to_string(NWAM_OBJECT_TYPE_KNOWN_WLAN
)) == 0)
498 return (NWAM_OBJECT_TYPE_KNOWN_WLAN
);
499 return (NWAM_OBJECT_TYPE_UNKNOWN
);
503 nwam_errno_to_nwam_error(int errnum
)
507 return (NWAM_SUCCESS
);
509 return (NWAM_ERROR_BIND
);
512 return (NWAM_PERMISSION_DENIED
);
514 return (NWAM_ENTITY_NOT_FOUND
);
516 return (NWAM_ENTITY_INVALID
);
518 return (NWAM_ENTITY_EXISTS
);
521 return (NWAM_ENTITY_IN_USE
);
524 return (NWAM_NO_MEMORY
);
527 return (NWAM_INVALID_ARG
);
529 return (NWAM_ERROR_INTERNAL
);
533 /* Common validation functions */
536 * Do the flags represent a subset of valid_flags?
539 nwam_valid_flags(uint64_t flags
, uint64_t valid_flags
)
542 if ((flags
| valid_flags
) != valid_flags
)
543 return (NWAM_INVALID_ARG
);
544 return (NWAM_SUCCESS
);
548 nwam_valid_condition(nwam_value_t value
)
552 nwam_condition_object_type_t object_type
;
553 nwam_condition_t condition
;
555 if (nwam_value_get_string_array(value
, &conditions
, &numvalues
)
557 return (NWAM_ENTITY_INVALID_VALUE
);
559 for (i
= 0; i
< numvalues
; i
++) {
560 char *object_name
= NULL
;
562 if (nwam_condition_string_to_condition(conditions
[i
],
563 &object_type
, &condition
, &object_name
) != NWAM_SUCCESS
)
564 return (NWAM_ENTITY_INVALID_VALUE
);
565 if (object_name
!= NULL
)
568 return (NWAM_SUCCESS
);
571 /* check if boolean values are correct, generalize for array of booleans */
573 nwam_valid_boolean(nwam_value_t value
)
578 if (nwam_value_get_boolean_array(value
, &val
, &numvalues
)
580 return (NWAM_ENTITY_INVALID_VALUE
);
582 for (i
= 0; i
< numvalues
; i
++) {
583 if (val
[i
] != B_TRUE
&& val
[i
] != B_FALSE
)
584 return (NWAM_ENTITY_INVALID_VALUE
);
586 return (NWAM_SUCCESS
);
589 /* check if uint64 values are correct, generalize for array of ints */
591 nwam_valid_uint64(nwam_value_t value
)
596 if (nwam_value_get_int64_array(value
, &val
, &numvalues
)
598 return (NWAM_ENTITY_INVALID_VALUE
);
600 for (i
= 0; i
< numvalues
; i
++) {
602 return (NWAM_ENTITY_INVALID_VALUE
);
604 return (NWAM_SUCCESS
);
607 /* check if domain names are correct, generalize for array of domains */
609 nwam_valid_domain(nwam_value_t value
)
611 char **domainvalues
, *domain
;
615 if (nwam_value_get_string_array(value
, &domainvalues
, &numvalues
)
617 return (NWAM_ENTITY_INVALID_VALUE
);
619 for (i
= 0; i
< numvalues
; i
++) {
621 * First and last character must be alphanumeric.
622 * Only '.' and '-' are allowed.
624 domain
= domainvalues
[i
];
625 len
= strlen(domain
);
626 if (!isalnum(domain
[0]) || !isalnum(domain
[len
-1]))
627 return (NWAM_ENTITY_INVALID_VALUE
);
628 for (j
= 0; j
< len
; j
++) {
629 if (!isalnum(domain
[j
]) &&
630 domain
[j
] != '.' && domain
[j
] != '-')
631 return (NWAM_ENTITY_INVALID_VALUE
);
634 return (NWAM_SUCCESS
);
637 /* check if address prefix is valid */
639 nwam_valid_prefix(char *addr
, int max_plen
)
644 if ((prefix
= strchr(addr
, '/')) != NULL
) {
646 prefixlen
= strtol(prefix
, &end
, 10);
647 if (prefix
== end
|| prefixlen
< 0 || prefixlen
> max_plen
)
648 return (NWAM_ENTITY_INVALID_VALUE
);
650 return (NWAM_SUCCESS
);
653 /* check if IPv4 addresses are correct, generalize for array of addresses */
655 nwam_valid_host_v4(nwam_value_t value
)
657 char **addrvalues
, *addr
;
659 struct sockaddr_in sa
;
661 if (nwam_value_get_string_array(value
, &addrvalues
, &numvalues
)
663 return (NWAM_ENTITY_INVALID_VALUE
);
665 for (i
= 0; i
< numvalues
; i
++) {
666 addr
= strdup(addrvalues
[i
]);
667 if (nwam_valid_prefix(addr
, IP_ABITS
) != NWAM_SUCCESS
) {
669 return (NWAM_ENTITY_INVALID_VALUE
);
671 /* replace '/' with '\0' */
672 addr
= strsep(&addr
, "/");
673 if (inet_pton(AF_INET
, addr
, &(sa
.sin_addr
)) != 1) {
675 return (NWAM_ENTITY_INVALID_VALUE
);
679 return (NWAM_SUCCESS
);
682 /* Check if IPv4 address for default route is valid */
684 nwam_valid_route_v4(nwam_value_t value
)
687 struct sockaddr_in sa
;
689 if (nwam_value_get_string(value
, &addrvalue
) != NWAM_SUCCESS
)
690 return (NWAM_ENTITY_INVALID_VALUE
);
692 if (inet_pton(AF_INET
, addrvalue
, &(sa
.sin_addr
)) != 1)
693 return (NWAM_ENTITY_INVALID_VALUE
);
695 return (NWAM_SUCCESS
);
698 /* check if IPv6 addresses are correct, generalize for array of addresses */
700 nwam_valid_host_v6(nwam_value_t value
)
702 char **addrvalues
, *addr
;
704 struct sockaddr_in6 sa
;
706 if (nwam_value_get_string_array(value
, &addrvalues
, &numvalues
)
708 return (NWAM_ENTITY_INVALID_VALUE
);
710 for (i
= 0; i
< numvalues
; i
++) {
711 addr
= strdup(addrvalues
[i
]);
712 if (nwam_valid_prefix(addr
, IPV6_ABITS
) != NWAM_SUCCESS
) {
714 return (NWAM_ENTITY_INVALID_VALUE
);
716 /* replace '/' with '\0' */
717 addr
= strsep(&addr
, "/");
718 if (inet_pton(AF_INET6
, addr
, &(sa
.sin6_addr
)) != 1) {
720 return (NWAM_ENTITY_INVALID_VALUE
);
724 return (NWAM_SUCCESS
);
727 /* Check if IPv4 address for default route is valid */
729 nwam_valid_route_v6(nwam_value_t value
)
732 struct sockaddr_in6 sa
;
734 if (nwam_value_get_string(value
, &addrvalue
) != NWAM_SUCCESS
)
735 return (NWAM_ENTITY_INVALID_VALUE
);
737 if (inet_pton(AF_INET6
, addrvalue
, &(sa
.sin6_addr
)) != 1)
738 return (NWAM_ENTITY_INVALID_VALUE
);
740 return (NWAM_SUCCESS
);
744 nwam_valid_host_any(nwam_value_t value
)
746 if (nwam_valid_host_v4(value
) != NWAM_SUCCESS
&&
747 nwam_valid_host_v6(value
) != NWAM_SUCCESS
)
748 return (NWAM_ENTITY_INVALID_VALUE
);
749 return (NWAM_SUCCESS
);
753 nwam_valid_host_or_domain(nwam_value_t value
)
755 if (nwam_valid_host_any(value
) != NWAM_SUCCESS
&&
756 nwam_valid_domain(value
) != NWAM_SUCCESS
)
757 return (NWAM_ENTITY_INVALID_VALUE
);
758 return (NWAM_SUCCESS
);
761 /* We do not validate file existence, merely that it is an absolute path. */
763 nwam_valid_file(nwam_value_t value
)
768 if (nwam_value_get_string_array(value
, &files
, &numvalues
)
770 return (NWAM_ENTITY_INVALID_VALUE
);
772 for (i
= 0; i
< numvalues
; i
++) {
774 while (isspace(files
[i
][j
]))
776 if (files
[i
][j
] != '/')
777 return (NWAM_ENTITY_INVALID_VALUE
);
779 return (NWAM_SUCCESS
);
783 * We do not validate existence of the object pointed to by the FMRI
784 * but merely ensure that it is a valid FMRI. We do this by
785 * using scf_handle_decode_fmri(), but ignore all errors bar
786 * SCF_ERROR_INVALID_ARGUMENT (which indicates the FMRI is invalid).
789 nwam_valid_fmri(nwam_value_t value
)
792 scf_handle_t
*h
= NULL
;
793 scf_service_t
*svc
= NULL
;
795 nwam_error_t err
= NWAM_SUCCESS
;
797 if ((err
= nwam_value_get_string_array(value
, &valstr
, &numvalues
))
801 h
= scf_handle_create(SCF_VERSION
);
803 return (NWAM_ERROR_INTERNAL
);
805 if (scf_handle_bind(h
) != 0) {
806 err
= NWAM_ERROR_INTERNAL
;
810 if ((svc
= scf_service_create(h
)) == NULL
) {
811 err
= NWAM_ERROR_INTERNAL
;
816 for (i
= 0; i
< numvalues
; i
++) {
817 if (scf_handle_decode_fmri(h
, valstr
[i
], NULL
, svc
,
818 NULL
, NULL
, NULL
, SCF_DECODE_FMRI_TRUNCATE
) == 0 ||
819 scf_error() != SCF_ERROR_INVALID_ARGUMENT
) {
823 err
= NWAM_ENTITY_INVALID_VALUE
;
827 scf_service_destroy(svc
);
828 scf_handle_destroy(h
);
832 /* verifies mac-address and bssids */
834 nwam_valid_mac_addr(nwam_value_t value
)
836 char **mac_addrs
, *addr
;
841 if (nwam_value_get_string_array(value
, &mac_addrs
, &numvalues
)
843 return (NWAM_ENTITY_INVALID_VALUE
);
845 for (i
= 0; i
< numvalues
; i
++) {
849 /* validate that a-fA-F0-9 and ':' only */
850 while (addr
[j
] != 0) {
851 if (!isxdigit(addr
[j
]) && addr
[j
] != ':')
852 return (NWAM_ENTITY_INVALID_VALUE
);
856 if ((hwaddr
= _link_aton(addr
, &hwaddrlen
)) == NULL
)
857 return (NWAM_ENTITY_INVALID_VALUE
);
861 return (NWAM_SUCCESS
);
865 nwam_uid_is_special(void)
867 uid_t uid
= getuid();
868 return (uid
== UID_NETADM
|| uid
== 0);
872 nwam_get_smf_string_property(const char *fmri
, const char *pgname
,
873 const char *propname
, char **valuep
)
875 scf_handle_t
*h
= NULL
;
876 scf_snapshot_t
*snap
= NULL
;
877 scf_instance_t
*inst
= NULL
;
878 scf_propertygroup_t
*pg
= NULL
;
879 scf_property_t
*prop
= NULL
;
880 scf_value_t
*val
= NULL
;
881 nwam_error_t err
= NWAM_SUCCESS
;
883 if ((*valuep
= malloc(NWAM_MAX_NAME_LEN
)) == NULL
)
884 return (NWAM_NO_MEMORY
);
886 if ((h
= scf_handle_create(SCF_VERSION
)) == NULL
||
887 scf_handle_bind(h
) != 0 ||
888 (inst
= scf_instance_create(h
)) == NULL
||
889 (snap
= scf_snapshot_create(h
)) == NULL
||
890 (pg
= scf_pg_create(h
)) == NULL
||
891 (prop
= scf_property_create(h
)) == NULL
||
892 (val
= scf_value_create(h
)) == NULL
) {
893 err
= NWAM_ERROR_INTERNAL
;
896 if (scf_handle_decode_fmri(h
, fmri
, NULL
, NULL
, inst
,
897 NULL
, NULL
, SCF_DECODE_FMRI_REQUIRE_INSTANCE
) != 0) {
898 err
= NWAM_ENTITY_NOT_FOUND
;
901 /* Retrieve value from running snapshot (if present) */
902 if (scf_instance_get_snapshot(inst
, "running", snap
) != 0) {
903 scf_snapshot_destroy(snap
);
906 if (scf_instance_get_pg_composed(inst
, snap
, pgname
, pg
) != 0 ||
907 scf_pg_get_property(pg
, propname
, prop
) != 0 ||
908 scf_property_get_value(prop
, val
) != 0 ||
909 scf_value_get_astring(val
, *valuep
, NWAM_MAX_NAME_LEN
) == -1) {
910 err
= NWAM_ENTITY_NOT_FOUND
;
913 if (err
!= NWAM_SUCCESS
)
916 scf_value_destroy(val
);
917 scf_property_destroy(prop
);
920 scf_snapshot_destroy(snap
);
921 scf_instance_destroy(inst
);
922 scf_handle_destroy(h
);
928 nwam_set_smf_string_property(const char *fmri
, const char *pgname
,
929 const char *propname
, const char *propval
)
931 scf_handle_t
*h
= NULL
;
932 scf_instance_t
*inst
= NULL
;
933 scf_propertygroup_t
*pg
= NULL
;
934 scf_property_t
*prop
= NULL
;
935 scf_value_t
*val
= NULL
;
936 scf_transaction_t
*tx
= NULL
;
937 scf_transaction_entry_t
*ent
= NULL
;
938 nwam_error_t err
= NWAM_SUCCESS
;
941 if ((h
= scf_handle_create(SCF_VERSION
)) == NULL
||
942 scf_handle_bind(h
) != 0 ||
943 (inst
= scf_instance_create(h
)) == NULL
||
944 (pg
= scf_pg_create(h
)) == NULL
||
945 (prop
= scf_property_create(h
)) == NULL
||
946 (val
= scf_value_create(h
)) == NULL
||
947 scf_value_set_astring(val
, propval
) != 0 ||
948 (tx
= scf_transaction_create(h
)) == NULL
||
949 (ent
= scf_entry_create(h
)) == NULL
) {
950 err
= NWAM_ERROR_INTERNAL
;
953 if (scf_handle_decode_fmri(h
, fmri
, NULL
, NULL
, inst
,
954 NULL
, NULL
, SCF_DECODE_FMRI_REQUIRE_INSTANCE
) != 0 ||
955 scf_instance_get_pg_composed(inst
, NULL
, pgname
, pg
) != 0) {
956 err
= NWAM_ENTITY_NOT_FOUND
;
961 if (scf_transaction_start(tx
, pg
) == -1 ||
962 scf_transaction_property_change(tx
, ent
, propname
, SCF_TYPE_ASTRING
)
963 == -1 || scf_entry_add_value(ent
, val
) != 0) {
964 err
= NWAM_ERROR_INTERNAL
;
968 result
= scf_transaction_commit(tx
);
971 (void) smf_refresh_instance(fmri
);
974 scf_transaction_reset(tx
);
975 if (scf_pg_update(pg
) == -1) {
976 err
= NWAM_ERROR_INTERNAL
;
981 err
= NWAM_ERROR_INTERNAL
;
985 scf_value_destroy(val
);
986 scf_property_destroy(prop
);
988 scf_instance_destroy(inst
);
989 scf_handle_destroy(h
);