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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
28 #include <sys/param.h>
29 #include <sys/types.h>
37 #include "libnwam_impl.h"
38 #include <libnwam_priv.h>
42 * Functions to support creating, modifying, destroying, querying the
43 * state of and changing the state of location objects. Locations
44 * represent the configuration to be applied once basic network configuration
45 * has been established - name services, IPsec config, etc, and can be enabled
46 * either manually or conditionally for a combination of the set of
47 * available conditions (an IP address is present, an ENM is active etc).
50 #define NSSWITCH_PREFIX "/etc/nsswitch."
52 typedef nwam_error_t (*nwam_loc_prop_validate_func_t
)(nwam_value_t
);
54 static nwam_error_t
valid_loc_activation_mode(nwam_value_t
);
55 static nwam_error_t
valid_loc_condition(nwam_value_t
);
56 static nwam_error_t
valid_nameservices(nwam_value_t
);
57 static nwam_error_t
valid_configsrc(nwam_value_t
);
59 struct nwam_prop_table_entry loc_prop_table_entries
[] = {
60 {NWAM_LOC_PROP_ACTIVATION_MODE
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1, 1,
61 valid_loc_activation_mode
,
62 "specifies the location activation mode - valid values are:\n"
63 "\'manual\', \'conditional-any\' and \'conditional-all\'",
64 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
65 {NWAM_LOC_PROP_CONDITIONS
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
66 NWAM_MAX_NUM_VALUES
, valid_loc_condition
,
67 "specifies the activation condition. Conditions are of the form:\n"
68 "ncp|ncu|enm name is|is-not active\n"
69 "ip-address is|is-not|is-in-range|is-not-in-range| 1.2.3.4[/24]\n"
70 "advertised-domain is|is-not|contains|does-not-contain string\n"
71 "system-domain is|is-not|contains|does-not-contain string\n"
72 "essid is|is-not|contains|does-not-contain string\n"
73 "bssid is|is-not string",
74 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
75 {NWAM_LOC_PROP_ENABLED
, NWAM_VALUE_TYPE_BOOLEAN
, B_TRUE
, 1, 1,
77 "specifies if location is to be enabled",
78 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
79 {NWAM_LOC_PROP_NAMESERVICES
, NWAM_VALUE_TYPE_UINT64
, B_FALSE
, 1,
80 NWAM_MAX_NUM_VALUES
, valid_nameservices
,
81 "specifies name service(s) to be used - valid values are:\n"
82 "\'files\', \'dns\', \'nis\', and \'ldap\'",
83 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
84 {NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
,
85 B_FALSE
, 0, 1, nwam_valid_file
,
86 "specifies path to configuration file for name services switch "
87 "for this location - see nsswitch.conf(4)",
88 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
89 {NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
, NWAM_VALUE_TYPE_UINT64
,
90 B_FALSE
, 0, NWAM_MAX_NUM_VALUES
, valid_configsrc
,
91 "specifies sources of DNS configuration parameters - valid values "
92 "are:\n\'dhcp\', or \'manual\'",
93 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
94 {NWAM_LOC_PROP_DNS_NAMESERVICE_DOMAIN
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
95 0, 1, nwam_valid_domain
,
96 "specifies DNS domain name to be set for this location",
97 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
98 {NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
99 0, NWAM_MAX_NUM_VALUES
, nwam_valid_host_any
,
100 "specifies DNS server host address(es)",
101 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
102 {NWAM_LOC_PROP_DNS_NAMESERVICE_SEARCH
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
103 0, NWAM_MAX_NUM_VALUES
, nwam_valid_domain
,
104 "specifies DNS search list for host name lookup",
105 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
106 {NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
, NWAM_VALUE_TYPE_UINT64
,
107 B_FALSE
, 0, NWAM_MAX_NUM_VALUES
, valid_configsrc
,
108 "specifies sources of NIS configuration parameters - valid values "
109 "are:\n\'dhcp\', or \'manual\'",
110 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
111 {NWAM_LOC_PROP_NIS_NAMESERVICE_SERVERS
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
112 0, NWAM_MAX_NUM_VALUES
, nwam_valid_host_any
,
113 "specifies NIS server host address(es)",
114 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
115 {NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
, NWAM_VALUE_TYPE_UINT64
,
116 B_FALSE
, 0, NWAM_MAX_NUM_VALUES
, valid_configsrc
,
117 "specifies sources of NIS configuration parameters - currently, "
118 "the only valid value is \'manual\'",
119 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
120 {NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
, NWAM_VALUE_TYPE_STRING
,
121 B_FALSE
, 0, NWAM_MAX_NUM_VALUES
, nwam_valid_host_or_domain
,
122 "specifies LDAP server host address(es)",
123 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
124 {NWAM_LOC_PROP_DEFAULT_DOMAIN
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
126 "specifies the domainname(1M) to be set for this location",
127 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
128 {NWAM_LOC_PROP_NFSV4_DOMAIN
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
130 "specifies an NFSv4 domain for this location",
131 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
132 {NWAM_LOC_PROP_IPFILTER_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
,
133 0, 1, nwam_valid_file
,
134 "specifies an absolute path to an ipf.conf(4) file for this "
136 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
137 {NWAM_LOC_PROP_IPFILTER_V6_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
,
138 B_FALSE
, 0, 1, nwam_valid_file
,
139 "specifies an absolute path to an ipf6.conf file for this "
141 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
142 {NWAM_LOC_PROP_IPNAT_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
144 "specifies an absolute path to an ipnat.conf(4) file for this "
146 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
147 {NWAM_LOC_PROP_IPPOOL_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0,
149 "specifies an absolute path to an ippool.conf(4) file for this "
151 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
152 {NWAM_LOC_PROP_IKE_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
, B_FALSE
, 0, 1,
154 "specifies an absolute path to an ike config file "
155 "(see ike.config(4))",
156 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
157 {NWAM_LOC_PROP_IPSECPOLICY_CONFIG_FILE
, NWAM_VALUE_TYPE_STRING
,
158 B_FALSE
, 0, 1, nwam_valid_file
,
159 "specifies an absolute path to an IPsec policy configuration file "
160 "(see ipsecconf(1M)",
161 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
},
164 #define NWAM_NUM_LOC_PROPS (sizeof (loc_prop_table_entries) / \
165 sizeof (*loc_prop_table_entries))
167 struct nwam_prop_table loc_prop_table
=
168 { NWAM_NUM_LOC_PROPS
, loc_prop_table_entries
};
171 nwam_loc_activation_to_flag(nwam_activation_mode_t activation
)
173 switch (activation
) {
174 case NWAM_ACTIVATION_MODE_MANUAL
:
175 return (NWAM_FLAG_ACTIVATION_MODE_MANUAL
);
176 case NWAM_ACTIVATION_MODE_SYSTEM
:
177 return (NWAM_FLAG_ACTIVATION_MODE_SYSTEM
);
178 case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
:
179 return (NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL_ANY
);
180 case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
:
181 return (NWAM_FLAG_ACTIVATION_MODE_CONDITIONAL_ALL
);
188 nwam_loc_read(const char *name
, uint64_t flags
, nwam_loc_handle_t
*lochp
)
190 return (nwam_read(NWAM_OBJECT_TYPE_LOC
, NWAM_LOC_CONF_FILE
, name
,
195 nwam_loc_create(const char *name
, nwam_loc_handle_t
*lochp
)
198 nwam_value_t val
= NULL
;
199 char *nsswitch
= NULL
;
201 assert(lochp
!= NULL
&& name
!= NULL
);
203 if ((err
= nwam_create(NWAM_OBJECT_TYPE_LOC
, NWAM_LOC_CONF_FILE
, name
,
204 lochp
)) != NWAM_SUCCESS
)
207 /* Create new object list for loc */
208 if ((err
= nwam_alloc_object_list(&((*lochp
)->nwh_data
)))
212 /* NWAM_LOC_PROP_ACTIVATION_MODE is mandatory */
213 if ((err
= nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL
, &val
))
217 if ((err
= nwam_set_prop_value((*lochp
)->nwh_data
,
218 NWAM_LOC_PROP_ACTIVATION_MODE
, val
)) != NWAM_SUCCESS
) {
221 nwam_value_free(val
);
225 * NWAM_LOC_PROP_ENABLED defaults to false.
227 if ((err
= nwam_value_create_boolean(B_FALSE
, &val
)) != NWAM_SUCCESS
)
229 if ((err
= nwam_set_prop_value((*lochp
)->nwh_data
,
230 NWAM_LOC_PROP_ENABLED
, val
)) != NWAM_SUCCESS
)
232 nwam_value_free(val
);
236 * Initialize name service properties: use DNS, configured
237 * via DHCP, with default nsswitch (/etc/nsswitch.dns).
239 if ((err
= nwam_value_create_uint64(NWAM_NAMESERVICES_DNS
, &val
)) !=
242 if ((err
= nwam_set_prop_value((*lochp
)->nwh_data
,
243 NWAM_LOC_PROP_NAMESERVICES
, val
)) != NWAM_SUCCESS
)
245 nwam_value_free(val
);
248 if ((err
= nwam_value_create_uint64(NWAM_CONFIGSRC_DHCP
, &val
)) !=
251 if ((err
= nwam_set_prop_value((*lochp
)->nwh_data
,
252 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
, val
)) != NWAM_SUCCESS
)
254 nwam_value_free(val
);
257 /* concatenate these two strings */
258 nsswitch
= strdup(NSSWITCH_PREFIX NWAM_NAMESERVICES_DNS_STRING
);
259 if (nsswitch
== NULL
) {
260 err
= NWAM_NO_MEMORY
;
263 if ((err
= nwam_value_create_string(nsswitch
, &val
)) != NWAM_SUCCESS
)
265 err
= nwam_set_prop_value((*lochp
)->nwh_data
,
266 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, val
);
271 nwam_value_free(val
);
272 if (err
!= NWAM_SUCCESS
) {
273 nwam_loc_free(*lochp
);
280 nwam_loc_get_name(nwam_loc_handle_t loch
, char **namep
)
282 return (nwam_get_name(loch
, namep
));
286 nwam_loc_set_name(nwam_loc_handle_t loch
, const char *name
)
288 return (nwam_set_name(loch
, name
));
292 nwam_loc_can_set_name(nwam_loc_handle_t loch
)
294 return (!loch
->nwh_committed
);
299 loc_selectcb(struct nwam_handle
*hp
, uint64_t flags
, void *data
)
301 nwam_loc_handle_t loch
= hp
;
303 uint64_t activation
, actflag
, walkfilter
;
304 nwam_value_t activationval
;
306 /* Skip the Legacy location in all cases */
307 if (nwam_loc_get_name(loch
, &locname
) != NWAM_SUCCESS
)
308 return (NWAM_INVALID_ARG
);
309 if (strcmp(locname
, NWAM_LOC_NAME_LEGACY
) == 0) {
311 return (NWAM_INVALID_ARG
);
316 * Get a bitmapped flag value corresponding to this loc's
319 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
320 &activationval
) != NWAM_SUCCESS
) {
321 return (NWAM_INVALID_ARG
);
323 if (nwam_value_get_uint64(activationval
, &activation
) != NWAM_SUCCESS
) {
324 nwam_value_free(activationval
);
325 return (NWAM_INVALID_ARG
);
328 actflag
= nwam_loc_activation_to_flag(activation
);
329 nwam_value_free(activationval
);
330 if ((walkfilter
= (flags
& NWAM_WALK_FILTER_MASK
)) == 0)
331 walkfilter
= NWAM_FLAG_ACTIVATION_MODE_ALL
;
332 if (actflag
& walkfilter
)
333 return (NWAM_SUCCESS
);
334 return (NWAM_INVALID_ARG
);
338 nwam_walk_locs(int(*cb
)(nwam_loc_handle_t
, void *), void *data
, uint64_t flags
,
341 nwam_error_t err
= nwam_valid_flags(flags
,
342 NWAM_FLAG_ACTIVATION_MODE_ALL
| NWAM_FLAG_BLOCKING
);
344 if (err
!= NWAM_SUCCESS
)
347 return (nwam_walk(NWAM_OBJECT_TYPE_LOC
, NWAM_LOC_CONF_FILE
,
348 cb
, data
, flags
, retp
, loc_selectcb
));
352 nwam_loc_free(nwam_loc_handle_t loch
)
358 nwam_loc_delete_prop(nwam_loc_handle_t loch
, const char *propname
)
364 assert(loch
!= NULL
&& propname
!= NULL
);
366 if ((err
= nwam_loc_prop_read_only(propname
, &ro
)) != NWAM_SUCCESS
)
369 return (NWAM_ENTITY_READ_ONLY
);
372 * Duplicate data, remove property and validate. If validation
373 * fails, revert to data duplicated prior to remove.
375 if ((err
= nwam_dup_object_list(loch
->nwh_data
, &olddata
))
378 if ((err
= nwam_delete_prop(loch
->nwh_data
, propname
))
380 nwam_free_object_list(loch
->nwh_data
);
381 loch
->nwh_data
= olddata
;
384 if ((err
= nwam_loc_validate(loch
, NULL
)) != NWAM_SUCCESS
) {
385 nwam_free_object_list(loch
->nwh_data
);
386 loch
->nwh_data
= olddata
;
389 nwam_free_object_list(olddata
);
391 return (NWAM_SUCCESS
);
395 nwam_loc_set_prop_value(nwam_loc_handle_t loch
, const char *propname
,
401 assert(loch
!= NULL
&& propname
!= NULL
&& value
!= NULL
);
403 if ((err
= nwam_loc_validate_prop(loch
, propname
, value
))
405 (err
= nwam_loc_prop_read_only(propname
, &ro
)) != NWAM_SUCCESS
)
408 return (NWAM_ENTITY_READ_ONLY
);
410 return (nwam_set_prop_value(loch
->nwh_data
, propname
, value
));
414 nwam_loc_get_prop_value(nwam_loc_handle_t loch
, const char *propname
,
415 nwam_value_t
*valuep
)
417 return (nwam_get_prop_value(loch
->nwh_data
, propname
, valuep
));
421 nwam_loc_walk_props(nwam_loc_handle_t loch
,
422 int (*cb
)(const char *, nwam_value_t
, void *),
423 void *data
, uint64_t flags
, int *retp
)
425 return (nwam_walk_props(loch
, cb
, data
, flags
, retp
));
429 nwam_loc_commit(nwam_loc_handle_t loch
, uint64_t flags
)
433 assert(loch
!= NULL
&& loch
->nwh_data
!= NULL
);
435 if ((err
= nwam_loc_validate(loch
, NULL
)) != NWAM_SUCCESS
)
438 return (nwam_commit(NWAM_LOC_CONF_FILE
, loch
, flags
));
442 nwam_loc_destroy(nwam_loc_handle_t loch
, uint64_t flags
)
449 * Automatic and NoNet are not destroyable and Legacy is
450 * destroyable by netadm only. These have system activation-mode.
452 if ((err
= nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
453 &actval
)) != NWAM_SUCCESS
)
455 err
= nwam_value_get_uint64(actval
, &activation
);
456 nwam_value_free(actval
);
457 if (err
!= NWAM_SUCCESS
)
460 if (activation
== NWAM_ACTIVATION_MODE_SYSTEM
) {
461 if (strcmp(loch
->nwh_name
, NWAM_LOC_NAME_LEGACY
) == 0) {
462 if (!nwam_uid_is_special())
463 return (NWAM_ENTITY_NOT_DESTROYABLE
);
465 return (NWAM_ENTITY_NOT_DESTROYABLE
);
469 return (nwam_destroy(NWAM_LOC_CONF_FILE
, loch
, flags
));
473 nwam_loc_get_prop_description(const char *propname
, const char **descriptionp
)
475 return (nwam_get_prop_description(loc_prop_table
, propname
,
480 nwam_loc_prop_read_only(const char *propname
, boolean_t
*readp
)
482 return (nwam_prop_read_only(loc_prop_table
, propname
, readp
));
486 valid_loc_activation_mode(nwam_value_t value
)
488 uint64_t activation_mode
;
490 if (nwam_value_get_uint64(value
, &activation_mode
) != NWAM_SUCCESS
)
491 return (NWAM_ENTITY_INVALID_VALUE
);
493 switch (activation_mode
) {
494 case NWAM_ACTIVATION_MODE_MANUAL
:
495 case NWAM_ACTIVATION_MODE_SYSTEM
:
496 case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
:
497 case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
:
498 return (NWAM_SUCCESS
);
500 return (NWAM_ENTITY_INVALID_VALUE
);
504 * Identical to nwam_valid_condition(), except locations cannot specify other
505 * location's activation as a condition, e.g. loc2 cannot specify
506 * "loc1 is active" since only one location is active at a time, and
507 * as a consequence the condition is unsatisfiable.
510 valid_loc_condition(nwam_value_t value
)
514 nwam_condition_object_type_t object_type
;
515 nwam_condition_t condition
;
517 if (nwam_value_get_string_array(value
, &conditions
, &numvalues
)
519 return (NWAM_ENTITY_INVALID_VALUE
);
521 for (i
= 0; i
< numvalues
; i
++) {
522 char *object_name
= NULL
;
524 if (nwam_condition_string_to_condition(conditions
[i
],
525 &object_type
, &condition
, &object_name
) != NWAM_SUCCESS
)
526 return (NWAM_ENTITY_INVALID_VALUE
);
527 if (object_type
== NWAM_CONDITION_OBJECT_TYPE_LOC
&&
528 condition
== NWAM_CONDITION_IS
) {
530 return (NWAM_ENTITY_INVALID_VALUE
);
534 return (NWAM_SUCCESS
);
538 valid_nameservices(nwam_value_t value
)
540 uint64_t *nameservices
;
543 if (nwam_value_get_uint64_array(value
, &nameservices
, &numvalues
)
545 return (NWAM_ENTITY_INVALID_VALUE
);
547 for (i
= 0; i
< numvalues
; i
++) {
548 if (nameservices
[i
] > NWAM_NAMESERVICES_LDAP
)
549 return (NWAM_ENTITY_INVALID_VALUE
);
551 return (NWAM_SUCCESS
);
555 valid_configsrc(nwam_value_t value
)
557 uint64_t *configsrcs
;
560 if (nwam_value_get_uint64_array(value
, &configsrcs
, &numvalues
)
562 return (NWAM_ENTITY_INVALID_VALUE
);
564 for (i
= 0; i
< numvalues
; i
++) {
565 if (configsrcs
[i
] > NWAM_CONFIGSRC_DHCP
)
566 return (NWAM_ENTITY_INVALID_VALUE
);
568 return (NWAM_SUCCESS
);
572 * Validates that the activation-mode is system for Automatic and NoNet
573 * locations, and not system for all other locations.
576 nwam_loc_validate_activation_mode(nwam_loc_handle_t loch
, nwam_value_t actval
)
581 if ((err
= nwam_value_get_uint64(actval
, &activation
)) != NWAM_SUCCESS
)
584 if (NWAM_LOC_NAME_PRE_DEFINED(loch
->nwh_name
)) {
585 if (activation
!= NWAM_ACTIVATION_MODE_SYSTEM
)
586 return (NWAM_ENTITY_INVALID_VALUE
);
588 if (activation
== NWAM_ACTIVATION_MODE_SYSTEM
)
589 return (NWAM_ENTITY_INVALID_VALUE
);
591 return (NWAM_SUCCESS
);
595 * Helper function to validate one nameservice, used by
596 * nwam_loc_validate_all_nameservices().
598 * requiredprop denotes the property that is mandatory when the
599 * configsrcprop is manual. errpropp is used to return the invalid
603 nwam_loc_validate_one_nameservice(nwam_loc_handle_t loch
,
604 const char *configsrcprop
, const char *requiredprop
, const char **errpropp
)
606 nwam_value_t configsrcval
, requiredval
;
607 uint64_t *configsrcs
;
610 if (nwam_loc_get_prop_value(loch
, configsrcprop
, &configsrcval
)
612 if (errpropp
!= NULL
)
613 *errpropp
= configsrcprop
;
614 return (NWAM_ENTITY_MISSING_MEMBER
);
617 if (nwam_value_get_uint64_array(configsrcval
, &configsrcs
, &numvalues
)
619 if (errpropp
!= NULL
)
620 *errpropp
= configsrcprop
;
621 nwam_value_free(configsrcval
);
622 return (NWAM_ENTITY_NO_VALUE
);
625 /* If -configsrc is manual, requiredprop is required */
626 for (i
= 0; i
< numvalues
; i
++) {
627 if (configsrcs
[i
] == NWAM_CONFIGSRC_MANUAL
) {
628 if (nwam_loc_get_prop_value(loch
, requiredprop
,
629 &requiredval
) != NWAM_SUCCESS
) {
630 if (errpropp
!= NULL
)
631 *errpropp
= requiredprop
;
632 return (NWAM_ENTITY_MISSING_MEMBER
);
634 nwam_value_free(requiredval
);
637 nwam_value_free(configsrcval
);
639 return (NWAM_SUCCESS
);
643 * Helper function to validate LDAP nameservice, used by
644 * nwam_loc_validate_all_nameservices(). Separated because LDAP must be
645 * configured manually only and both default-domain and -servers are required.
648 nwam_loc_validate_ldap_nameservice(nwam_loc_handle_t loch
,
649 const char **errpropp
)
652 uint64_t *configsrcs
;
655 if (nwam_loc_get_prop_value(loch
,
656 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
, &val
) != NWAM_SUCCESS
) {
657 if (errpropp
!= NULL
)
658 *errpropp
= NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
;
659 return (NWAM_ENTITY_MISSING_MEMBER
);
661 /* -configsrc is defined as an array */
662 if (nwam_value_get_uint64_array(val
, &configsrcs
, &numvalues
)
664 if (errpropp
!= NULL
)
665 *errpropp
= NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
;
666 nwam_value_free(val
);
667 return (NWAM_ENTITY_NO_VALUE
);
670 /* -configsrc must be manual */
671 for (i
= 0; i
< numvalues
; i
++) {
672 if (configsrcs
[i
] != NWAM_CONFIGSRC_MANUAL
) {
673 if (errpropp
!= NULL
)
675 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
;
676 nwam_value_free(val
);
677 return (NWAM_ENTITY_INVALID_VALUE
);
680 nwam_value_free(val
);
682 /* both default-domain and -servers are required */
683 if (nwam_loc_get_prop_value(loch
,
684 NWAM_LOC_PROP_DEFAULT_DOMAIN
, &val
) != NWAM_SUCCESS
) {
685 if (errpropp
!= NULL
)
686 *errpropp
= NWAM_LOC_PROP_DEFAULT_DOMAIN
;
687 return (NWAM_ENTITY_MISSING_MEMBER
);
689 nwam_value_free(val
);
691 if (nwam_loc_get_prop_value(loch
,
692 NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
, &val
) != NWAM_SUCCESS
) {
693 if (errpropp
!= NULL
)
694 *errpropp
= NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
;
695 return (NWAM_ENTITY_MISSING_MEMBER
);
697 nwam_value_free(val
);
699 return (NWAM_SUCCESS
);
703 * Validates the different nameservices properties.
705 * If "nameservices" property has more than one nameservice to configure,
706 * "nameservices-config-file" must be specified. If only one nameservice
707 * is configured and "nameservices-config-file" is missing, set the
708 * property with the appropriately suffixed nsswitch file.
710 * For any nameservice being configured, the respective -configsrc property
711 * must be specified. For DNS, -servers is required if -configsrc is
712 * manual. For NIS and LDAP, default-domain is required if -configsrc is
713 * manual. For LDAP, -configsrc must be manual and -servers is required.
716 nwam_loc_validate_all_nameservices(nwam_loc_handle_t loch
,
717 nwam_value_t nameservicesval
, const char **errpropp
)
721 uint64_t *nameservices
;
724 if ((err
= nwam_value_get_uint64_array(nameservicesval
, &nameservices
,
725 &numvalues
)) != NWAM_SUCCESS
)
729 * nameservices-config-file is required if nameservices has more
733 if (nwam_loc_get_prop_value(loch
,
734 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, &val
)
736 if (errpropp
!= NULL
)
738 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
;
739 return (NWAM_ENTITY_MISSING_MEMBER
);
741 nwam_value_free(val
);
742 } else if (numvalues
== 1) {
744 * If only one nameservice is being configured and
745 * nameservices-config-file doesn't exist, create it to
746 * point to the respective nsswitch file.
748 err
= nwam_loc_get_prop_value(loch
,
749 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, &val
);
750 if (err
== NWAM_INVALID_ARG
|| err
== NWAM_ENTITY_NOT_FOUND
) {
752 const char *nsswitch_suffix
;
754 /* get the single nameservice being configured */
755 if ((err
= nwam_uint64_get_value_string(
756 NWAM_LOC_PROP_NAMESERVICES
, nameservices
[0],
757 &nsswitch_suffix
)) != NWAM_SUCCESS
)
758 goto config_file_fail
;
759 if ((nsswitch
= malloc(MAXPATHLEN
)) == NULL
) {
760 err
= NWAM_NO_MEMORY
;
761 goto config_file_fail
;
764 /* create appropriately suffixed nsswitch name */
765 (void) snprintf(nsswitch
, MAXPATHLEN
, "%s%s",
766 NSSWITCH_PREFIX
, nsswitch_suffix
);
767 if ((err
= nwam_value_create_string(nsswitch
, &val
))
770 goto config_file_fail
;
773 err
= nwam_set_prop_value(loch
->nwh_data
,
774 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, val
);
776 nwam_value_free(val
);
777 if (err
!= NWAM_SUCCESS
) {
778 nwam_value_free(val
);
779 goto config_file_fail
;
781 } else if (err
!= NWAM_SUCCESS
) {
782 goto config_file_fail
;
784 nwam_value_free(val
);
789 * validate the -configsrc property and the required default-domain
790 * and/or -servers property for each nameservice being configured.
792 for (i
= 0; i
< numvalues
; i
++) {
793 switch (nameservices
[i
]) {
794 case NWAM_NAMESERVICES_DNS
:
795 if ((err
= nwam_loc_validate_one_nameservice(loch
,
796 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
,
797 NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS
, errpropp
))
801 case NWAM_NAMESERVICES_NIS
:
802 if ((err
= nwam_loc_validate_one_nameservice(loch
,
803 NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
,
804 NWAM_LOC_PROP_DEFAULT_DOMAIN
, errpropp
))
808 case NWAM_NAMESERVICES_LDAP
:
809 if ((err
= nwam_loc_validate_ldap_nameservice(loch
,
810 errpropp
)) != NWAM_SUCCESS
)
813 case NWAM_NAMESERVICES_FILES
:
816 return (NWAM_ENTITY_INVALID_VALUE
);
819 return (NWAM_SUCCESS
);
822 if (errpropp
!= NULL
)
823 *errpropp
= NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
;
828 nwam_loc_validate(nwam_loc_handle_t loch
, const char **errpropp
)
831 nwam_value_t activationval
, conditionval
, nameservicesval
;
833 char **conditions
, *name
;
835 nwam_condition_object_type_t object_type
;
836 nwam_condition_t condition
;
838 assert(loch
!= NULL
);
841 * Make sure loc is internally consistent: if activation type is
842 * conditional, the condition string must be specified.
844 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
845 &activationval
) != NWAM_SUCCESS
) {
846 if (errpropp
!= NULL
)
847 *errpropp
= NWAM_LOC_PROP_ACTIVATION_MODE
;
848 return (NWAM_ENTITY_MISSING_MEMBER
);
851 if (nwam_value_get_uint64(activationval
, &activation
)
853 if (errpropp
!= NULL
)
854 *errpropp
= NWAM_LOC_PROP_ACTIVATION_MODE
;
855 nwam_value_free(activationval
);
856 return (NWAM_ENTITY_NO_VALUE
);
859 /* validate activation against the location first */
860 if ((err
= nwam_loc_validate_activation_mode(loch
, activationval
))
862 if (errpropp
!= NULL
)
863 *errpropp
= NWAM_LOC_PROP_ACTIVATION_MODE
;
864 nwam_value_free(activationval
);
867 nwam_value_free(activationval
);
869 if (activation
== NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
||
870 activation
== NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
) {
871 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_CONDITIONS
,
872 &conditionval
) != NWAM_SUCCESS
) {
873 if (errpropp
!= NULL
)
874 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
875 return (NWAM_ENTITY_MISSING_MEMBER
);
878 * Are conditions self-referential? In other words, do any
879 * of the activation conditions refer to this location?
881 if (nwam_value_get_string_array(conditionval
, &conditions
,
882 &numvalues
) != NWAM_SUCCESS
) {
883 nwam_value_free(conditionval
);
884 if (errpropp
!= NULL
)
885 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
886 return (NWAM_ENTITY_INVALID_VALUE
);
888 if (nwam_loc_get_name(loch
, &name
) != NWAM_SUCCESS
) {
889 nwam_value_free(conditionval
);
890 return (NWAM_INVALID_ARG
);
892 for (i
= 0; i
< numvalues
; i
++) {
893 char *object_name
= NULL
;
895 if (nwam_condition_string_to_condition(conditions
[i
],
896 &object_type
, &condition
, &object_name
)
898 if (errpropp
!= NULL
)
899 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
901 nwam_value_free(conditionval
);
902 return (NWAM_ENTITY_INVALID_VALUE
);
904 if (object_name
!= NULL
&&
905 object_type
== NWAM_CONDITION_OBJECT_TYPE_LOC
&&
906 strcmp(object_name
, name
) == 0) {
907 if (errpropp
!= NULL
)
908 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
911 nwam_value_free(conditionval
);
912 return (NWAM_ENTITY_INVALID_VALUE
);
917 nwam_value_free(conditionval
);
920 /* validate namerservices */
921 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_NAMESERVICES
,
922 &nameservicesval
) != NWAM_SUCCESS
) {
923 if (errpropp
!= NULL
)
924 *errpropp
= NWAM_LOC_PROP_NAMESERVICES
;
925 return (NWAM_ENTITY_MISSING_MEMBER
);
927 err
= nwam_loc_validate_all_nameservices(loch
, nameservicesval
,
929 nwam_value_free(nameservicesval
);
930 if (err
!= NWAM_SUCCESS
)
933 return (nwam_validate(loc_prop_table
, loch
, errpropp
));
937 nwam_loc_validate_prop(nwam_loc_handle_t loch
, const char *propname
,
942 assert(loch
!= NULL
);
944 if (strcmp(propname
, NWAM_LOC_PROP_ACTIVATION_MODE
) == 0) {
945 if ((err
= nwam_loc_validate_activation_mode(loch
, value
))
950 return (nwam_validate_prop(loc_prop_table
, loch
, propname
, value
));
954 nwam_loc_copy(nwam_loc_handle_t oldloch
, const char *newname
,
955 nwam_loc_handle_t
*newlochp
)
960 if ((err
= nwam_copy(NWAM_LOC_CONF_FILE
, oldloch
, newname
, newlochp
))
964 /* If the activation-mode is system, change it to manual */
965 if ((err
= nwam_loc_get_prop_value(*newlochp
,
966 NWAM_LOC_PROP_ACTIVATION_MODE
, &val
)) != NWAM_SUCCESS
)
968 err
= nwam_loc_validate_activation_mode(*newlochp
, val
);
969 nwam_value_free(val
);
970 if (err
!= NWAM_SUCCESS
) {
971 if ((err
= nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL
,
972 &val
)) != NWAM_SUCCESS
)
974 err
= nwam_set_prop_value((*newlochp
)->nwh_data
,
975 NWAM_LOC_PROP_ACTIVATION_MODE
, val
);
976 nwam_value_free(val
);
977 if (err
!= NWAM_SUCCESS
)
980 if ((err
= nwam_value_create_boolean(B_FALSE
, &val
))
983 err
= nwam_set_prop_value((*newlochp
)->nwh_data
,
984 NWAM_LOC_PROP_ENABLED
, val
);
985 nwam_value_free(val
);
986 if (err
!= NWAM_SUCCESS
)
990 return (NWAM_SUCCESS
);
993 nwam_loc_free(*newlochp
);
999 * Given a property, return expected property data type
1002 nwam_loc_get_prop_type(const char *propname
, nwam_value_type_t
*typep
)
1004 return (nwam_get_prop_type(loc_prop_table
, propname
, typep
));
1008 nwam_loc_prop_multivalued(const char *propname
, boolean_t
*multip
)
1010 return (nwam_prop_multivalued(loc_prop_table
, propname
, multip
));
1014 * Determine if the location has manual activation-mode or not.
1017 nwam_loc_is_manual(nwam_loc_handle_t loch
, boolean_t
*manualp
)
1020 nwam_value_t actval
;
1021 uint64_t activation
;
1023 assert(loch
!= NULL
);
1025 if ((err
= nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
1026 &actval
)) != NWAM_SUCCESS
)
1028 err
= nwam_value_get_uint64(actval
, &activation
);
1029 nwam_value_free(actval
);
1030 if (err
!= NWAM_SUCCESS
)
1033 if (activation
== NWAM_ACTIVATION_MODE_MANUAL
)
1037 return (NWAM_SUCCESS
);
1040 /* Determine if location is enabled or not */
1042 nwam_loc_is_enabled(nwam_loc_handle_t loch
, boolean_t
*enabledp
)
1045 nwam_value_t enabledval
;
1047 assert(loch
!= NULL
);
1049 if ((err
= nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ENABLED
,
1050 &enabledval
)) != NWAM_SUCCESS
)
1052 err
= nwam_value_get_boolean(enabledval
, enabledp
);
1053 nwam_value_free(enabledval
);
1058 * Callback to disable all locations other than one to enable, the handle
1059 * of which we pass in as an argument. If the argument is NULL, we disable
1063 loc_set_enabled(nwam_loc_handle_t loch
, void *data
)
1065 nwam_value_t enabledval
;
1066 boolean_t curr_state
, enabled
= B_FALSE
;
1067 nwam_loc_handle_t testloch
= data
;
1068 nwam_error_t err
= NWAM_SUCCESS
;
1070 if (testloch
!= NULL
) {
1071 char *name
, *testname
;
1073 if (nwam_loc_get_name(loch
, &name
) == NWAM_SUCCESS
&&
1074 nwam_loc_get_name(testloch
, &testname
) == NWAM_SUCCESS
&&
1075 strcmp(name
, testname
) == 0) {
1076 /* We enable this location. */
1081 /* If the enabled property is not changing, don't do anything. */
1082 if (nwam_loc_is_enabled(loch
, &curr_state
) == NWAM_SUCCESS
&&
1083 curr_state
== enabled
)
1086 if (nwam_value_create_boolean(enabled
, &enabledval
) != NWAM_SUCCESS
)
1088 if (nwam_set_prop_value(loch
->nwh_data
, NWAM_LOC_PROP_ENABLED
,
1089 enabledval
) == NWAM_SUCCESS
)
1090 err
= nwam_loc_commit(loch
, NWAM_FLAG_ENTITY_ENABLE
);
1092 nwam_value_free(enabledval
);
1097 * Update the enabled property for this location (and for all others
1101 nwam_loc_update_enabled(nwam_loc_handle_t loch
, boolean_t enabled
)
1108 * Disable all other locations that are manually enabled
1109 * and enable this one - a maximum of 1 location can be
1112 err
= nwam_walk_locs(loc_set_enabled
, loch
, 0, &cb_ret
);
1113 if (err
!= NWAM_SUCCESS
&& err
!= NWAM_WALK_HALTED
)
1116 cb_ret
= loc_set_enabled(loch
, NULL
);
1122 nwam_loc_enable(nwam_loc_handle_t loch
)
1127 assert(loch
!= NULL
);
1129 /* Make sure location is not enabled */
1130 if ((err
= nwam_loc_is_enabled(loch
, &enabled
)) != NWAM_SUCCESS
)
1133 return (NWAM_SUCCESS
);
1135 if ((err
= nwam_loc_update_enabled(loch
, B_TRUE
)) != NWAM_SUCCESS
)
1138 err
= nwam_enable(NULL
, loch
);
1140 /* nwamd may not be running, that's okay. */
1141 if (err
== NWAM_ERROR_BIND
)
1142 return (NWAM_SUCCESS
);
1148 nwam_loc_disable(nwam_loc_handle_t loch
)
1153 assert(loch
!= NULL
);
1155 /* Make sure location is enabled */
1156 if ((err
= nwam_loc_is_enabled(loch
, &enabled
)) != NWAM_SUCCESS
)
1159 return (NWAM_SUCCESS
);
1161 if ((err
= nwam_loc_update_enabled(loch
, B_FALSE
)) != NWAM_SUCCESS
)
1164 err
= nwam_disable(NULL
, loch
);
1166 /* nwamd may not be running, that's okay. */
1167 if (err
== NWAM_ERROR_BIND
)
1168 return (NWAM_SUCCESS
);
1174 nwam_loc_get_default_proplist(const char ***prop_list
, uint_t
*numvaluesp
)
1176 return (nwam_get_default_proplist(loc_prop_table
,
1177 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
, prop_list
, numvaluesp
));
1181 nwam_loc_get_state(nwam_loc_handle_t loch
, nwam_state_t
*statep
,
1182 nwam_aux_state_t
*auxp
)
1184 return (nwam_get_state(NULL
, loch
, statep
, auxp
));