1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
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>
36
37 #include "libnwam_impl.h"
38 #include <libnwam_priv.h>
39 #include <libnwam.h>
40
41 /*
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).
48 */
49
50 #define NSSWITCH_PREFIX "/etc/nsswitch."
51
52 typedef nwam_error_t (*nwam_loc_prop_validate_func_t)(nwam_value_t);
53
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);
58
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(5)",
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(8) 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(5) 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(5) 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(5) 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(5))",
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(8)",
161 NWAM_TYPE_ANY, NWAM_CLASS_ANY},
162 };
163
164 #define NWAM_NUM_LOC_PROPS (sizeof (loc_prop_table_entries) / \
165 sizeof (*loc_prop_table_entries))
166
167 struct nwam_prop_table loc_prop_table =
168 { NWAM_NUM_LOC_PROPS, loc_prop_table_entries };
169
170 static uint64_t
nwam_loc_activation_to_flag(nwam_activation_mode_t activation)171 nwam_loc_activation_to_flag(nwam_activation_mode_t activation)
172 {
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);
184 }
185 }
186
187 nwam_error_t
nwam_loc_read(const char * name,uint64_t flags,nwam_loc_handle_t * lochp)188 nwam_loc_read(const char *name, uint64_t flags, nwam_loc_handle_t *lochp)
189 {
190 return (nwam_read(NWAM_OBJECT_TYPE_LOC, NWAM_LOC_CONF_FILE, name,
191 flags, lochp));
192 }
193
194 nwam_error_t
nwam_loc_create(const char * name,nwam_loc_handle_t * lochp)195 nwam_loc_create(const char *name, nwam_loc_handle_t *lochp)
196 {
197 nwam_error_t err;
198 nwam_value_t val = NULL;
199 char *nsswitch = NULL;
200
201 assert(lochp != NULL && name != NULL);
202
203 if ((err = nwam_create(NWAM_OBJECT_TYPE_LOC, NWAM_LOC_CONF_FILE, name,
204 lochp)) != NWAM_SUCCESS)
205 return (err);
206
207 /* Create new object list for loc */
208 if ((err = nwam_alloc_object_list(&((*lochp)->nwh_data)))
209 != NWAM_SUCCESS)
210 goto finish;
211
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;
216 }
217 if ((err = nwam_set_prop_value((*lochp)->nwh_data,
218 NWAM_LOC_PROP_ACTIVATION_MODE, val)) != NWAM_SUCCESS) {
219 goto finish;
220 }
221 nwam_value_free(val);
222 val = NULL;
223
224 /*
225 * NWAM_LOC_PROP_ENABLED defaults to false.
226 */
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;
234
235 /*
236 * Initialize name service properties: use DNS, configured
237 * via DHCP, with default nsswitch (/etc/nsswitch.dns).
238 */
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;
247
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;
256
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;
262 }
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);
267
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;
276 }
277 return (err);
278 }
279
280 nwam_error_t
nwam_loc_get_name(nwam_loc_handle_t loch,char ** namep)281 nwam_loc_get_name(nwam_loc_handle_t loch, char **namep)
282 {
283 return (nwam_get_name(loch, namep));
284 }
285
286 nwam_error_t
nwam_loc_set_name(nwam_loc_handle_t loch,const char * name)287 nwam_loc_set_name(nwam_loc_handle_t loch, const char *name)
288 {
289 return (nwam_set_name(loch, name));
290 }
291
292 boolean_t
nwam_loc_can_set_name(nwam_loc_handle_t loch)293 nwam_loc_can_set_name(nwam_loc_handle_t loch)
294 {
295 return (!loch->nwh_committed);
296 }
297
298 /* ARGSUSED2 */
299 static int
loc_selectcb(struct nwam_handle * hp,uint64_t flags,void * data)300 loc_selectcb(struct nwam_handle *hp, uint64_t flags, void *data)
301 {
302 nwam_loc_handle_t loch = hp;
303 char *locname;
304 uint64_t activation, actflag, walkfilter;
305 nwam_value_t activationval;
306
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);
313 }
314 free(locname);
315
316 /*
317 * Get a bitmapped flag value corresponding to this loc's
318 * activation.
319 */
320 if (nwam_loc_get_prop_value(loch, NWAM_LOC_PROP_ACTIVATION_MODE,
321 &activationval) != NWAM_SUCCESS) {
322 return (NWAM_INVALID_ARG);
323 }
324 if (nwam_value_get_uint64(activationval, &activation) != NWAM_SUCCESS) {
325 nwam_value_free(activationval);
326 return (NWAM_INVALID_ARG);
327 }
328
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);
336 }
337
338 nwam_error_t
nwam_walk_locs(int (* cb)(nwam_loc_handle_t,void *),void * data,uint64_t flags,int * retp)339 nwam_walk_locs(int(*cb)(nwam_loc_handle_t, void *), void *data, uint64_t flags,
340 int *retp)
341 {
342 nwam_error_t err = nwam_valid_flags(flags,
343 NWAM_FLAG_ACTIVATION_MODE_ALL | NWAM_FLAG_BLOCKING);
344
345 if (err != NWAM_SUCCESS)
346 return (err);
347
348 return (nwam_walk(NWAM_OBJECT_TYPE_LOC, NWAM_LOC_CONF_FILE,
349 cb, data, flags, retp, loc_selectcb));
350 }
351
352 void
nwam_loc_free(nwam_loc_handle_t loch)353 nwam_loc_free(nwam_loc_handle_t loch)
354 {
355 nwam_free(loch);
356 }
357
358 nwam_error_t
nwam_loc_delete_prop(nwam_loc_handle_t loch,const char * propname)359 nwam_loc_delete_prop(nwam_loc_handle_t loch, const char *propname)
360 {
361 nwam_error_t err;
362 boolean_t ro;
363 void *olddata;
364
365 assert(loch != NULL && propname != NULL);
366
367 if ((err = nwam_loc_prop_read_only(propname, &ro)) != NWAM_SUCCESS)
368 return (err);
369 if (ro)
370 return (NWAM_ENTITY_READ_ONLY);
371
372 /*
373 * Duplicate data, remove property and validate. If validation
374 * fails, revert to data duplicated prior to remove.
375 */
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);
384 }
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);
389 }
390 nwam_free_object_list(olddata);
391
392 return (NWAM_SUCCESS);
393 }
394
395 nwam_error_t
nwam_loc_set_prop_value(nwam_loc_handle_t loch,const char * propname,nwam_value_t value)396 nwam_loc_set_prop_value(nwam_loc_handle_t loch, const char *propname,
397 nwam_value_t value)
398 {
399 nwam_error_t err;
400 boolean_t ro;
401
402 assert(loch != NULL && propname != NULL && value != NULL);
403
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);
410
411 return (nwam_set_prop_value(loch->nwh_data, propname, value));
412 }
413
414 nwam_error_t
nwam_loc_get_prop_value(nwam_loc_handle_t loch,const char * propname,nwam_value_t * valuep)415 nwam_loc_get_prop_value(nwam_loc_handle_t loch, const char *propname,
416 nwam_value_t *valuep)
417 {
418 return (nwam_get_prop_value(loch->nwh_data, propname, valuep));
419 }
420
421 nwam_error_t
nwam_loc_walk_props(nwam_loc_handle_t loch,int (* cb)(const char *,nwam_value_t,void *),void * data,uint64_t flags,int * retp)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)
425 {
426 return (nwam_walk_props(loch, cb, data, flags, retp));
427 }
428
429 nwam_error_t
nwam_loc_commit(nwam_loc_handle_t loch,uint64_t flags)430 nwam_loc_commit(nwam_loc_handle_t loch, uint64_t flags)
431 {
432 nwam_error_t err;
433
434 assert(loch != NULL && loch->nwh_data != NULL);
435
436 if ((err = nwam_loc_validate(loch, NULL)) != NWAM_SUCCESS)
437 return (err);
438
439 return (nwam_commit(NWAM_LOC_CONF_FILE, loch, flags));
440 }
441
442 nwam_error_t
nwam_loc_destroy(nwam_loc_handle_t loch,uint64_t flags)443 nwam_loc_destroy(nwam_loc_handle_t loch, uint64_t flags)
444 {
445 nwam_error_t err;
446 nwam_value_t actval;
447 uint64_t activation;
448
449 /*
450 * Automatic and NoNet are not destroyable and Legacy is
451 * destroyable by netadm only. These have system activation-mode.
452 */
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);
460
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);
467 }
468 }
469
470 return (nwam_destroy(NWAM_LOC_CONF_FILE, loch, flags));
471 }
472
473 nwam_error_t
nwam_loc_get_prop_description(const char * propname,const char ** descriptionp)474 nwam_loc_get_prop_description(const char *propname, const char **descriptionp)
475 {
476 return (nwam_get_prop_description(loc_prop_table, propname,
477 descriptionp));
478 }
479
480 nwam_error_t
nwam_loc_prop_read_only(const char * propname,boolean_t * readp)481 nwam_loc_prop_read_only(const char *propname, boolean_t *readp)
482 {
483 return (nwam_prop_read_only(loc_prop_table, propname, readp));
484 }
485
486 static nwam_error_t
valid_loc_activation_mode(nwam_value_t value)487 valid_loc_activation_mode(nwam_value_t value)
488 {
489 uint64_t activation_mode;
490
491 if (nwam_value_get_uint64(value, &activation_mode) != NWAM_SUCCESS)
492 return (NWAM_ENTITY_INVALID_VALUE);
493
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);
500 }
501 return (NWAM_ENTITY_INVALID_VALUE);
502 }
503
504 /*
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.
509 */
510 nwam_error_t
valid_loc_condition(nwam_value_t value)511 valid_loc_condition(nwam_value_t value)
512 {
513 char **conditions;
514 uint_t i, numvalues;
515 nwam_condition_object_type_t object_type;
516 nwam_condition_t condition;
517
518 if (nwam_value_get_string_array(value, &conditions, &numvalues)
519 != NWAM_SUCCESS)
520 return (NWAM_ENTITY_INVALID_VALUE);
521
522 for (i = 0; i < numvalues; i++) {
523 char *object_name = NULL;
524
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);
532 }
533 if (object_name != NULL)
534 free(object_name);
535 }
536 return (NWAM_SUCCESS);
537 }
538
539 static nwam_error_t
valid_nameservices(nwam_value_t value)540 valid_nameservices(nwam_value_t value)
541 {
542 uint64_t *nameservices;
543 uint_t i, numvalues;
544
545 if (nwam_value_get_uint64_array(value, &nameservices, &numvalues)
546 != NWAM_SUCCESS)
547 return (NWAM_ENTITY_INVALID_VALUE);
548
549 for (i = 0; i < numvalues; i++) {
550 if (nameservices[i] > NWAM_NAMESERVICES_LDAP)
551 return (NWAM_ENTITY_INVALID_VALUE);
552 }
553 return (NWAM_SUCCESS);
554 }
555
556 static nwam_error_t
valid_configsrc(nwam_value_t value)557 valid_configsrc(nwam_value_t value)
558 {
559 uint64_t *configsrcs;
560 uint_t i, numvalues;
561
562 if (nwam_value_get_uint64_array(value, &configsrcs, &numvalues)
563 != NWAM_SUCCESS)
564 return (NWAM_ENTITY_INVALID_VALUE);
565
566 for (i = 0; i < numvalues; i++) {
567 if (configsrcs[i] > NWAM_CONFIGSRC_DHCP)
568 return (NWAM_ENTITY_INVALID_VALUE);
569 }
570 return (NWAM_SUCCESS);
571 }
572
573 /*
574 * Validates that the activation-mode is system for Automatic and NoNet
575 * locations, and not system for all other locations.
576 */
577 static nwam_error_t
nwam_loc_validate_activation_mode(nwam_loc_handle_t loch,nwam_value_t actval)578 nwam_loc_validate_activation_mode(nwam_loc_handle_t loch, nwam_value_t actval)
579 {
580 nwam_error_t err;
581 uint64_t activation;
582
583 if ((err = nwam_value_get_uint64(actval, &activation)) != NWAM_SUCCESS)
584 return (err);
585
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);
592 }
593 return (NWAM_SUCCESS);
594 }
595
596 /*
597 * Helper function to validate one nameservice, used by
598 * nwam_loc_validate_all_nameservices().
599 *
600 * requiredprop denotes the property that is mandatory when the
601 * configsrcprop is manual. errpropp is used to return the invalid
602 * property.
603 */
604 static nwam_error_t
nwam_loc_validate_one_nameservice(nwam_loc_handle_t loch,const char * configsrcprop,const char * requiredprop,const char ** errpropp)605 nwam_loc_validate_one_nameservice(nwam_loc_handle_t loch,
606 const char *configsrcprop, const char *requiredprop, const char **errpropp)
607 {
608 nwam_value_t configsrcval, requiredval;
609 uint64_t *configsrcs;
610 uint_t i, numvalues;
611
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);
617 }
618
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);
625 }
626
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);
635 }
636 nwam_value_free(requiredval);
637 }
638 }
639 nwam_value_free(configsrcval);
640
641 return (NWAM_SUCCESS);
642 }
643
644 /*
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.
648 */
649 static nwam_error_t
nwam_loc_validate_ldap_nameservice(nwam_loc_handle_t loch,const char ** errpropp)650 nwam_loc_validate_ldap_nameservice(nwam_loc_handle_t loch,
651 const char **errpropp)
652 {
653 nwam_value_t val;
654 uint64_t *configsrcs;
655 uint_t i, numvalues;
656
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);
662 }
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);
670 }
671
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);
680 }
681 }
682 nwam_value_free(val);
683
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);
690 }
691 nwam_value_free(val);
692
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);
698 }
699 nwam_value_free(val);
700
701 return (NWAM_SUCCESS);
702 }
703
704 /*
705 * Validates the different nameservices properties.
706 *
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.
711 *
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.
716 */
717 static nwam_error_t
nwam_loc_validate_all_nameservices(nwam_loc_handle_t loch,nwam_value_t nameservicesval,const char ** errpropp)718 nwam_loc_validate_all_nameservices(nwam_loc_handle_t loch,
719 nwam_value_t nameservicesval, const char **errpropp)
720 {
721 nwam_error_t err;
722 nwam_value_t val;
723 uint64_t *nameservices;
724 uint_t i, numvalues;
725
726 if ((err = nwam_value_get_uint64_array(nameservicesval, &nameservices,
727 &numvalues)) != NWAM_SUCCESS)
728 return (err);
729
730 /*
731 * nameservices-config-file is required if nameservices has more
732 * than one value.
733 */
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);
742 }
743 nwam_value_free(val);
744 } else if (numvalues == 1) {
745 /*
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.
749 */
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;
755
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;
764 }
765
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;
773 }
774
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;
782 }
783 } else if (err != NWAM_SUCCESS) {
784 goto config_file_fail;
785 } else {
786 nwam_value_free(val);
787 }
788 }
789
790 /*
791 * validate the -configsrc property and the required default-domain
792 * and/or -servers property for each nameservice being configured.
793 */
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);
819 }
820 }
821 return (NWAM_SUCCESS);
822
823 config_file_fail:
824 if (errpropp != NULL)
825 *errpropp = NWAM_LOC_PROP_NAMESERVICES_CONFIG_FILE;
826 return (err);
827 }
828
829 nwam_error_t
nwam_loc_validate(nwam_loc_handle_t loch,const char ** errpropp)830 nwam_loc_validate(nwam_loc_handle_t loch, const char **errpropp)
831 {
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;
839
840 assert(loch != NULL);
841
842 /*
843 * Make sure loc is internally consistent: if activation type is
844 * conditional, the condition string must be specified.
845 */
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);
851 }
852
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);
859 }
860
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);
868 }
869 nwam_value_free(activationval);
870
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);
878 }
879 /*
880 * Are conditions self-referential? In other words, do any
881 * of the activation conditions refer to this location?
882 */
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);
889 }
890 if (nwam_loc_get_name(loch, &name) != NWAM_SUCCESS) {
891 nwam_value_free(conditionval);
892 return (NWAM_INVALID_ARG);
893 }
894 for (i = 0; i < numvalues; i++) {
895 char *object_name = NULL;
896
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);
905 }
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);
915 }
916 free(object_name);
917 }
918 free(name);
919 nwam_value_free(conditionval);
920 }
921
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);
928 }
929 err = nwam_loc_validate_all_nameservices(loch, nameservicesval,
930 errpropp);
931 nwam_value_free(nameservicesval);
932 if (err != NWAM_SUCCESS)
933 return (err);
934
935 return (nwam_validate(loc_prop_table, loch, errpropp));
936 }
937
938 nwam_error_t
nwam_loc_validate_prop(nwam_loc_handle_t loch,const char * propname,nwam_value_t value)939 nwam_loc_validate_prop(nwam_loc_handle_t loch, const char *propname,
940 nwam_value_t value)
941 {
942 nwam_error_t err;
943
944 assert(loch != NULL);
945
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);
950 }
951
952 return (nwam_validate_prop(loc_prop_table, loch, propname, value));
953 }
954
955 nwam_error_t
nwam_loc_copy(nwam_loc_handle_t oldloch,const char * newname,nwam_loc_handle_t * newlochp)956 nwam_loc_copy(nwam_loc_handle_t oldloch, const char *newname,
957 nwam_loc_handle_t *newlochp)
958 {
959 nwam_error_t err;
960 nwam_value_t val;
961
962 if ((err = nwam_copy(NWAM_LOC_CONF_FILE, oldloch, newname, newlochp))
963 != NWAM_SUCCESS)
964 return (err);
965
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;
981
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;
990 }
991
992 return (NWAM_SUCCESS);
993
994 finish:
995 nwam_loc_free(*newlochp);
996 *newlochp = NULL;
997 return (err);
998 }
999
1000 /*
1001 * Given a property, return expected property data type
1002 */
1003 nwam_error_t
nwam_loc_get_prop_type(const char * propname,nwam_value_type_t * typep)1004 nwam_loc_get_prop_type(const char *propname, nwam_value_type_t *typep)
1005 {
1006 return (nwam_get_prop_type(loc_prop_table, propname, typep));
1007 }
1008
1009 nwam_error_t
nwam_loc_prop_multivalued(const char * propname,boolean_t * multip)1010 nwam_loc_prop_multivalued(const char *propname, boolean_t *multip)
1011 {
1012 return (nwam_prop_multivalued(loc_prop_table, propname, multip));
1013 }
1014
1015 /*
1016 * Determine if the location has manual activation-mode or not.
1017 */
1018 nwam_error_t
nwam_loc_is_manual(nwam_loc_handle_t loch,boolean_t * manualp)1019 nwam_loc_is_manual(nwam_loc_handle_t loch, boolean_t *manualp)
1020 {
1021 nwam_error_t err;
1022 nwam_value_t actval;
1023 uint64_t activation;
1024
1025 assert(loch != NULL);
1026
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);
1034
1035 if (activation == NWAM_ACTIVATION_MODE_MANUAL)
1036 *manualp = B_TRUE;
1037 else
1038 *manualp = B_FALSE;
1039 return (NWAM_SUCCESS);
1040 }
1041
1042 /* Determine if location is enabled or not */
1043 static nwam_error_t
nwam_loc_is_enabled(nwam_loc_handle_t loch,boolean_t * enabledp)1044 nwam_loc_is_enabled(nwam_loc_handle_t loch, boolean_t *enabledp)
1045 {
1046 nwam_error_t err;
1047 nwam_value_t enabledval;
1048
1049 assert(loch != NULL);
1050
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);
1057 }
1058
1059 /*
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.
1063 */
1064 static int
loc_set_enabled(nwam_loc_handle_t loch,void * data)1065 loc_set_enabled(nwam_loc_handle_t loch, void *data)
1066 {
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;
1071
1072 if (testloch != NULL) {
1073 char *name, *testname;
1074
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;
1080 }
1081 }
1082
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);
1087
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);
1093
1094 nwam_value_free(enabledval);
1095 return (err);
1096 }
1097
1098 /*
1099 * Update the enabled property for this location (and for all others
1100 * if necessary.
1101 */
1102 static int
nwam_loc_update_enabled(nwam_loc_handle_t loch,boolean_t enabled)1103 nwam_loc_update_enabled(nwam_loc_handle_t loch, boolean_t enabled)
1104 {
1105 nwam_error_t err;
1106 int cb_ret;
1107
1108 if (enabled) {
1109 /*
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.
1113 */
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);
1119 }
1120 return (cb_ret);
1121 }
1122
1123 nwam_error_t
nwam_loc_enable(nwam_loc_handle_t loch)1124 nwam_loc_enable(nwam_loc_handle_t loch)
1125 {
1126 nwam_error_t err;
1127 boolean_t enabled;
1128
1129 assert(loch != NULL);
1130
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);
1136
1137 if ((err = nwam_loc_update_enabled(loch, B_TRUE)) != NWAM_SUCCESS)
1138 return (err);
1139
1140 err = nwam_enable(NULL, loch);
1141
1142 /* nwamd may not be running, that's okay. */
1143 if (err == NWAM_ERROR_BIND)
1144 return (NWAM_SUCCESS);
1145 else
1146 return (err);
1147 }
1148
1149 nwam_error_t
nwam_loc_disable(nwam_loc_handle_t loch)1150 nwam_loc_disable(nwam_loc_handle_t loch)
1151 {
1152 nwam_error_t err;
1153 boolean_t enabled;
1154
1155 assert(loch != NULL);
1156
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);
1162
1163 if ((err = nwam_loc_update_enabled(loch, B_FALSE)) != NWAM_SUCCESS)
1164 return (err);
1165
1166 err = nwam_disable(NULL, loch);
1167
1168 /* nwamd may not be running, that's okay. */
1169 if (err == NWAM_ERROR_BIND)
1170 return (NWAM_SUCCESS);
1171 else
1172 return (err);
1173 }
1174
1175 nwam_error_t
nwam_loc_get_default_proplist(const char *** prop_list,uint_t * numvaluesp)1176 nwam_loc_get_default_proplist(const char ***prop_list, uint_t *numvaluesp)
1177 {
1178 return (nwam_get_default_proplist(loc_prop_table,
1179 NWAM_TYPE_ANY, NWAM_CLASS_ANY, prop_list, numvaluesp));
1180 }
1181
1182 nwam_error_t
nwam_loc_get_state(nwam_loc_handle_t loch,nwam_state_t * statep,nwam_aux_state_t * auxp)1183 nwam_loc_get_state(nwam_loc_handle_t loch, nwam_state_t *statep,
1184 nwam_aux_state_t *auxp)
1185 {
1186 return (nwam_get_state(NULL, loch, statep, auxp));
1187 }
1188