dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libnwam / common / libnwam_loc.c
blob52b50240128d8a067c6b9a1ec8cc7501205ca0b5
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 free(nsswitch);
270 if (val != NULL)
271 nwam_value_free(val);
272 if (err != NWAM_SUCCESS) {
273 nwam_loc_free(*lochp);
274 *lochp = NULL;
276 return (err);
279 nwam_error_t
280 nwam_loc_get_name(nwam_loc_handle_t loch, char **namep)
282 return (nwam_get_name(loch, namep));
285 nwam_error_t
286 nwam_loc_set_name(nwam_loc_handle_t loch, const char *name)
288 return (nwam_set_name(loch, name));
291 boolean_t
292 nwam_loc_can_set_name(nwam_loc_handle_t loch)
294 return (!loch->nwh_committed);
297 /* ARGSUSED2 */
298 static int
299 loc_selectcb(struct nwam_handle *hp, uint64_t flags, void *data)
301 nwam_loc_handle_t loch = hp;
302 char *locname;
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) {
310 free(locname);
311 return (NWAM_INVALID_ARG);
313 free(locname);
316 * Get a bitmapped flag value corresponding to this loc's
317 * activation.
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);
337 nwam_error_t
338 nwam_walk_locs(int(*cb)(nwam_loc_handle_t, void *), void *data, uint64_t flags,
339 int *retp)
341 nwam_error_t err = nwam_valid_flags(flags,
342 NWAM_FLAG_ACTIVATION_MODE_ALL | NWAM_FLAG_BLOCKING);
344 if (err != NWAM_SUCCESS)
345 return (err);
347 return (nwam_walk(NWAM_OBJECT_TYPE_LOC, NWAM_LOC_CONF_FILE,
348 cb, data, flags, retp, loc_selectcb));
351 void
352 nwam_loc_free(nwam_loc_handle_t loch)
354 nwam_free(loch);
357 nwam_error_t
358 nwam_loc_delete_prop(nwam_loc_handle_t loch, const char *propname)
360 nwam_error_t err;
361 boolean_t ro;
362 void *olddata;
364 assert(loch != NULL && propname != NULL);
366 if ((err = nwam_loc_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
367 return (err);
368 if (ro)
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))
376 != NWAM_SUCCESS)
377 return (err);
378 if ((err = nwam_delete_prop(loch->nwh_data, propname))
379 != NWAM_SUCCESS) {
380 nwam_free_object_list(loch->nwh_data);
381 loch->nwh_data = olddata;
382 return (err);
384 if ((err = nwam_loc_validate(loch, NULL)) != NWAM_SUCCESS) {
385 nwam_free_object_list(loch->nwh_data);
386 loch->nwh_data = olddata;
387 return (err);
389 nwam_free_object_list(olddata);
391 return (NWAM_SUCCESS);
394 nwam_error_t
395 nwam_loc_set_prop_value(nwam_loc_handle_t loch, const char *propname,
396 nwam_value_t value)
398 nwam_error_t err;
399 boolean_t ro;
401 assert(loch != NULL && propname != NULL && value != NULL);
403 if ((err = nwam_loc_validate_prop(loch, propname, value))
404 != NWAM_SUCCESS ||
405 (err = nwam_loc_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
406 return (err);
407 if (ro)
408 return (NWAM_ENTITY_READ_ONLY);
410 return (nwam_set_prop_value(loch->nwh_data, propname, value));
413 nwam_error_t
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));
420 nwam_error_t
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));
428 nwam_error_t
429 nwam_loc_commit(nwam_loc_handle_t loch, uint64_t flags)
431 nwam_error_t err;
433 assert(loch != NULL && loch->nwh_data != NULL);
435 if ((err = nwam_loc_validate(loch, NULL)) != NWAM_SUCCESS)
436 return (err);
438 return (nwam_commit(NWAM_LOC_CONF_FILE, loch, flags));
441 nwam_error_t
442 nwam_loc_destroy(nwam_loc_handle_t loch, uint64_t flags)
444 nwam_error_t err;
445 nwam_value_t actval;
446 uint64_t activation;
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)
454 return (err);
455 err = nwam_value_get_uint64(actval, &activation);
456 nwam_value_free(actval);
457 if (err != NWAM_SUCCESS)
458 return (err);
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);
464 } else {
465 return (NWAM_ENTITY_NOT_DESTROYABLE);
469 return (nwam_destroy(NWAM_LOC_CONF_FILE, loch, flags));
472 nwam_error_t
473 nwam_loc_get_prop_description(const char *propname, const char **descriptionp)
475 return (nwam_get_prop_description(loc_prop_table, propname,
476 descriptionp));
479 nwam_error_t
480 nwam_loc_prop_read_only(const char *propname, boolean_t *readp)
482 return (nwam_prop_read_only(loc_prop_table, propname, readp));
485 static nwam_error_t
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.
509 nwam_error_t
510 valid_loc_condition(nwam_value_t value)
512 char **conditions;
513 uint_t i, numvalues;
514 nwam_condition_object_type_t object_type;
515 nwam_condition_t condition;
517 if (nwam_value_get_string_array(value, &conditions, &numvalues)
518 != NWAM_SUCCESS)
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) {
529 free(object_name);
530 return (NWAM_ENTITY_INVALID_VALUE);
532 free(object_name);
534 return (NWAM_SUCCESS);
537 static nwam_error_t
538 valid_nameservices(nwam_value_t value)
540 uint64_t *nameservices;
541 uint_t i, numvalues;
543 if (nwam_value_get_uint64_array(value, &nameservices, &numvalues)
544 != NWAM_SUCCESS)
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);
554 static nwam_error_t
555 valid_configsrc(nwam_value_t value)
557 uint64_t *configsrcs;
558 uint_t i, numvalues;
560 if (nwam_value_get_uint64_array(value, &configsrcs, &numvalues)
561 != NWAM_SUCCESS)
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.
575 static nwam_error_t
576 nwam_loc_validate_activation_mode(nwam_loc_handle_t loch, nwam_value_t actval)
578 nwam_error_t err;
579 uint64_t activation;
581 if ((err = nwam_value_get_uint64(actval, &activation)) != NWAM_SUCCESS)
582 return (err);
584 if (NWAM_LOC_NAME_PRE_DEFINED(loch->nwh_name)) {
585 if (activation != NWAM_ACTIVATION_MODE_SYSTEM)
586 return (NWAM_ENTITY_INVALID_VALUE);
587 } else {
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
600 * property.
602 static nwam_error_t
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;
608 uint_t i, numvalues;
610 if (nwam_loc_get_prop_value(loch, configsrcprop, &configsrcval)
611 != NWAM_SUCCESS) {
612 if (errpropp != NULL)
613 *errpropp = configsrcprop;
614 return (NWAM_ENTITY_MISSING_MEMBER);
617 if (nwam_value_get_uint64_array(configsrcval, &configsrcs, &numvalues)
618 != NWAM_SUCCESS) {
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.
647 static nwam_error_t
648 nwam_loc_validate_ldap_nameservice(nwam_loc_handle_t loch,
649 const char **errpropp)
651 nwam_value_t val;
652 uint64_t *configsrcs;
653 uint_t i, numvalues;
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)
663 != NWAM_SUCCESS) {
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)
674 *errpropp =
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.
715 static nwam_error_t
716 nwam_loc_validate_all_nameservices(nwam_loc_handle_t loch,
717 nwam_value_t nameservicesval, const char **errpropp)
719 nwam_error_t err;
720 nwam_value_t val;
721 uint64_t *nameservices;
722 uint_t i, numvalues;
724 if ((err = nwam_value_get_uint64_array(nameservicesval, &nameservices,
725 &numvalues)) != NWAM_SUCCESS)
726 return (err);
729 * nameservices-config-file is required if nameservices has more
730 * than one value.
732 if (numvalues > 1) {
733 if (nwam_loc_get_prop_value(loch,
734 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE, &val)
735 != NWAM_SUCCESS) {
736 if (errpropp != NULL)
737 *errpropp =
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) {
751 char *nsswitch;
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))
768 != NWAM_SUCCESS) {
769 free(nsswitch);
770 goto config_file_fail;
773 err = nwam_set_prop_value(loch->nwh_data,
774 NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE, val);
775 free(nsswitch);
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;
783 } else {
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))
798 != NWAM_SUCCESS)
799 return (err);
800 break;
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))
805 != NWAM_SUCCESS)
806 return (err);
807 break;
808 case NWAM_NAMESERVICES_LDAP:
809 if ((err = nwam_loc_validate_ldap_nameservice(loch,
810 errpropp)) != NWAM_SUCCESS)
811 return (err);
812 break;
813 case NWAM_NAMESERVICES_FILES:
814 break;
815 default:
816 return (NWAM_ENTITY_INVALID_VALUE);
819 return (NWAM_SUCCESS);
821 config_file_fail:
822 if (errpropp != NULL)
823 *errpropp = NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE;
824 return (err);
827 nwam_error_t
828 nwam_loc_validate(nwam_loc_handle_t loch, const char **errpropp)
830 nwam_error_t err;
831 nwam_value_t activationval, conditionval, nameservicesval;
832 uint64_t activation;
833 char **conditions, *name;
834 uint_t i, numvalues;
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)
852 != NWAM_SUCCESS) {
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))
861 != NWAM_SUCCESS) {
862 if (errpropp != NULL)
863 *errpropp = NWAM_LOC_PROP_ACTIVATION_MODE;
864 nwam_value_free(activationval);
865 return (err);
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)
897 != NWAM_SUCCESS) {
898 if (errpropp != NULL)
899 *errpropp = NWAM_LOC_PROP_CONDITIONS;
900 free(name);
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;
909 free(name);
910 free(object_name);
911 nwam_value_free(conditionval);
912 return (NWAM_ENTITY_INVALID_VALUE);
914 free(object_name);
916 free(name);
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,
928 errpropp);
929 nwam_value_free(nameservicesval);
930 if (err != NWAM_SUCCESS)
931 return (err);
933 return (nwam_validate(loc_prop_table, loch, errpropp));
936 nwam_error_t
937 nwam_loc_validate_prop(nwam_loc_handle_t loch, const char *propname,
938 nwam_value_t value)
940 nwam_error_t err;
942 assert(loch != NULL);
944 if (strcmp(propname, NWAM_LOC_PROP_ACTIVATION_MODE) == 0) {
945 if ((err = nwam_loc_validate_activation_mode(loch, value))
946 != NWAM_SUCCESS)
947 return (err);
950 return (nwam_validate_prop(loc_prop_table, loch, propname, value));
953 nwam_error_t
954 nwam_loc_copy(nwam_loc_handle_t oldloch, const char *newname,
955 nwam_loc_handle_t *newlochp)
957 nwam_error_t err;
958 nwam_value_t val;
960 if ((err = nwam_copy(NWAM_LOC_CONF_FILE, oldloch, newname, newlochp))
961 != NWAM_SUCCESS)
962 return (err);
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)
967 goto finish;
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)
973 goto finish;
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)
978 goto finish;
980 if ((err = nwam_value_create_boolean(B_FALSE, &val))
981 != NWAM_SUCCESS)
982 goto finish;
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)
987 goto finish;
990 return (NWAM_SUCCESS);
992 finish:
993 nwam_loc_free(*newlochp);
994 *newlochp = NULL;
995 return (err);
999 * Given a property, return expected property data type
1001 nwam_error_t
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));
1007 nwam_error_t
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.
1016 nwam_error_t
1017 nwam_loc_is_manual(nwam_loc_handle_t loch, boolean_t *manualp)
1019 nwam_error_t err;
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)
1027 return (err);
1028 err = nwam_value_get_uint64(actval, &activation);
1029 nwam_value_free(actval);
1030 if (err != NWAM_SUCCESS)
1031 return (err);
1033 if (activation == NWAM_ACTIVATION_MODE_MANUAL)
1034 *manualp = B_TRUE;
1035 else
1036 *manualp = B_FALSE;
1037 return (NWAM_SUCCESS);
1040 /* Determine if location is enabled or not */
1041 static nwam_error_t
1042 nwam_loc_is_enabled(nwam_loc_handle_t loch, boolean_t *enabledp)
1044 nwam_error_t err;
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)
1051 return (err);
1052 err = nwam_value_get_boolean(enabledval, enabledp);
1053 nwam_value_free(enabledval);
1054 return (err);
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
1060 * all locations.
1062 static int
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. */
1077 enabled = B_TRUE;
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)
1084 return (0);
1086 if (nwam_value_create_boolean(enabled, &enabledval) != NWAM_SUCCESS)
1087 return (0);
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);
1093 return (err);
1097 * Update the enabled property for this location (and for all others
1098 * if necessary.
1100 static int
1101 nwam_loc_update_enabled(nwam_loc_handle_t loch, boolean_t enabled)
1103 nwam_error_t err;
1104 int cb_ret;
1106 if (enabled) {
1108 * Disable all other locations that are manually enabled
1109 * and enable this one - a maximum of 1 location can be
1110 * enabled at once.
1112 err = nwam_walk_locs(loc_set_enabled, loch, 0, &cb_ret);
1113 if (err != NWAM_SUCCESS && err != NWAM_WALK_HALTED)
1114 cb_ret = err;
1115 } else {
1116 cb_ret = loc_set_enabled(loch, NULL);
1118 return (cb_ret);
1121 nwam_error_t
1122 nwam_loc_enable(nwam_loc_handle_t loch)
1124 nwam_error_t err;
1125 boolean_t enabled;
1127 assert(loch != NULL);
1129 /* Make sure location is not enabled */
1130 if ((err = nwam_loc_is_enabled(loch, &enabled)) != NWAM_SUCCESS)
1131 return (err);
1132 if (enabled)
1133 return (NWAM_SUCCESS);
1135 if ((err = nwam_loc_update_enabled(loch, B_TRUE)) != NWAM_SUCCESS)
1136 return (err);
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);
1143 else
1144 return (err);
1147 nwam_error_t
1148 nwam_loc_disable(nwam_loc_handle_t loch)
1150 nwam_error_t err;
1151 boolean_t enabled;
1153 assert(loch != NULL);
1155 /* Make sure location is enabled */
1156 if ((err = nwam_loc_is_enabled(loch, &enabled)) != NWAM_SUCCESS)
1157 return (err);
1158 if (!enabled)
1159 return (NWAM_SUCCESS);
1161 if ((err = nwam_loc_update_enabled(loch, B_FALSE)) != NWAM_SUCCESS)
1162 return (err);
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);
1169 else
1170 return (err);
1173 nwam_error_t
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));
1180 nwam_error_t
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));