8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libnwam / common / libnwam_loc.c
blob23adbba00b703a618d361d730d5bf4820119487f
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <assert.h>
27 #include <ctype.h>
28 #include <sys/param.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <strings.h>
34 #include <unistd.h>
35 #include <libscf.h>
37 #include "libnwam_impl.h"
38 #include <libnwam_priv.h>
39 #include <libnwam.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,
76 nwam_valid_boolean,
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,
125 nwam_valid_domain,
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,
129 nwam_valid_domain,
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 "
135 "location",
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 "
140 "location",
141 NWAM_TYPE_ANY, NWAM_CLASS_ANY},
142 {NWAM_LOC_PROP_IPNAT_CONFIG_FILE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
143 1, nwam_valid_file,
144 "specifies an absolute path to an ipnat.conf(4) file for this "
145 "location",
146 NWAM_TYPE_ANY, NWAM_CLASS_ANY},
147 {NWAM_LOC_PROP_IPPOOL_CONFIG_FILE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0,
148 1, nwam_valid_file,
149 "specifies an absolute path to an ippool.conf(4) file for this "
150 "location",
151 NWAM_TYPE_ANY, NWAM_CLASS_ANY},
152 {NWAM_LOC_PROP_IKE_CONFIG_FILE, NWAM_VALUE_TYPE_STRING, B_FALSE, 0, 1,
153 nwam_valid_file,
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 };
170 static uint64_t
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);
182 default:
183 return (0);
187 nwam_error_t
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,
191 flags, lochp));
194 nwam_error_t
195 nwam_loc_create(const char *name, nwam_loc_handle_t *lochp)
197 nwam_error_t err;
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)
205 return (err);
207 /* Create new object list for loc */
208 if ((err = nwam_alloc_object_list(&((*lochp)->nwh_data)))
209 != NWAM_SUCCESS)
210 goto finish;
212 /* NWAM_LOC_PROP_ACTIVATION_MODE is mandatory */
213 if ((err = nwam_value_create_uint64(NWAM_ACTIVATION_MODE_MANUAL, &val))
214 != NWAM_SUCCESS) {
215 goto finish;
217 if ((err = nwam_set_prop_value((*lochp)->nwh_data,
218 NWAM_LOC_PROP_ACTIVATION_MODE, val)) != NWAM_SUCCESS) {
219 goto finish;
221 nwam_value_free(val);
222 val = NULL;
225 * NWAM_LOC_PROP_ENABLED defaults to false.
227 if ((err = nwam_value_create_boolean(B_FALSE, &val)) != NWAM_SUCCESS)
228 goto finish;
229 if ((err = nwam_set_prop_value((*lochp)->nwh_data,
230 NWAM_LOC_PROP_ENABLED, val)) != NWAM_SUCCESS)
231 goto finish;
232 nwam_value_free(val);
233 val = NULL;
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)) !=
240 NWAM_SUCCESS)
241 goto finish;
242 if ((err = nwam_set_prop_value((*lochp)->nwh_data,
243 NWAM_LOC_PROP_NAMESERVICES, val)) != NWAM_SUCCESS)
244 goto finish;
245 nwam_value_free(val);
246 val = NULL;
248 if ((err = nwam_value_create_uint64(NWAM_CONFIGSRC_DHCP, &val)) !=
249 NWAM_SUCCESS)
250 goto finish;
251 if ((err = nwam_set_prop_value((*lochp)->nwh_data,
252 NWAM_LOC_PROP_DNS_NAMESERVICE_CONFIGSRC, val)) != NWAM_SUCCESS)
253 goto finish;
254 nwam_value_free(val);
255 val = NULL;
257 /* concatenate these two strings */
258 nsswitch = strdup(NSSWITCH_PREFIX NWAM_NAMESERVICES_DNS_STRING);
259 if (nsswitch == NULL) {
260 err = NWAM_NO_MEMORY;
261 goto finish;
263 if ((err = nwam_value_create_string(nsswitch, &val)) != NWAM_SUCCESS)
264 goto finish;
265 err = nwam_set_prop_value((*lochp)->nwh_data,
266 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE, val);
268 finish:
269 if (nsswitch != NULL)
270 free(nsswitch);
271 if (val != NULL)
272 nwam_value_free(val);
273 if (err != NWAM_SUCCESS) {
274 nwam_loc_free(*lochp);
275 *lochp = NULL;
277 return (err);
280 nwam_error_t
281 nwam_loc_get_name(nwam_loc_handle_t loch, char **namep)
283 return (nwam_get_name(loch, namep));
286 nwam_error_t
287 nwam_loc_set_name(nwam_loc_handle_t loch, const char *name)
289 return (nwam_set_name(loch, name));
292 boolean_t
293 nwam_loc_can_set_name(nwam_loc_handle_t loch)
295 return (!loch->nwh_committed);
298 /* ARGSUSED2 */
299 static int
300 loc_selectcb(struct nwam_handle *hp, uint64_t flags, void *data)
302 nwam_loc_handle_t loch = hp;
303 char *locname;
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) {
311 free(locname);
312 return (NWAM_INVALID_ARG);
314 free(locname);
317 * Get a bitmapped flag value corresponding to this loc's
318 * activation.
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);
338 nwam_error_t
339 nwam_walk_locs(int(*cb)(nwam_loc_handle_t, void *), void *data, uint64_t flags,
340 int *retp)
342 nwam_error_t err = nwam_valid_flags(flags,
343 NWAM_FLAG_ACTIVATION_MODE_ALL | NWAM_FLAG_BLOCKING);
345 if (err != NWAM_SUCCESS)
346 return (err);
348 return (nwam_walk(NWAM_OBJECT_TYPE_LOC, NWAM_LOC_CONF_FILE,
349 cb, data, flags, retp, loc_selectcb));
352 void
353 nwam_loc_free(nwam_loc_handle_t loch)
355 nwam_free(loch);
358 nwam_error_t
359 nwam_loc_delete_prop(nwam_loc_handle_t loch, const char *propname)
361 nwam_error_t err;
362 boolean_t ro;
363 void *olddata;
365 assert(loch != NULL && propname != NULL);
367 if ((err = nwam_loc_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
368 return (err);
369 if (ro)
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))
377 != NWAM_SUCCESS)
378 return (err);
379 if ((err = nwam_delete_prop(loch->nwh_data, propname))
380 != NWAM_SUCCESS) {
381 nwam_free_object_list(loch->nwh_data);
382 loch->nwh_data = olddata;
383 return (err);
385 if ((err = nwam_loc_validate(loch, NULL)) != NWAM_SUCCESS) {
386 nwam_free_object_list(loch->nwh_data);
387 loch->nwh_data = olddata;
388 return (err);
390 nwam_free_object_list(olddata);
392 return (NWAM_SUCCESS);
395 nwam_error_t
396 nwam_loc_set_prop_value(nwam_loc_handle_t loch, const char *propname,
397 nwam_value_t value)
399 nwam_error_t err;
400 boolean_t ro;
402 assert(loch != NULL && propname != NULL && value != NULL);
404 if ((err = nwam_loc_validate_prop(loch, propname, value))
405 != NWAM_SUCCESS ||
406 (err = nwam_loc_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
407 return (err);
408 if (ro)
409 return (NWAM_ENTITY_READ_ONLY);
411 return (nwam_set_prop_value(loch->nwh_data, propname, value));
414 nwam_error_t
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));
421 nwam_error_t
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));
429 nwam_error_t
430 nwam_loc_commit(nwam_loc_handle_t loch, uint64_t flags)
432 nwam_error_t err;
434 assert(loch != NULL && loch->nwh_data != NULL);
436 if ((err = nwam_loc_validate(loch, NULL)) != NWAM_SUCCESS)
437 return (err);
439 return (nwam_commit(NWAM_LOC_CONF_FILE, loch, flags));
442 nwam_error_t
443 nwam_loc_destroy(nwam_loc_handle_t loch, uint64_t flags)
445 nwam_error_t err;
446 nwam_value_t actval;
447 uint64_t activation;
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)
455 return (err);
456 err = nwam_value_get_uint64(actval, &activation);
457 nwam_value_free(actval);
458 if (err != NWAM_SUCCESS)
459 return (err);
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);
465 } else {
466 return (NWAM_ENTITY_NOT_DESTROYABLE);
470 return (nwam_destroy(NWAM_LOC_CONF_FILE, loch, flags));
473 nwam_error_t
474 nwam_loc_get_prop_description(const char *propname, const char **descriptionp)
476 return (nwam_get_prop_description(loc_prop_table, propname,
477 descriptionp));
480 nwam_error_t
481 nwam_loc_prop_read_only(const char *propname, boolean_t *readp)
483 return (nwam_prop_read_only(loc_prop_table, propname, readp));
486 static nwam_error_t
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.
510 nwam_error_t
511 valid_loc_condition(nwam_value_t value)
513 char **conditions;
514 uint_t i, numvalues;
515 nwam_condition_object_type_t object_type;
516 nwam_condition_t condition;
518 if (nwam_value_get_string_array(value, &conditions, &numvalues)
519 != NWAM_SUCCESS)
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) {
530 free(object_name);
531 return (NWAM_ENTITY_INVALID_VALUE);
533 if (object_name != NULL)
534 free(object_name);
536 return (NWAM_SUCCESS);
539 static nwam_error_t
540 valid_nameservices(nwam_value_t value)
542 uint64_t *nameservices;
543 uint_t i, numvalues;
545 if (nwam_value_get_uint64_array(value, &nameservices, &numvalues)
546 != NWAM_SUCCESS)
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);
556 static nwam_error_t
557 valid_configsrc(nwam_value_t value)
559 uint64_t *configsrcs;
560 uint_t i, numvalues;
562 if (nwam_value_get_uint64_array(value, &configsrcs, &numvalues)
563 != NWAM_SUCCESS)
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.
577 static nwam_error_t
578 nwam_loc_validate_activation_mode(nwam_loc_handle_t loch, nwam_value_t actval)
580 nwam_error_t err;
581 uint64_t activation;
583 if ((err = nwam_value_get_uint64(actval, &activation)) != NWAM_SUCCESS)
584 return (err);
586 if (NWAM_LOC_NAME_PRE_DEFINED(loch->nwh_name)) {
587 if (activation != NWAM_ACTIVATION_MODE_SYSTEM)
588 return (NWAM_ENTITY_INVALID_VALUE);
589 } else {
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
602 * property.
604 static nwam_error_t
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;
610 uint_t i, numvalues;
612 if (nwam_loc_get_prop_value(loch, configsrcprop, &configsrcval)
613 != NWAM_SUCCESS) {
614 if (errpropp != NULL)
615 *errpropp = configsrcprop;
616 return (NWAM_ENTITY_MISSING_MEMBER);
619 if (nwam_value_get_uint64_array(configsrcval, &configsrcs, &numvalues)
620 != NWAM_SUCCESS) {
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.
649 static nwam_error_t
650 nwam_loc_validate_ldap_nameservice(nwam_loc_handle_t loch,
651 const char **errpropp)
653 nwam_value_t val;
654 uint64_t *configsrcs;
655 uint_t i, numvalues;
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)
665 != NWAM_SUCCESS) {
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)
676 *errpropp =
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.
717 static nwam_error_t
718 nwam_loc_validate_all_nameservices(nwam_loc_handle_t loch,
719 nwam_value_t nameservicesval, const char **errpropp)
721 nwam_error_t err;
722 nwam_value_t val;
723 uint64_t *nameservices;
724 uint_t i, numvalues;
726 if ((err = nwam_value_get_uint64_array(nameservicesval, &nameservices,
727 &numvalues)) != NWAM_SUCCESS)
728 return (err);
731 * nameservices-config-file is required if nameservices has more
732 * than one value.
734 if (numvalues > 1) {
735 if (nwam_loc_get_prop_value(loch,
736 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE, &val)
737 != NWAM_SUCCESS) {
738 if (errpropp != NULL)
739 *errpropp =
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) {
753 char *nsswitch;
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))
770 != NWAM_SUCCESS) {
771 free(nsswitch);
772 goto config_file_fail;
775 err = nwam_set_prop_value(loch->nwh_data,
776 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE, val);
777 free(nsswitch);
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;
785 } else {
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))
800 != NWAM_SUCCESS)
801 return (err);
802 break;
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))
807 != NWAM_SUCCESS)
808 return (err);
809 break;
810 case NWAM_NAMESERVICES_LDAP:
811 if ((err = nwam_loc_validate_ldap_nameservice(loch,
812 errpropp)) != NWAM_SUCCESS)
813 return (err);
814 break;
815 case NWAM_NAMESERVICES_FILES:
816 break;
817 default:
818 return (NWAM_ENTITY_INVALID_VALUE);
821 return (NWAM_SUCCESS);
823 config_file_fail:
824 if (errpropp != NULL)
825 *errpropp = NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE;
826 return (err);
829 nwam_error_t
830 nwam_loc_validate(nwam_loc_handle_t loch, const char **errpropp)
832 nwam_error_t err;
833 nwam_value_t activationval, conditionval, nameservicesval;
834 uint64_t activation;
835 char **conditions, *name;
836 uint_t i, numvalues;
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)
854 != NWAM_SUCCESS) {
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))
863 != NWAM_SUCCESS) {
864 if (errpropp != NULL)
865 *errpropp = NWAM_LOC_PROP_ACTIVATION_MODE;
866 nwam_value_free(activationval);
867 return (err);
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)
899 != NWAM_SUCCESS) {
900 if (errpropp != NULL)
901 *errpropp = NWAM_LOC_PROP_CONDITIONS;
902 free(name);
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;
911 free(name);
912 free(object_name);
913 nwam_value_free(conditionval);
914 return (NWAM_ENTITY_INVALID_VALUE);
916 free(object_name);
918 free(name);
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,
930 errpropp);
931 nwam_value_free(nameservicesval);
932 if (err != NWAM_SUCCESS)
933 return (err);
935 return (nwam_validate(loc_prop_table, loch, errpropp));
938 nwam_error_t
939 nwam_loc_validate_prop(nwam_loc_handle_t loch, const char *propname,
940 nwam_value_t value)
942 nwam_error_t err;
944 assert(loch != NULL);
946 if (strcmp(propname, NWAM_LOC_PROP_ACTIVATION_MODE) == 0) {
947 if ((err = nwam_loc_validate_activation_mode(loch, value))
948 != NWAM_SUCCESS)
949 return (err);
952 return (nwam_validate_prop(loc_prop_table, loch, propname, value));
955 nwam_error_t
956 nwam_loc_copy(nwam_loc_handle_t oldloch, const char *newname,
957 nwam_loc_handle_t *newlochp)
959 nwam_error_t err;
960 nwam_value_t val;
962 if ((err = nwam_copy(NWAM_LOC_CONF_FILE, oldloch, newname, newlochp))
963 != NWAM_SUCCESS)
964 return (err);
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)
969 goto finish;
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)
975 goto finish;
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)
980 goto finish;
982 if ((err = nwam_value_create_boolean(B_FALSE, &val))
983 != NWAM_SUCCESS)
984 goto finish;
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)
989 goto finish;
992 return (NWAM_SUCCESS);
994 finish:
995 nwam_loc_free(*newlochp);
996 *newlochp = NULL;
997 return (err);
1001 * Given a property, return expected property data type
1003 nwam_error_t
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));
1009 nwam_error_t
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.
1018 nwam_error_t
1019 nwam_loc_is_manual(nwam_loc_handle_t loch, boolean_t *manualp)
1021 nwam_error_t err;
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)
1029 return (err);
1030 err = nwam_value_get_uint64(actval, &activation);
1031 nwam_value_free(actval);
1032 if (err != NWAM_SUCCESS)
1033 return (err);
1035 if (activation == NWAM_ACTIVATION_MODE_MANUAL)
1036 *manualp = B_TRUE;
1037 else
1038 *manualp = B_FALSE;
1039 return (NWAM_SUCCESS);
1042 /* Determine if location is enabled or not */
1043 static nwam_error_t
1044 nwam_loc_is_enabled(nwam_loc_handle_t loch, boolean_t *enabledp)
1046 nwam_error_t err;
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)
1053 return (err);
1054 err = nwam_value_get_boolean(enabledval, enabledp);
1055 nwam_value_free(enabledval);
1056 return (err);
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
1062 * all locations.
1064 static int
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. */
1079 enabled = B_TRUE;
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)
1086 return (0);
1088 if (nwam_value_create_boolean(enabled, &enabledval) != NWAM_SUCCESS)
1089 return (0);
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);
1095 return (err);
1099 * Update the enabled property for this location (and for all others
1100 * if necessary.
1102 static int
1103 nwam_loc_update_enabled(nwam_loc_handle_t loch, boolean_t enabled)
1105 nwam_error_t err;
1106 int cb_ret;
1108 if (enabled) {
1110 * Disable all other locations that are manually enabled
1111 * and enable this one - a maximum of 1 location can be
1112 * enabled at once.
1114 err = nwam_walk_locs(loc_set_enabled, loch, 0, &cb_ret);
1115 if (err != NWAM_SUCCESS && err != NWAM_WALK_HALTED)
1116 cb_ret = err;
1117 } else {
1118 cb_ret = loc_set_enabled(loch, NULL);
1120 return (cb_ret);
1123 nwam_error_t
1124 nwam_loc_enable(nwam_loc_handle_t loch)
1126 nwam_error_t err;
1127 boolean_t enabled;
1129 assert(loch != NULL);
1131 /* Make sure location is not enabled */
1132 if ((err = nwam_loc_is_enabled(loch, &enabled)) != NWAM_SUCCESS)
1133 return (err);
1134 if (enabled)
1135 return (NWAM_SUCCESS);
1137 if ((err = nwam_loc_update_enabled(loch, B_TRUE)) != NWAM_SUCCESS)
1138 return (err);
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);
1145 else
1146 return (err);
1149 nwam_error_t
1150 nwam_loc_disable(nwam_loc_handle_t loch)
1152 nwam_error_t err;
1153 boolean_t enabled;
1155 assert(loch != NULL);
1157 /* Make sure location is enabled */
1158 if ((err = nwam_loc_is_enabled(loch, &enabled)) != NWAM_SUCCESS)
1159 return (err);
1160 if (!enabled)
1161 return (NWAM_SUCCESS);
1163 if ((err = nwam_loc_update_enabled(loch, B_FALSE)) != NWAM_SUCCESS)
1164 return (err);
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);
1171 else
1172 return (err);
1175 nwam_error_t
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));
1182 nwam_error_t
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));