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
);
269 if (nsswitch
!= NULL
)
272 nwam_value_free(val
);
273 if (err
!= NWAM_SUCCESS
) {
274 nwam_loc_free(*lochp
);
281 nwam_loc_get_name(nwam_loc_handle_t loch
, char **namep
)
283 return (nwam_get_name(loch
, namep
));
287 nwam_loc_set_name(nwam_loc_handle_t loch
, const char *name
)
289 return (nwam_set_name(loch
, name
));
293 nwam_loc_can_set_name(nwam_loc_handle_t loch
)
295 return (!loch
->nwh_committed
);
300 loc_selectcb(struct nwam_handle
*hp
, uint64_t flags
, void *data
)
302 nwam_loc_handle_t loch
= hp
;
304 uint64_t activation
, actflag
, walkfilter
;
305 nwam_value_t activationval
;
307 /* Skip the Legacy location in all cases */
308 if (nwam_loc_get_name(loch
, &locname
) != NWAM_SUCCESS
)
309 return (NWAM_INVALID_ARG
);
310 if (strcmp(locname
, NWAM_LOC_NAME_LEGACY
) == 0) {
312 return (NWAM_INVALID_ARG
);
317 * Get a bitmapped flag value corresponding to this loc's
320 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
321 &activationval
) != NWAM_SUCCESS
) {
322 return (NWAM_INVALID_ARG
);
324 if (nwam_value_get_uint64(activationval
, &activation
) != NWAM_SUCCESS
) {
325 nwam_value_free(activationval
);
326 return (NWAM_INVALID_ARG
);
329 actflag
= nwam_loc_activation_to_flag(activation
);
330 nwam_value_free(activationval
);
331 if ((walkfilter
= (flags
& NWAM_WALK_FILTER_MASK
)) == 0)
332 walkfilter
= NWAM_FLAG_ACTIVATION_MODE_ALL
;
333 if (actflag
& walkfilter
)
334 return (NWAM_SUCCESS
);
335 return (NWAM_INVALID_ARG
);
339 nwam_walk_locs(int(*cb
)(nwam_loc_handle_t
, void *), void *data
, uint64_t flags
,
342 nwam_error_t err
= nwam_valid_flags(flags
,
343 NWAM_FLAG_ACTIVATION_MODE_ALL
| NWAM_FLAG_BLOCKING
);
345 if (err
!= NWAM_SUCCESS
)
348 return (nwam_walk(NWAM_OBJECT_TYPE_LOC
, NWAM_LOC_CONF_FILE
,
349 cb
, data
, flags
, retp
, loc_selectcb
));
353 nwam_loc_free(nwam_loc_handle_t loch
)
359 nwam_loc_delete_prop(nwam_loc_handle_t loch
, const char *propname
)
365 assert(loch
!= NULL
&& propname
!= NULL
);
367 if ((err
= nwam_loc_prop_read_only(propname
, &ro
)) != NWAM_SUCCESS
)
370 return (NWAM_ENTITY_READ_ONLY
);
373 * Duplicate data, remove property and validate. If validation
374 * fails, revert to data duplicated prior to remove.
376 if ((err
= nwam_dup_object_list(loch
->nwh_data
, &olddata
))
379 if ((err
= nwam_delete_prop(loch
->nwh_data
, propname
))
381 nwam_free_object_list(loch
->nwh_data
);
382 loch
->nwh_data
= olddata
;
385 if ((err
= nwam_loc_validate(loch
, NULL
)) != NWAM_SUCCESS
) {
386 nwam_free_object_list(loch
->nwh_data
);
387 loch
->nwh_data
= olddata
;
390 nwam_free_object_list(olddata
);
392 return (NWAM_SUCCESS
);
396 nwam_loc_set_prop_value(nwam_loc_handle_t loch
, const char *propname
,
402 assert(loch
!= NULL
&& propname
!= NULL
&& value
!= NULL
);
404 if ((err
= nwam_loc_validate_prop(loch
, propname
, value
))
406 (err
= nwam_loc_prop_read_only(propname
, &ro
)) != NWAM_SUCCESS
)
409 return (NWAM_ENTITY_READ_ONLY
);
411 return (nwam_set_prop_value(loch
->nwh_data
, propname
, value
));
415 nwam_loc_get_prop_value(nwam_loc_handle_t loch
, const char *propname
,
416 nwam_value_t
*valuep
)
418 return (nwam_get_prop_value(loch
->nwh_data
, propname
, valuep
));
422 nwam_loc_walk_props(nwam_loc_handle_t loch
,
423 int (*cb
)(const char *, nwam_value_t
, void *),
424 void *data
, uint64_t flags
, int *retp
)
426 return (nwam_walk_props(loch
, cb
, data
, flags
, retp
));
430 nwam_loc_commit(nwam_loc_handle_t loch
, uint64_t flags
)
434 assert(loch
!= NULL
&& loch
->nwh_data
!= NULL
);
436 if ((err
= nwam_loc_validate(loch
, NULL
)) != NWAM_SUCCESS
)
439 return (nwam_commit(NWAM_LOC_CONF_FILE
, loch
, flags
));
443 nwam_loc_destroy(nwam_loc_handle_t loch
, uint64_t flags
)
450 * Automatic and NoNet are not destroyable and Legacy is
451 * destroyable by netadm only. These have system activation-mode.
453 if ((err
= nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
454 &actval
)) != NWAM_SUCCESS
)
456 err
= nwam_value_get_uint64(actval
, &activation
);
457 nwam_value_free(actval
);
458 if (err
!= NWAM_SUCCESS
)
461 if (activation
== NWAM_ACTIVATION_MODE_SYSTEM
) {
462 if (strcmp(loch
->nwh_name
, NWAM_LOC_NAME_LEGACY
) == 0) {
463 if (!nwam_uid_is_special())
464 return (NWAM_ENTITY_NOT_DESTROYABLE
);
466 return (NWAM_ENTITY_NOT_DESTROYABLE
);
470 return (nwam_destroy(NWAM_LOC_CONF_FILE
, loch
, flags
));
474 nwam_loc_get_prop_description(const char *propname
, const char **descriptionp
)
476 return (nwam_get_prop_description(loc_prop_table
, propname
,
481 nwam_loc_prop_read_only(const char *propname
, boolean_t
*readp
)
483 return (nwam_prop_read_only(loc_prop_table
, propname
, readp
));
487 valid_loc_activation_mode(nwam_value_t value
)
489 uint64_t activation_mode
;
491 if (nwam_value_get_uint64(value
, &activation_mode
) != NWAM_SUCCESS
)
492 return (NWAM_ENTITY_INVALID_VALUE
);
494 switch (activation_mode
) {
495 case NWAM_ACTIVATION_MODE_MANUAL
:
496 case NWAM_ACTIVATION_MODE_SYSTEM
:
497 case NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
:
498 case NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
:
499 return (NWAM_SUCCESS
);
501 return (NWAM_ENTITY_INVALID_VALUE
);
505 * Identical to nwam_valid_condition(), except locations cannot specify other
506 * location's activation as a condition, e.g. loc2 cannot specify
507 * "loc1 is active" since only one location is active at a time, and
508 * as a consequence the condition is unsatisfiable.
511 valid_loc_condition(nwam_value_t value
)
515 nwam_condition_object_type_t object_type
;
516 nwam_condition_t condition
;
518 if (nwam_value_get_string_array(value
, &conditions
, &numvalues
)
520 return (NWAM_ENTITY_INVALID_VALUE
);
522 for (i
= 0; i
< numvalues
; i
++) {
523 char *object_name
= NULL
;
525 if (nwam_condition_string_to_condition(conditions
[i
],
526 &object_type
, &condition
, &object_name
) != NWAM_SUCCESS
)
527 return (NWAM_ENTITY_INVALID_VALUE
);
528 if (object_type
== NWAM_CONDITION_OBJECT_TYPE_LOC
&&
529 condition
== NWAM_CONDITION_IS
) {
531 return (NWAM_ENTITY_INVALID_VALUE
);
533 if (object_name
!= NULL
)
536 return (NWAM_SUCCESS
);
540 valid_nameservices(nwam_value_t value
)
542 uint64_t *nameservices
;
545 if (nwam_value_get_uint64_array(value
, &nameservices
, &numvalues
)
547 return (NWAM_ENTITY_INVALID_VALUE
);
549 for (i
= 0; i
< numvalues
; i
++) {
550 if (nameservices
[i
] > NWAM_NAMESERVICES_LDAP
)
551 return (NWAM_ENTITY_INVALID_VALUE
);
553 return (NWAM_SUCCESS
);
557 valid_configsrc(nwam_value_t value
)
559 uint64_t *configsrcs
;
562 if (nwam_value_get_uint64_array(value
, &configsrcs
, &numvalues
)
564 return (NWAM_ENTITY_INVALID_VALUE
);
566 for (i
= 0; i
< numvalues
; i
++) {
567 if (configsrcs
[i
] > NWAM_CONFIGSRC_DHCP
)
568 return (NWAM_ENTITY_INVALID_VALUE
);
570 return (NWAM_SUCCESS
);
574 * Validates that the activation-mode is system for Automatic and NoNet
575 * locations, and not system for all other locations.
578 nwam_loc_validate_activation_mode(nwam_loc_handle_t loch
, nwam_value_t actval
)
583 if ((err
= nwam_value_get_uint64(actval
, &activation
)) != NWAM_SUCCESS
)
586 if (NWAM_LOC_NAME_PRE_DEFINED(loch
->nwh_name
)) {
587 if (activation
!= NWAM_ACTIVATION_MODE_SYSTEM
)
588 return (NWAM_ENTITY_INVALID_VALUE
);
590 if (activation
== NWAM_ACTIVATION_MODE_SYSTEM
)
591 return (NWAM_ENTITY_INVALID_VALUE
);
593 return (NWAM_SUCCESS
);
597 * Helper function to validate one nameservice, used by
598 * nwam_loc_validate_all_nameservices().
600 * requiredprop denotes the property that is mandatory when the
601 * configsrcprop is manual. errpropp is used to return the invalid
605 nwam_loc_validate_one_nameservice(nwam_loc_handle_t loch
,
606 const char *configsrcprop
, const char *requiredprop
, const char **errpropp
)
608 nwam_value_t configsrcval
, requiredval
;
609 uint64_t *configsrcs
;
612 if (nwam_loc_get_prop_value(loch
, configsrcprop
, &configsrcval
)
614 if (errpropp
!= NULL
)
615 *errpropp
= configsrcprop
;
616 return (NWAM_ENTITY_MISSING_MEMBER
);
619 if (nwam_value_get_uint64_array(configsrcval
, &configsrcs
, &numvalues
)
621 if (errpropp
!= NULL
)
622 *errpropp
= configsrcprop
;
623 nwam_value_free(configsrcval
);
624 return (NWAM_ENTITY_NO_VALUE
);
627 /* If -configsrc is manual, requiredprop is required */
628 for (i
= 0; i
< numvalues
; i
++) {
629 if (configsrcs
[i
] == NWAM_CONFIGSRC_MANUAL
) {
630 if (nwam_loc_get_prop_value(loch
, requiredprop
,
631 &requiredval
) != NWAM_SUCCESS
) {
632 if (errpropp
!= NULL
)
633 *errpropp
= requiredprop
;
634 return (NWAM_ENTITY_MISSING_MEMBER
);
636 nwam_value_free(requiredval
);
639 nwam_value_free(configsrcval
);
641 return (NWAM_SUCCESS
);
645 * Helper function to validate LDAP nameservice, used by
646 * nwam_loc_validate_all_nameservices(). Separated because LDAP must be
647 * configured manually only and both default-domain and -servers are required.
650 nwam_loc_validate_ldap_nameservice(nwam_loc_handle_t loch
,
651 const char **errpropp
)
654 uint64_t *configsrcs
;
657 if (nwam_loc_get_prop_value(loch
,
658 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
, &val
) != NWAM_SUCCESS
) {
659 if (errpropp
!= NULL
)
660 *errpropp
= NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
;
661 return (NWAM_ENTITY_MISSING_MEMBER
);
663 /* -configsrc is defined as an array */
664 if (nwam_value_get_uint64_array(val
, &configsrcs
, &numvalues
)
666 if (errpropp
!= NULL
)
667 *errpropp
= NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
;
668 nwam_value_free(val
);
669 return (NWAM_ENTITY_NO_VALUE
);
672 /* -configsrc must be manual */
673 for (i
= 0; i
< numvalues
; i
++) {
674 if (configsrcs
[i
] != NWAM_CONFIGSRC_MANUAL
) {
675 if (errpropp
!= NULL
)
677 NWAM_LOC_PROP_LDAP_NAMESERVICE_CONFIGSRC
;
678 nwam_value_free(val
);
679 return (NWAM_ENTITY_INVALID_VALUE
);
682 nwam_value_free(val
);
684 /* both default-domain and -servers are required */
685 if (nwam_loc_get_prop_value(loch
,
686 NWAM_LOC_PROP_DEFAULT_DOMAIN
, &val
) != NWAM_SUCCESS
) {
687 if (errpropp
!= NULL
)
688 *errpropp
= NWAM_LOC_PROP_DEFAULT_DOMAIN
;
689 return (NWAM_ENTITY_MISSING_MEMBER
);
691 nwam_value_free(val
);
693 if (nwam_loc_get_prop_value(loch
,
694 NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
, &val
) != NWAM_SUCCESS
) {
695 if (errpropp
!= NULL
)
696 *errpropp
= NWAM_LOC_PROP_LDAP_NAMESERVICE_SERVERS
;
697 return (NWAM_ENTITY_MISSING_MEMBER
);
699 nwam_value_free(val
);
701 return (NWAM_SUCCESS
);
705 * Validates the different nameservices properties.
707 * If "nameservices" property has more than one nameservice to configure,
708 * "nameservices-config-file" must be specified. If only one nameservice
709 * is configured and "nameservices-config-file" is missing, set the
710 * property with the appropriately suffixed nsswitch file.
712 * For any nameservice being configured, the respective -configsrc property
713 * must be specified. For DNS, -servers is required if -configsrc is
714 * manual. For NIS and LDAP, default-domain is required if -configsrc is
715 * manual. For LDAP, -configsrc must be manual and -servers is required.
718 nwam_loc_validate_all_nameservices(nwam_loc_handle_t loch
,
719 nwam_value_t nameservicesval
, const char **errpropp
)
723 uint64_t *nameservices
;
726 if ((err
= nwam_value_get_uint64_array(nameservicesval
, &nameservices
,
727 &numvalues
)) != NWAM_SUCCESS
)
731 * nameservices-config-file is required if nameservices has more
735 if (nwam_loc_get_prop_value(loch
,
736 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, &val
)
738 if (errpropp
!= NULL
)
740 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
;
741 return (NWAM_ENTITY_MISSING_MEMBER
);
743 nwam_value_free(val
);
744 } else if (numvalues
== 1) {
746 * If only one nameservice is being configured and
747 * nameservices-config-file doesn't exist, create it to
748 * point to the respective nsswitch file.
750 err
= nwam_loc_get_prop_value(loch
,
751 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, &val
);
752 if (err
== NWAM_INVALID_ARG
|| err
== NWAM_ENTITY_NOT_FOUND
) {
754 const char *nsswitch_suffix
;
756 /* get the single nameservice being configured */
757 if ((err
= nwam_uint64_get_value_string(
758 NWAM_LOC_PROP_NAMESERVICES
, nameservices
[0],
759 &nsswitch_suffix
)) != NWAM_SUCCESS
)
760 goto config_file_fail
;
761 if ((nsswitch
= malloc(MAXPATHLEN
)) == NULL
) {
762 err
= NWAM_NO_MEMORY
;
763 goto config_file_fail
;
766 /* create appropriately suffixed nsswitch name */
767 (void) snprintf(nsswitch
, MAXPATHLEN
, "%s%s",
768 NSSWITCH_PREFIX
, nsswitch_suffix
);
769 if ((err
= nwam_value_create_string(nsswitch
, &val
))
772 goto config_file_fail
;
775 err
= nwam_set_prop_value(loch
->nwh_data
,
776 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
, val
);
778 nwam_value_free(val
);
779 if (err
!= NWAM_SUCCESS
) {
780 nwam_value_free(val
);
781 goto config_file_fail
;
783 } else if (err
!= NWAM_SUCCESS
) {
784 goto config_file_fail
;
786 nwam_value_free(val
);
791 * validate the -configsrc property and the required default-domain
792 * and/or -servers property for each nameservice being configured.
794 for (i
= 0; i
< numvalues
; i
++) {
795 switch (nameservices
[i
]) {
796 case NWAM_NAMESERVICES_DNS
:
797 if ((err
= nwam_loc_validate_one_nameservice(loch
,
798 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC
,
799 NWAM_LOC_PROP_DNS_NAMESERVICE_SERVERS
, errpropp
))
803 case NWAM_NAMESERVICES_NIS
:
804 if ((err
= nwam_loc_validate_one_nameservice(loch
,
805 NWAM_LOC_PROP_NIS_NAMESERVICE_CONFIGSRC
,
806 NWAM_LOC_PROP_DEFAULT_DOMAIN
, errpropp
))
810 case NWAM_NAMESERVICES_LDAP
:
811 if ((err
= nwam_loc_validate_ldap_nameservice(loch
,
812 errpropp
)) != NWAM_SUCCESS
)
815 case NWAM_NAMESERVICES_FILES
:
818 return (NWAM_ENTITY_INVALID_VALUE
);
821 return (NWAM_SUCCESS
);
824 if (errpropp
!= NULL
)
825 *errpropp
= NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE
;
830 nwam_loc_validate(nwam_loc_handle_t loch
, const char **errpropp
)
833 nwam_value_t activationval
, conditionval
, nameservicesval
;
835 char **conditions
, *name
;
837 nwam_condition_object_type_t object_type
;
838 nwam_condition_t condition
;
840 assert(loch
!= NULL
);
843 * Make sure loc is internally consistent: if activation type is
844 * conditional, the condition string must be specified.
846 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
847 &activationval
) != NWAM_SUCCESS
) {
848 if (errpropp
!= NULL
)
849 *errpropp
= NWAM_LOC_PROP_ACTIVATION_MODE
;
850 return (NWAM_ENTITY_MISSING_MEMBER
);
853 if (nwam_value_get_uint64(activationval
, &activation
)
855 if (errpropp
!= NULL
)
856 *errpropp
= NWAM_LOC_PROP_ACTIVATION_MODE
;
857 nwam_value_free(activationval
);
858 return (NWAM_ENTITY_NO_VALUE
);
861 /* validate activation against the location first */
862 if ((err
= nwam_loc_validate_activation_mode(loch
, activationval
))
864 if (errpropp
!= NULL
)
865 *errpropp
= NWAM_LOC_PROP_ACTIVATION_MODE
;
866 nwam_value_free(activationval
);
869 nwam_value_free(activationval
);
871 if (activation
== NWAM_ACTIVATION_MODE_CONDITIONAL_ANY
||
872 activation
== NWAM_ACTIVATION_MODE_CONDITIONAL_ALL
) {
873 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_CONDITIONS
,
874 &conditionval
) != NWAM_SUCCESS
) {
875 if (errpropp
!= NULL
)
876 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
877 return (NWAM_ENTITY_MISSING_MEMBER
);
880 * Are conditions self-referential? In other words, do any
881 * of the activation conditions refer to this location?
883 if (nwam_value_get_string_array(conditionval
, &conditions
,
884 &numvalues
) != NWAM_SUCCESS
) {
885 nwam_value_free(conditionval
);
886 if (errpropp
!= NULL
)
887 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
888 return (NWAM_ENTITY_INVALID_VALUE
);
890 if (nwam_loc_get_name(loch
, &name
) != NWAM_SUCCESS
) {
891 nwam_value_free(conditionval
);
892 return (NWAM_INVALID_ARG
);
894 for (i
= 0; i
< numvalues
; i
++) {
895 char *object_name
= NULL
;
897 if (nwam_condition_string_to_condition(conditions
[i
],
898 &object_type
, &condition
, &object_name
)
900 if (errpropp
!= NULL
)
901 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
903 nwam_value_free(conditionval
);
904 return (NWAM_ENTITY_INVALID_VALUE
);
906 if (object_name
!= NULL
&&
907 object_type
== NWAM_CONDITION_OBJECT_TYPE_LOC
&&
908 strcmp(object_name
, name
) == 0) {
909 if (errpropp
!= NULL
)
910 *errpropp
= NWAM_LOC_PROP_CONDITIONS
;
913 nwam_value_free(conditionval
);
914 return (NWAM_ENTITY_INVALID_VALUE
);
919 nwam_value_free(conditionval
);
922 /* validate namerservices */
923 if (nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_NAMESERVICES
,
924 &nameservicesval
) != NWAM_SUCCESS
) {
925 if (errpropp
!= NULL
)
926 *errpropp
= NWAM_LOC_PROP_NAMESERVICES
;
927 return (NWAM_ENTITY_MISSING_MEMBER
);
929 err
= nwam_loc_validate_all_nameservices(loch
, nameservicesval
,
931 nwam_value_free(nameservicesval
);
932 if (err
!= NWAM_SUCCESS
)
935 return (nwam_validate(loc_prop_table
, loch
, errpropp
));
939 nwam_loc_validate_prop(nwam_loc_handle_t loch
, const char *propname
,
944 assert(loch
!= NULL
);
946 if (strcmp(propname
, NWAM_LOC_PROP_ACTIVATION_MODE
) == 0) {
947 if ((err
= nwam_loc_validate_activation_mode(loch
, value
))
952 return (nwam_validate_prop(loc_prop_table
, loch
, propname
, value
));
956 nwam_loc_copy(nwam_loc_handle_t oldloch
, const char *newname
,
957 nwam_loc_handle_t
*newlochp
)
962 if ((err
= nwam_copy(NWAM_LOC_CONF_FILE
, oldloch
, newname
, newlochp
))
966 /* If the activation-mode is system, change it to manual */
967 if ((err
= nwam_loc_get_prop_value(*newlochp
,
968 NWAM_LOC_PROP_ACTIVATION_MODE
, &val
)) != NWAM_SUCCESS
)
970 err
= nwam_loc_validate_activation_mode(*newlochp
, val
);
971 nwam_value_free(val
);
972 if (err
!= NWAM_SUCCESS
) {
973 if ((err
= nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL
,
974 &val
)) != NWAM_SUCCESS
)
976 err
= nwam_set_prop_value((*newlochp
)->nwh_data
,
977 NWAM_LOC_PROP_ACTIVATION_MODE
, val
);
978 nwam_value_free(val
);
979 if (err
!= NWAM_SUCCESS
)
982 if ((err
= nwam_value_create_boolean(B_FALSE
, &val
))
985 err
= nwam_set_prop_value((*newlochp
)->nwh_data
,
986 NWAM_LOC_PROP_ENABLED
, val
);
987 nwam_value_free(val
);
988 if (err
!= NWAM_SUCCESS
)
992 return (NWAM_SUCCESS
);
995 nwam_loc_free(*newlochp
);
1001 * Given a property, return expected property data type
1004 nwam_loc_get_prop_type(const char *propname
, nwam_value_type_t
*typep
)
1006 return (nwam_get_prop_type(loc_prop_table
, propname
, typep
));
1010 nwam_loc_prop_multivalued(const char *propname
, boolean_t
*multip
)
1012 return (nwam_prop_multivalued(loc_prop_table
, propname
, multip
));
1016 * Determine if the location has manual activation-mode or not.
1019 nwam_loc_is_manual(nwam_loc_handle_t loch
, boolean_t
*manualp
)
1022 nwam_value_t actval
;
1023 uint64_t activation
;
1025 assert(loch
!= NULL
);
1027 if ((err
= nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ACTIVATION_MODE
,
1028 &actval
)) != NWAM_SUCCESS
)
1030 err
= nwam_value_get_uint64(actval
, &activation
);
1031 nwam_value_free(actval
);
1032 if (err
!= NWAM_SUCCESS
)
1035 if (activation
== NWAM_ACTIVATION_MODE_MANUAL
)
1039 return (NWAM_SUCCESS
);
1042 /* Determine if location is enabled or not */
1044 nwam_loc_is_enabled(nwam_loc_handle_t loch
, boolean_t
*enabledp
)
1047 nwam_value_t enabledval
;
1049 assert(loch
!= NULL
);
1051 if ((err
= nwam_loc_get_prop_value(loch
, NWAM_LOC_PROP_ENABLED
,
1052 &enabledval
)) != NWAM_SUCCESS
)
1054 err
= nwam_value_get_boolean(enabledval
, enabledp
);
1055 nwam_value_free(enabledval
);
1060 * Callback to disable all locations other than one to enable, the handle
1061 * of which we pass in as an argument. If the argument is NULL, we disable
1065 loc_set_enabled(nwam_loc_handle_t loch
, void *data
)
1067 nwam_value_t enabledval
;
1068 boolean_t curr_state
, enabled
= B_FALSE
;
1069 nwam_loc_handle_t testloch
= data
;
1070 nwam_error_t err
= NWAM_SUCCESS
;
1072 if (testloch
!= NULL
) {
1073 char *name
, *testname
;
1075 if (nwam_loc_get_name(loch
, &name
) == NWAM_SUCCESS
&&
1076 nwam_loc_get_name(testloch
, &testname
) == NWAM_SUCCESS
&&
1077 strcmp(name
, testname
) == 0) {
1078 /* We enable this location. */
1083 /* If the enabled property is not changing, don't do anything. */
1084 if (nwam_loc_is_enabled(loch
, &curr_state
) == NWAM_SUCCESS
&&
1085 curr_state
== enabled
)
1088 if (nwam_value_create_boolean(enabled
, &enabledval
) != NWAM_SUCCESS
)
1090 if (nwam_set_prop_value(loch
->nwh_data
, NWAM_LOC_PROP_ENABLED
,
1091 enabledval
) == NWAM_SUCCESS
)
1092 err
= nwam_loc_commit(loch
, NWAM_FLAG_ENTITY_ENABLE
);
1094 nwam_value_free(enabledval
);
1099 * Update the enabled property for this location (and for all others
1103 nwam_loc_update_enabled(nwam_loc_handle_t loch
, boolean_t enabled
)
1110 * Disable all other locations that are manually enabled
1111 * and enable this one - a maximum of 1 location can be
1114 err
= nwam_walk_locs(loc_set_enabled
, loch
, 0, &cb_ret
);
1115 if (err
!= NWAM_SUCCESS
&& err
!= NWAM_WALK_HALTED
)
1118 cb_ret
= loc_set_enabled(loch
, NULL
);
1124 nwam_loc_enable(nwam_loc_handle_t loch
)
1129 assert(loch
!= NULL
);
1131 /* Make sure location is not enabled */
1132 if ((err
= nwam_loc_is_enabled(loch
, &enabled
)) != NWAM_SUCCESS
)
1135 return (NWAM_SUCCESS
);
1137 if ((err
= nwam_loc_update_enabled(loch
, B_TRUE
)) != NWAM_SUCCESS
)
1140 err
= nwam_enable(NULL
, loch
);
1142 /* nwamd may not be running, that's okay. */
1143 if (err
== NWAM_ERROR_BIND
)
1144 return (NWAM_SUCCESS
);
1150 nwam_loc_disable(nwam_loc_handle_t loch
)
1155 assert(loch
!= NULL
);
1157 /* Make sure location is enabled */
1158 if ((err
= nwam_loc_is_enabled(loch
, &enabled
)) != NWAM_SUCCESS
)
1161 return (NWAM_SUCCESS
);
1163 if ((err
= nwam_loc_update_enabled(loch
, B_FALSE
)) != NWAM_SUCCESS
)
1166 err
= nwam_disable(NULL
, loch
);
1168 /* nwamd may not be running, that's okay. */
1169 if (err
== NWAM_ERROR_BIND
)
1170 return (NWAM_SUCCESS
);
1176 nwam_loc_get_default_proplist(const char ***prop_list
, uint_t
*numvaluesp
)
1178 return (nwam_get_default_proplist(loc_prop_table
,
1179 NWAM_TYPE_ANY
, NWAM_CLASS_ANY
, prop_list
, numvaluesp
));
1183 nwam_loc_get_state(nwam_loc_handle_t loch
, nwam_state_t
*statep
,
1184 nwam_aux_state_t
*auxp
)
1186 return (nwam_get_state(NULL
, loch
, statep
, auxp
));