1*13080SPavan.Mettu@Oracle.COM /*
2*13080SPavan.Mettu@Oracle.COM * CDDL HEADER START
3*13080SPavan.Mettu@Oracle.COM *
4*13080SPavan.Mettu@Oracle.COM * The contents of this file are subject to the terms of the
5*13080SPavan.Mettu@Oracle.COM * Common Development and Distribution License (the "License").
6*13080SPavan.Mettu@Oracle.COM * You may not use this file except in compliance with the License.
7*13080SPavan.Mettu@Oracle.COM *
8*13080SPavan.Mettu@Oracle.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*13080SPavan.Mettu@Oracle.COM * or http://www.opensolaris.org/os/licensing.
10*13080SPavan.Mettu@Oracle.COM * See the License for the specific language governing permissions
11*13080SPavan.Mettu@Oracle.COM * and limitations under the License.
12*13080SPavan.Mettu@Oracle.COM *
13*13080SPavan.Mettu@Oracle.COM * When distributing Covered Code, include this CDDL HEADER in each
14*13080SPavan.Mettu@Oracle.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*13080SPavan.Mettu@Oracle.COM * If applicable, add the following below this CDDL HEADER, with the
16*13080SPavan.Mettu@Oracle.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*13080SPavan.Mettu@Oracle.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*13080SPavan.Mettu@Oracle.COM *
19*13080SPavan.Mettu@Oracle.COM * CDDL HEADER END
20*13080SPavan.Mettu@Oracle.COM */
21*13080SPavan.Mettu@Oracle.COM
22*13080SPavan.Mettu@Oracle.COM /*
23*13080SPavan.Mettu@Oracle.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*13080SPavan.Mettu@Oracle.COM */
25*13080SPavan.Mettu@Oracle.COM
26*13080SPavan.Mettu@Oracle.COM /*
27*13080SPavan.Mettu@Oracle.COM * AUTOMOUNT specific functions
28*13080SPavan.Mettu@Oracle.COM */
29*13080SPavan.Mettu@Oracle.COM #include <stdio.h>
30*13080SPavan.Mettu@Oracle.COM #include <string.h>
31*13080SPavan.Mettu@Oracle.COM #include <ctype.h>
32*13080SPavan.Mettu@Oracle.COM #include <stdlib.h>
33*13080SPavan.Mettu@Oracle.COM #include <unistd.h>
34*13080SPavan.Mettu@Oracle.COM #include <zone.h>
35*13080SPavan.Mettu@Oracle.COM #include <errno.h>
36*13080SPavan.Mettu@Oracle.COM #include <locale.h>
37*13080SPavan.Mettu@Oracle.COM #include <fcntl.h>
38*13080SPavan.Mettu@Oracle.COM #include <sys/types.h>
39*13080SPavan.Mettu@Oracle.COM #include <sys/stat.h>
40*13080SPavan.Mettu@Oracle.COM #include <syslog.h>
41*13080SPavan.Mettu@Oracle.COM #include "libshare.h"
42*13080SPavan.Mettu@Oracle.COM #include "libshare_impl.h"
43*13080SPavan.Mettu@Oracle.COM #include <pwd.h>
44*13080SPavan.Mettu@Oracle.COM #include <limits.h>
45*13080SPavan.Mettu@Oracle.COM #include <libscf.h>
46*13080SPavan.Mettu@Oracle.COM #include <strings.h>
47*13080SPavan.Mettu@Oracle.COM #include <libdlpi.h>
48*13080SPavan.Mettu@Oracle.COM #include "smfcfg.h"
49*13080SPavan.Mettu@Oracle.COM
50*13080SPavan.Mettu@Oracle.COM
51*13080SPavan.Mettu@Oracle.COM static int autofs_init();
52*13080SPavan.Mettu@Oracle.COM static void autofs_fini();
53*13080SPavan.Mettu@Oracle.COM static int autofs_validate_property(sa_handle_t, sa_property_t, sa_optionset_t);
54*13080SPavan.Mettu@Oracle.COM static int autofs_set_proto_prop(sa_property_t);
55*13080SPavan.Mettu@Oracle.COM static sa_protocol_properties_t autofs_get_proto_set();
56*13080SPavan.Mettu@Oracle.COM static char *autofs_get_status();
57*13080SPavan.Mettu@Oracle.COM static uint64_t autofs_features();
58*13080SPavan.Mettu@Oracle.COM
59*13080SPavan.Mettu@Oracle.COM static int initautofsprotofromsmf();
60*13080SPavan.Mettu@Oracle.COM static int true_false_validator(int index, char *value);
61*13080SPavan.Mettu@Oracle.COM static int strlen_validator(int index, char *value);
62*13080SPavan.Mettu@Oracle.COM static int range_check_validator(int index, char *value);
63*13080SPavan.Mettu@Oracle.COM
64*13080SPavan.Mettu@Oracle.COM /*
65*13080SPavan.Mettu@Oracle.COM * ops vector that provides the protocol specific info and operations
66*13080SPavan.Mettu@Oracle.COM * for share management.
67*13080SPavan.Mettu@Oracle.COM */
68*13080SPavan.Mettu@Oracle.COM struct sa_plugin_ops sa_plugin_ops = {
69*13080SPavan.Mettu@Oracle.COM SA_PLUGIN_VERSION,
70*13080SPavan.Mettu@Oracle.COM "autofs",
71*13080SPavan.Mettu@Oracle.COM autofs_init, /* Init autofs */
72*13080SPavan.Mettu@Oracle.COM autofs_fini, /* Fini autofs */
73*13080SPavan.Mettu@Oracle.COM NULL, /* Start Sharing */
74*13080SPavan.Mettu@Oracle.COM NULL, /* stop sharing */
75*13080SPavan.Mettu@Oracle.COM autofs_validate_property,
76*13080SPavan.Mettu@Oracle.COM NULL, /* valid_space */
77*13080SPavan.Mettu@Oracle.COM NULL, /* security_prop */
78*13080SPavan.Mettu@Oracle.COM NULL, /* parse optstring */
79*13080SPavan.Mettu@Oracle.COM NULL, /* format optstring */
80*13080SPavan.Mettu@Oracle.COM autofs_set_proto_prop, /* Set properties */
81*13080SPavan.Mettu@Oracle.COM autofs_get_proto_set, /* get properties */
82*13080SPavan.Mettu@Oracle.COM autofs_get_status, /* get status */
83*13080SPavan.Mettu@Oracle.COM NULL, /* space_alias */
84*13080SPavan.Mettu@Oracle.COM NULL, /* update_legacy */
85*13080SPavan.Mettu@Oracle.COM NULL, /* delete_legacy */
86*13080SPavan.Mettu@Oracle.COM NULL, /* change notify */
87*13080SPavan.Mettu@Oracle.COM NULL, /* enable resource */
88*13080SPavan.Mettu@Oracle.COM NULL, /* disable resource */
89*13080SPavan.Mettu@Oracle.COM autofs_features, /* features */
90*13080SPavan.Mettu@Oracle.COM NULL, /* transient shares */
91*13080SPavan.Mettu@Oracle.COM NULL, /* notify resource */
92*13080SPavan.Mettu@Oracle.COM NULL, /* rename resource */
93*13080SPavan.Mettu@Oracle.COM NULL, /* run_command */
94*13080SPavan.Mettu@Oracle.COM NULL, /* command_help */
95*13080SPavan.Mettu@Oracle.COM NULL /* delete_proto_section */
96*13080SPavan.Mettu@Oracle.COM };
97*13080SPavan.Mettu@Oracle.COM
98*13080SPavan.Mettu@Oracle.COM
99*13080SPavan.Mettu@Oracle.COM static sa_protocol_properties_t protoset;
100*13080SPavan.Mettu@Oracle.COM
101*13080SPavan.Mettu@Oracle.COM #define AUTOMOUNT_VERBOSE_DEFAULT 0
102*13080SPavan.Mettu@Oracle.COM #define AUTOMOUNTD_VERBOSE_DEFAULT 0
103*13080SPavan.Mettu@Oracle.COM #define AUTOMOUNT_NOBROWSE_DEFAULT 0
104*13080SPavan.Mettu@Oracle.COM #define AUTOMOUNT_TIMEOUT_DEFAULT 600
105*13080SPavan.Mettu@Oracle.COM #define AUTOMOUNT_TRACE_DEFAULT 0
106*13080SPavan.Mettu@Oracle.COM /*
107*13080SPavan.Mettu@Oracle.COM * Protocol Management functions
108*13080SPavan.Mettu@Oracle.COM */
109*13080SPavan.Mettu@Oracle.COM struct proto_option_defs {
110*13080SPavan.Mettu@Oracle.COM char *tag;
111*13080SPavan.Mettu@Oracle.COM char *name; /* display name -- remove protocol identifier */
112*13080SPavan.Mettu@Oracle.COM int index;
113*13080SPavan.Mettu@Oracle.COM scf_type_t type;
114*13080SPavan.Mettu@Oracle.COM union {
115*13080SPavan.Mettu@Oracle.COM int intval;
116*13080SPavan.Mettu@Oracle.COM char *string;
117*13080SPavan.Mettu@Oracle.COM } defvalue;
118*13080SPavan.Mettu@Oracle.COM int32_t minval;
119*13080SPavan.Mettu@Oracle.COM int32_t maxval;
120*13080SPavan.Mettu@Oracle.COM int (*check)(int, char *);
121*13080SPavan.Mettu@Oracle.COM } proto_options[] = {
122*13080SPavan.Mettu@Oracle.COM #define PROTO_OPT_AUTOMOUNT_TIMEOUT 0
123*13080SPavan.Mettu@Oracle.COM { "timeout",
124*13080SPavan.Mettu@Oracle.COM "timeout", PROTO_OPT_AUTOMOUNT_TIMEOUT,
125*13080SPavan.Mettu@Oracle.COM SCF_TYPE_INTEGER, AUTOMOUNT_TIMEOUT_DEFAULT,
126*13080SPavan.Mettu@Oracle.COM 1, INT32_MAX, range_check_validator},
127*13080SPavan.Mettu@Oracle.COM #define PROTO_OPT_AUTOMOUNT_VERBOSE 1
128*13080SPavan.Mettu@Oracle.COM { "automount_verbose",
129*13080SPavan.Mettu@Oracle.COM "automount_verbose", PROTO_OPT_AUTOMOUNT_VERBOSE,
130*13080SPavan.Mettu@Oracle.COM SCF_TYPE_BOOLEAN, AUTOMOUNT_VERBOSE_DEFAULT, 0, 1,
131*13080SPavan.Mettu@Oracle.COM true_false_validator},
132*13080SPavan.Mettu@Oracle.COM #define PROTO_OPT_AUTOMOUNTD_VERBOSE 2
133*13080SPavan.Mettu@Oracle.COM { "automountd_verbose",
134*13080SPavan.Mettu@Oracle.COM "automountd_verbose", PROTO_OPT_AUTOMOUNTD_VERBOSE,
135*13080SPavan.Mettu@Oracle.COM SCF_TYPE_BOOLEAN, AUTOMOUNTD_VERBOSE_DEFAULT, 0, 1,
136*13080SPavan.Mettu@Oracle.COM true_false_validator},
137*13080SPavan.Mettu@Oracle.COM #define PROTO_OPT_AUTOMOUNTD_NOBROWSE 3
138*13080SPavan.Mettu@Oracle.COM { "nobrowse",
139*13080SPavan.Mettu@Oracle.COM "nobrowse", PROTO_OPT_AUTOMOUNTD_NOBROWSE, SCF_TYPE_BOOLEAN,
140*13080SPavan.Mettu@Oracle.COM AUTOMOUNT_NOBROWSE_DEFAULT, 0, 1, true_false_validator},
141*13080SPavan.Mettu@Oracle.COM #define PROTO_OPT_AUTOMOUNTD_TRACE 4
142*13080SPavan.Mettu@Oracle.COM { "trace",
143*13080SPavan.Mettu@Oracle.COM "trace", PROTO_OPT_AUTOMOUNTD_TRACE,
144*13080SPavan.Mettu@Oracle.COM SCF_TYPE_INTEGER, AUTOMOUNT_TRACE_DEFAULT,
145*13080SPavan.Mettu@Oracle.COM 0, 20, range_check_validator},
146*13080SPavan.Mettu@Oracle.COM #define PROTO_OPT_AUTOMOUNTD_ENV 5
147*13080SPavan.Mettu@Oracle.COM { "environment",
148*13080SPavan.Mettu@Oracle.COM "environment", PROTO_OPT_AUTOMOUNTD_ENV, SCF_TYPE_ASTRING,
149*13080SPavan.Mettu@Oracle.COM NULL, 0, 1024, strlen_validator},
150*13080SPavan.Mettu@Oracle.COM {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
151*13080SPavan.Mettu@Oracle.COM };
152*13080SPavan.Mettu@Oracle.COM
153*13080SPavan.Mettu@Oracle.COM #define AUTOFS_PROP_MAX (sizeof (proto_options) / sizeof (proto_options[0]))
154*13080SPavan.Mettu@Oracle.COM
155*13080SPavan.Mettu@Oracle.COM static void
add_defaults()156*13080SPavan.Mettu@Oracle.COM add_defaults()
157*13080SPavan.Mettu@Oracle.COM {
158*13080SPavan.Mettu@Oracle.COM int i;
159*13080SPavan.Mettu@Oracle.COM char number[MAXDIGITS];
160*13080SPavan.Mettu@Oracle.COM
161*13080SPavan.Mettu@Oracle.COM for (i = 0; proto_options[i].tag != NULL; i++) {
162*13080SPavan.Mettu@Oracle.COM sa_property_t prop;
163*13080SPavan.Mettu@Oracle.COM prop = sa_get_protocol_property(protoset,
164*13080SPavan.Mettu@Oracle.COM proto_options[i].name);
165*13080SPavan.Mettu@Oracle.COM if (prop == NULL) {
166*13080SPavan.Mettu@Oracle.COM /* add the default value */
167*13080SPavan.Mettu@Oracle.COM switch (proto_options[i].type) {
168*13080SPavan.Mettu@Oracle.COM case SCF_TYPE_INTEGER:
169*13080SPavan.Mettu@Oracle.COM (void) snprintf(number, sizeof (number), "%d",
170*13080SPavan.Mettu@Oracle.COM proto_options[i].defvalue.intval);
171*13080SPavan.Mettu@Oracle.COM prop = sa_create_property(proto_options[i].name,
172*13080SPavan.Mettu@Oracle.COM number);
173*13080SPavan.Mettu@Oracle.COM break;
174*13080SPavan.Mettu@Oracle.COM
175*13080SPavan.Mettu@Oracle.COM case SCF_TYPE_BOOLEAN:
176*13080SPavan.Mettu@Oracle.COM prop = sa_create_property(proto_options[i].name,
177*13080SPavan.Mettu@Oracle.COM proto_options[i].defvalue.intval ?
178*13080SPavan.Mettu@Oracle.COM "true" : "false");
179*13080SPavan.Mettu@Oracle.COM break;
180*13080SPavan.Mettu@Oracle.COM
181*13080SPavan.Mettu@Oracle.COM default:
182*13080SPavan.Mettu@Oracle.COM /* treat as strings of zero length */
183*13080SPavan.Mettu@Oracle.COM prop = sa_create_property(proto_options[i].name,
184*13080SPavan.Mettu@Oracle.COM "");
185*13080SPavan.Mettu@Oracle.COM break;
186*13080SPavan.Mettu@Oracle.COM }
187*13080SPavan.Mettu@Oracle.COM if (prop != NULL)
188*13080SPavan.Mettu@Oracle.COM (void) sa_add_protocol_property(protoset, prop);
189*13080SPavan.Mettu@Oracle.COM }
190*13080SPavan.Mettu@Oracle.COM }
191*13080SPavan.Mettu@Oracle.COM }
192*13080SPavan.Mettu@Oracle.COM
193*13080SPavan.Mettu@Oracle.COM static int
autofs_init()194*13080SPavan.Mettu@Oracle.COM autofs_init()
195*13080SPavan.Mettu@Oracle.COM {
196*13080SPavan.Mettu@Oracle.COM int ret = SA_OK;
197*13080SPavan.Mettu@Oracle.COM
198*13080SPavan.Mettu@Oracle.COM if (sa_plugin_ops.sa_init != autofs_init) {
199*13080SPavan.Mettu@Oracle.COM (void) printf(dgettext(TEXT_DOMAIN,
200*13080SPavan.Mettu@Oracle.COM "AUTOFS plugin not installed properly\n"));
201*13080SPavan.Mettu@Oracle.COM return (SA_CONFIG_ERR);
202*13080SPavan.Mettu@Oracle.COM }
203*13080SPavan.Mettu@Oracle.COM
204*13080SPavan.Mettu@Oracle.COM ret = initautofsprotofromsmf();
205*13080SPavan.Mettu@Oracle.COM if (ret != SA_OK) {
206*13080SPavan.Mettu@Oracle.COM (void) printf(dgettext(TEXT_DOMAIN,
207*13080SPavan.Mettu@Oracle.COM "AUTOFS plugin problem with SMF properties: %s\n"),
208*13080SPavan.Mettu@Oracle.COM sa_errorstr(ret));
209*13080SPavan.Mettu@Oracle.COM ret = SA_OK;
210*13080SPavan.Mettu@Oracle.COM }
211*13080SPavan.Mettu@Oracle.COM add_defaults();
212*13080SPavan.Mettu@Oracle.COM return (ret);
213*13080SPavan.Mettu@Oracle.COM }
214*13080SPavan.Mettu@Oracle.COM
215*13080SPavan.Mettu@Oracle.COM static void
free_protoprops()216*13080SPavan.Mettu@Oracle.COM free_protoprops()
217*13080SPavan.Mettu@Oracle.COM {
218*13080SPavan.Mettu@Oracle.COM if (protoset != NULL) {
219*13080SPavan.Mettu@Oracle.COM xmlFreeNode(protoset);
220*13080SPavan.Mettu@Oracle.COM protoset = NULL;
221*13080SPavan.Mettu@Oracle.COM }
222*13080SPavan.Mettu@Oracle.COM }
223*13080SPavan.Mettu@Oracle.COM
224*13080SPavan.Mettu@Oracle.COM static void
autofs_fini()225*13080SPavan.Mettu@Oracle.COM autofs_fini()
226*13080SPavan.Mettu@Oracle.COM {
227*13080SPavan.Mettu@Oracle.COM free_protoprops();
228*13080SPavan.Mettu@Oracle.COM }
229*13080SPavan.Mettu@Oracle.COM
230*13080SPavan.Mettu@Oracle.COM static int
findprotoopt(char * propname)231*13080SPavan.Mettu@Oracle.COM findprotoopt(char *propname)
232*13080SPavan.Mettu@Oracle.COM {
233*13080SPavan.Mettu@Oracle.COM int i;
234*13080SPavan.Mettu@Oracle.COM
235*13080SPavan.Mettu@Oracle.COM for (i = 0; proto_options[i].tag != NULL; i++)
236*13080SPavan.Mettu@Oracle.COM if (strcmp(proto_options[i].name, propname) == 0)
237*13080SPavan.Mettu@Oracle.COM return (i);
238*13080SPavan.Mettu@Oracle.COM return (-1);
239*13080SPavan.Mettu@Oracle.COM }
240*13080SPavan.Mettu@Oracle.COM
241*13080SPavan.Mettu@Oracle.COM static int
autofs_validate_property(sa_handle_t handle,sa_property_t property,sa_optionset_t parent)242*13080SPavan.Mettu@Oracle.COM autofs_validate_property(sa_handle_t handle, sa_property_t property,
243*13080SPavan.Mettu@Oracle.COM sa_optionset_t parent)
244*13080SPavan.Mettu@Oracle.COM {
245*13080SPavan.Mettu@Oracle.COM int ret = SA_OK;
246*13080SPavan.Mettu@Oracle.COM char *propname;
247*13080SPavan.Mettu@Oracle.COM int optionindex;
248*13080SPavan.Mettu@Oracle.COM char *value;
249*13080SPavan.Mettu@Oracle.COM
250*13080SPavan.Mettu@Oracle.COM #ifdef lint
251*13080SPavan.Mettu@Oracle.COM handle = handle;
252*13080SPavan.Mettu@Oracle.COM parent = parent;
253*13080SPavan.Mettu@Oracle.COM #endif
254*13080SPavan.Mettu@Oracle.COM propname = sa_get_property(property, "type");
255*13080SPavan.Mettu@Oracle.COM if (propname == NULL)
256*13080SPavan.Mettu@Oracle.COM return (SA_NO_SUCH_PROP);
257*13080SPavan.Mettu@Oracle.COM
258*13080SPavan.Mettu@Oracle.COM if ((optionindex = findprotoopt(propname)) < 0)
259*13080SPavan.Mettu@Oracle.COM ret = SA_NO_SUCH_PROP;
260*13080SPavan.Mettu@Oracle.COM
261*13080SPavan.Mettu@Oracle.COM if (ret != SA_OK) {
262*13080SPavan.Mettu@Oracle.COM if (propname != NULL)
263*13080SPavan.Mettu@Oracle.COM sa_free_attr_string(propname);
264*13080SPavan.Mettu@Oracle.COM return (ret);
265*13080SPavan.Mettu@Oracle.COM }
266*13080SPavan.Mettu@Oracle.COM
267*13080SPavan.Mettu@Oracle.COM value = sa_get_property_attr(property, "value");
268*13080SPavan.Mettu@Oracle.COM if (value != NULL) {
269*13080SPavan.Mettu@Oracle.COM /*
270*13080SPavan.Mettu@Oracle.COM * If any property is added to AUTOFS, which is a different
271*13080SPavan.Mettu@Oracle.COM * type than the below list, a case needs to be added for that
272*13080SPavan.Mettu@Oracle.COM * to check the values. For now AUTOFS type are just integers,
273*13080SPavan.Mettu@Oracle.COM * string and boolean properties. Just taking care of them.
274*13080SPavan.Mettu@Oracle.COM */
275*13080SPavan.Mettu@Oracle.COM switch (proto_options[optionindex].type) {
276*13080SPavan.Mettu@Oracle.COM case SCF_TYPE_INTEGER:
277*13080SPavan.Mettu@Oracle.COM case SCF_TYPE_BOOLEAN:
278*13080SPavan.Mettu@Oracle.COM case SCF_TYPE_ASTRING:
279*13080SPavan.Mettu@Oracle.COM ret = proto_options[optionindex].check(optionindex,
280*13080SPavan.Mettu@Oracle.COM value);
281*13080SPavan.Mettu@Oracle.COM break;
282*13080SPavan.Mettu@Oracle.COM default:
283*13080SPavan.Mettu@Oracle.COM break;
284*13080SPavan.Mettu@Oracle.COM }
285*13080SPavan.Mettu@Oracle.COM }
286*13080SPavan.Mettu@Oracle.COM
287*13080SPavan.Mettu@Oracle.COM /* Free the value */
288*13080SPavan.Mettu@Oracle.COM if (value != NULL)
289*13080SPavan.Mettu@Oracle.COM sa_free_attr_string(value);
290*13080SPavan.Mettu@Oracle.COM if (propname != NULL)
291*13080SPavan.Mettu@Oracle.COM sa_free_attr_string(propname);
292*13080SPavan.Mettu@Oracle.COM return (ret);
293*13080SPavan.Mettu@Oracle.COM }
294*13080SPavan.Mettu@Oracle.COM
295*13080SPavan.Mettu@Oracle.COM /*
296*13080SPavan.Mettu@Oracle.COM * service_in_state(service, chkstate)
297*13080SPavan.Mettu@Oracle.COM *
298*13080SPavan.Mettu@Oracle.COM * Want to know if the specified service is in the desired state
299*13080SPavan.Mettu@Oracle.COM * (chkstate) or not. Return true (1) if it is and false (0) if it
300*13080SPavan.Mettu@Oracle.COM * isn't.
301*13080SPavan.Mettu@Oracle.COM */
302*13080SPavan.Mettu@Oracle.COM static int
service_in_state(char * service,const char * chkstate)303*13080SPavan.Mettu@Oracle.COM service_in_state(char *service, const char *chkstate)
304*13080SPavan.Mettu@Oracle.COM {
305*13080SPavan.Mettu@Oracle.COM char *state;
306*13080SPavan.Mettu@Oracle.COM int ret = B_FALSE;
307*13080SPavan.Mettu@Oracle.COM
308*13080SPavan.Mettu@Oracle.COM state = smf_get_state(service);
309*13080SPavan.Mettu@Oracle.COM if (state != NULL) {
310*13080SPavan.Mettu@Oracle.COM /* got the state so get the equality for the return value */
311*13080SPavan.Mettu@Oracle.COM ret = strcmp(state, chkstate) == 0 ? B_TRUE : B_FALSE;
312*13080SPavan.Mettu@Oracle.COM free(state);
313*13080SPavan.Mettu@Oracle.COM }
314*13080SPavan.Mettu@Oracle.COM return (ret);
315*13080SPavan.Mettu@Oracle.COM }
316*13080SPavan.Mettu@Oracle.COM
317*13080SPavan.Mettu@Oracle.COM static void
restart_service(char * service)318*13080SPavan.Mettu@Oracle.COM restart_service(char *service)
319*13080SPavan.Mettu@Oracle.COM {
320*13080SPavan.Mettu@Oracle.COM int ret = -1;
321*13080SPavan.Mettu@Oracle.COM
322*13080SPavan.Mettu@Oracle.COM /*
323*13080SPavan.Mettu@Oracle.COM * Only attempt to restart the service if it is
324*13080SPavan.Mettu@Oracle.COM * currently running. In the future, it may be
325*13080SPavan.Mettu@Oracle.COM * desirable to use smf_refresh_instance if the AUTOFS
326*13080SPavan.Mettu@Oracle.COM * services ever implement the refresh method.
327*13080SPavan.Mettu@Oracle.COM */
328*13080SPavan.Mettu@Oracle.COM if (service_in_state(service, SCF_STATE_STRING_ONLINE)) {
329*13080SPavan.Mettu@Oracle.COM ret = smf_restart_instance(service);
330*13080SPavan.Mettu@Oracle.COM /*
331*13080SPavan.Mettu@Oracle.COM * There are only a few SMF errors at this point, but
332*13080SPavan.Mettu@Oracle.COM * it is also possible that a bad value may have put
333*13080SPavan.Mettu@Oracle.COM * the service into maintenance if there wasn't an
334*13080SPavan.Mettu@Oracle.COM * SMF level error.
335*13080SPavan.Mettu@Oracle.COM */
336*13080SPavan.Mettu@Oracle.COM if (ret != 0) {
337*13080SPavan.Mettu@Oracle.COM (void) fprintf(stderr,
338*13080SPavan.Mettu@Oracle.COM dgettext(TEXT_DOMAIN,
339*13080SPavan.Mettu@Oracle.COM "%s failed to restart: %s\n"),
340*13080SPavan.Mettu@Oracle.COM scf_strerror(scf_error()));
341*13080SPavan.Mettu@Oracle.COM } else {
342*13080SPavan.Mettu@Oracle.COM /*
343*13080SPavan.Mettu@Oracle.COM * Check whether it has gone to "maintenance"
344*13080SPavan.Mettu@Oracle.COM * mode or not. Maintenance implies something
345*13080SPavan.Mettu@Oracle.COM * went wrong.
346*13080SPavan.Mettu@Oracle.COM */
347*13080SPavan.Mettu@Oracle.COM if (service_in_state(service,
348*13080SPavan.Mettu@Oracle.COM SCF_STATE_STRING_MAINT)) {
349*13080SPavan.Mettu@Oracle.COM (void) fprintf(stderr,
350*13080SPavan.Mettu@Oracle.COM dgettext(TEXT_DOMAIN,
351*13080SPavan.Mettu@Oracle.COM "%s failed to restart\n"),
352*13080SPavan.Mettu@Oracle.COM service);
353*13080SPavan.Mettu@Oracle.COM }
354*13080SPavan.Mettu@Oracle.COM }
355*13080SPavan.Mettu@Oracle.COM }
356*13080SPavan.Mettu@Oracle.COM }
357*13080SPavan.Mettu@Oracle.COM
358*13080SPavan.Mettu@Oracle.COM static int
is_a_number(char * number)359*13080SPavan.Mettu@Oracle.COM is_a_number(char *number)
360*13080SPavan.Mettu@Oracle.COM {
361*13080SPavan.Mettu@Oracle.COM int ret = 1;
362*13080SPavan.Mettu@Oracle.COM int hex = 0;
363*13080SPavan.Mettu@Oracle.COM
364*13080SPavan.Mettu@Oracle.COM if (strncmp(number, "0x", 2) == 0) {
365*13080SPavan.Mettu@Oracle.COM number += 2;
366*13080SPavan.Mettu@Oracle.COM hex = 1;
367*13080SPavan.Mettu@Oracle.COM } else if (*number == '-') {
368*13080SPavan.Mettu@Oracle.COM number++; /* skip the minus */
369*13080SPavan.Mettu@Oracle.COM }
370*13080SPavan.Mettu@Oracle.COM while (ret == 1 && *number != '\0') {
371*13080SPavan.Mettu@Oracle.COM if (hex) {
372*13080SPavan.Mettu@Oracle.COM ret = isxdigit(*number++);
373*13080SPavan.Mettu@Oracle.COM } else {
374*13080SPavan.Mettu@Oracle.COM ret = isdigit(*number++);
375*13080SPavan.Mettu@Oracle.COM }
376*13080SPavan.Mettu@Oracle.COM }
377*13080SPavan.Mettu@Oracle.COM return (ret);
378*13080SPavan.Mettu@Oracle.COM }
379*13080SPavan.Mettu@Oracle.COM
380*13080SPavan.Mettu@Oracle.COM /*
381*13080SPavan.Mettu@Oracle.COM * fixcaselower(str)
382*13080SPavan.Mettu@Oracle.COM *
383*13080SPavan.Mettu@Oracle.COM * convert a string to lower case (inplace).
384*13080SPavan.Mettu@Oracle.COM */
385*13080SPavan.Mettu@Oracle.COM
386*13080SPavan.Mettu@Oracle.COM static void
fixcaselower(char * str)387*13080SPavan.Mettu@Oracle.COM fixcaselower(char *str)
388*13080SPavan.Mettu@Oracle.COM {
389*13080SPavan.Mettu@Oracle.COM while (*str) {
390*13080SPavan.Mettu@Oracle.COM *str = tolower(*str);
391*13080SPavan.Mettu@Oracle.COM str++;
392*13080SPavan.Mettu@Oracle.COM }
393*13080SPavan.Mettu@Oracle.COM }
394*13080SPavan.Mettu@Oracle.COM
395*13080SPavan.Mettu@Oracle.COM /*
396*13080SPavan.Mettu@Oracle.COM * skipwhitespace(str)
397*13080SPavan.Mettu@Oracle.COM *
398*13080SPavan.Mettu@Oracle.COM * Skip leading white space. It is assumed that it is called with a
399*13080SPavan.Mettu@Oracle.COM * valid pointer.
400*13080SPavan.Mettu@Oracle.COM */
401*13080SPavan.Mettu@Oracle.COM static char *
skipwhitespace(char * str)402*13080SPavan.Mettu@Oracle.COM skipwhitespace(char *str)
403*13080SPavan.Mettu@Oracle.COM {
404*13080SPavan.Mettu@Oracle.COM while (*str && isspace(*str))
405*13080SPavan.Mettu@Oracle.COM str++;
406*13080SPavan.Mettu@Oracle.COM
407*13080SPavan.Mettu@Oracle.COM return (str);
408*13080SPavan.Mettu@Oracle.COM }
409*13080SPavan.Mettu@Oracle.COM
410*13080SPavan.Mettu@Oracle.COM /*
411*13080SPavan.Mettu@Oracle.COM * extractprop()
412*13080SPavan.Mettu@Oracle.COM *
413*13080SPavan.Mettu@Oracle.COM * Extract the property and value out of the line and create the
414*13080SPavan.Mettu@Oracle.COM * property in the optionset.
415*13080SPavan.Mettu@Oracle.COM */
416*13080SPavan.Mettu@Oracle.COM static int
extractprop(char * name,char * value)417*13080SPavan.Mettu@Oracle.COM extractprop(char *name, char *value)
418*13080SPavan.Mettu@Oracle.COM {
419*13080SPavan.Mettu@Oracle.COM sa_property_t prop;
420*13080SPavan.Mettu@Oracle.COM int index;
421*13080SPavan.Mettu@Oracle.COM int ret = SA_OK;
422*13080SPavan.Mettu@Oracle.COM /*
423*13080SPavan.Mettu@Oracle.COM * Remove any leading
424*13080SPavan.Mettu@Oracle.COM * white space.
425*13080SPavan.Mettu@Oracle.COM */
426*13080SPavan.Mettu@Oracle.COM name = skipwhitespace(name);
427*13080SPavan.Mettu@Oracle.COM
428*13080SPavan.Mettu@Oracle.COM index = findprotoopt(name);
429*13080SPavan.Mettu@Oracle.COM if (index >= 0) {
430*13080SPavan.Mettu@Oracle.COM fixcaselower(name);
431*13080SPavan.Mettu@Oracle.COM prop = sa_create_property(proto_options[index].name, value);
432*13080SPavan.Mettu@Oracle.COM if (prop != NULL)
433*13080SPavan.Mettu@Oracle.COM ret = sa_add_protocol_property(protoset, prop);
434*13080SPavan.Mettu@Oracle.COM else
435*13080SPavan.Mettu@Oracle.COM ret = SA_NO_MEMORY;
436*13080SPavan.Mettu@Oracle.COM }
437*13080SPavan.Mettu@Oracle.COM return (ret);
438*13080SPavan.Mettu@Oracle.COM }
439*13080SPavan.Mettu@Oracle.COM
440*13080SPavan.Mettu@Oracle.COM static int
initautofsprotofromsmf(void)441*13080SPavan.Mettu@Oracle.COM initautofsprotofromsmf(void)
442*13080SPavan.Mettu@Oracle.COM {
443*13080SPavan.Mettu@Oracle.COM char name[PATH_MAX];
444*13080SPavan.Mettu@Oracle.COM char value[PATH_MAX];
445*13080SPavan.Mettu@Oracle.COM int ret = SA_OK, bufsz = 0, i;
446*13080SPavan.Mettu@Oracle.COM char *instance = NULL;
447*13080SPavan.Mettu@Oracle.COM scf_type_t sctype;
448*13080SPavan.Mettu@Oracle.COM
449*13080SPavan.Mettu@Oracle.COM protoset = sa_create_protocol_properties("autofs");
450*13080SPavan.Mettu@Oracle.COM if (protoset != NULL) {
451*13080SPavan.Mettu@Oracle.COM for (i = 0; proto_options[i].tag != NULL; i++) {
452*13080SPavan.Mettu@Oracle.COM bzero(value, PATH_MAX);
453*13080SPavan.Mettu@Oracle.COM (void) strncpy(name, proto_options[i].name, PATH_MAX);
454*13080SPavan.Mettu@Oracle.COM sctype = proto_options[i].type;
455*13080SPavan.Mettu@Oracle.COM bufsz = PATH_MAX;
456*13080SPavan.Mettu@Oracle.COM ret = autofs_smf_get_prop(name, value,
457*13080SPavan.Mettu@Oracle.COM instance, sctype, AUTOFS_FMRI, &bufsz);
458*13080SPavan.Mettu@Oracle.COM if (ret == SA_OK) {
459*13080SPavan.Mettu@Oracle.COM ret = extractprop(name, value);
460*13080SPavan.Mettu@Oracle.COM }
461*13080SPavan.Mettu@Oracle.COM }
462*13080SPavan.Mettu@Oracle.COM } else {
463*13080SPavan.Mettu@Oracle.COM ret = SA_NO_MEMORY;
464*13080SPavan.Mettu@Oracle.COM }
465*13080SPavan.Mettu@Oracle.COM return (ret);
466*13080SPavan.Mettu@Oracle.COM }
467*13080SPavan.Mettu@Oracle.COM
468*13080SPavan.Mettu@Oracle.COM static int
range_check_validator(int index,char * value)469*13080SPavan.Mettu@Oracle.COM range_check_validator(int index, char *value)
470*13080SPavan.Mettu@Oracle.COM {
471*13080SPavan.Mettu@Oracle.COM int ret = SA_OK;
472*13080SPavan.Mettu@Oracle.COM if (!is_a_number(value)) {
473*13080SPavan.Mettu@Oracle.COM ret = SA_BAD_VALUE;
474*13080SPavan.Mettu@Oracle.COM } else {
475*13080SPavan.Mettu@Oracle.COM int val;
476*13080SPavan.Mettu@Oracle.COM errno = 0;
477*13080SPavan.Mettu@Oracle.COM val = strtoul(value, NULL, 0);
478*13080SPavan.Mettu@Oracle.COM if (errno != 0)
479*13080SPavan.Mettu@Oracle.COM return (SA_BAD_VALUE);
480*13080SPavan.Mettu@Oracle.COM
481*13080SPavan.Mettu@Oracle.COM if (val < proto_options[index].minval ||
482*13080SPavan.Mettu@Oracle.COM val > proto_options[index].maxval)
483*13080SPavan.Mettu@Oracle.COM ret = SA_BAD_VALUE;
484*13080SPavan.Mettu@Oracle.COM }
485*13080SPavan.Mettu@Oracle.COM return (ret);
486*13080SPavan.Mettu@Oracle.COM }
487*13080SPavan.Mettu@Oracle.COM
488*13080SPavan.Mettu@Oracle.COM static int
true_false_validator(int index,char * value)489*13080SPavan.Mettu@Oracle.COM true_false_validator(int index, char *value)
490*13080SPavan.Mettu@Oracle.COM {
491*13080SPavan.Mettu@Oracle.COM
492*13080SPavan.Mettu@Oracle.COM #ifdef lint
493*13080SPavan.Mettu@Oracle.COM index = index;
494*13080SPavan.Mettu@Oracle.COM #endif
495*13080SPavan.Mettu@Oracle.COM if ((strcasecmp(value, "true") == 0) ||
496*13080SPavan.Mettu@Oracle.COM (strcasecmp(value, "on") == 0) ||
497*13080SPavan.Mettu@Oracle.COM (strcasecmp(value, "yes") == 0) ||
498*13080SPavan.Mettu@Oracle.COM (strcmp(value, "1") == 0) ||
499*13080SPavan.Mettu@Oracle.COM (strcasecmp(value, "false") == 0) ||
500*13080SPavan.Mettu@Oracle.COM (strcasecmp(value, "off") == 0) ||
501*13080SPavan.Mettu@Oracle.COM (strcasecmp(value, "no") == 0) ||
502*13080SPavan.Mettu@Oracle.COM (strcmp(value, "0") == 0)) {
503*13080SPavan.Mettu@Oracle.COM return (SA_OK);
504*13080SPavan.Mettu@Oracle.COM }
505*13080SPavan.Mettu@Oracle.COM return (SA_BAD_VALUE);
506*13080SPavan.Mettu@Oracle.COM }
507*13080SPavan.Mettu@Oracle.COM
508*13080SPavan.Mettu@Oracle.COM static int
strlen_validator(int index,char * value)509*13080SPavan.Mettu@Oracle.COM strlen_validator(int index, char *value)
510*13080SPavan.Mettu@Oracle.COM {
511*13080SPavan.Mettu@Oracle.COM int ret = SA_OK;
512*13080SPavan.Mettu@Oracle.COM if (value == NULL) {
513*13080SPavan.Mettu@Oracle.COM if (proto_options[index].minval == 0) {
514*13080SPavan.Mettu@Oracle.COM return (ret);
515*13080SPavan.Mettu@Oracle.COM } else {
516*13080SPavan.Mettu@Oracle.COM return (SA_BAD_VALUE);
517*13080SPavan.Mettu@Oracle.COM }
518*13080SPavan.Mettu@Oracle.COM }
519*13080SPavan.Mettu@Oracle.COM if (strlen(value) > proto_options[index].maxval ||
520*13080SPavan.Mettu@Oracle.COM strlen(value) < proto_options[index].minval)
521*13080SPavan.Mettu@Oracle.COM ret = SA_BAD_VALUE;
522*13080SPavan.Mettu@Oracle.COM return (ret);
523*13080SPavan.Mettu@Oracle.COM }
524*13080SPavan.Mettu@Oracle.COM
525*13080SPavan.Mettu@Oracle.COM static int
autofs_validate_proto_prop(int index,char * name,char * value)526*13080SPavan.Mettu@Oracle.COM autofs_validate_proto_prop(int index, char *name, char *value)
527*13080SPavan.Mettu@Oracle.COM {
528*13080SPavan.Mettu@Oracle.COM #ifdef lint
529*13080SPavan.Mettu@Oracle.COM name = name;
530*13080SPavan.Mettu@Oracle.COM #endif
531*13080SPavan.Mettu@Oracle.COM return (proto_options[index].check(index, value));
532*13080SPavan.Mettu@Oracle.COM }
533*13080SPavan.Mettu@Oracle.COM
534*13080SPavan.Mettu@Oracle.COM static int
autofs_set_proto_prop(sa_property_t prop)535*13080SPavan.Mettu@Oracle.COM autofs_set_proto_prop(sa_property_t prop)
536*13080SPavan.Mettu@Oracle.COM {
537*13080SPavan.Mettu@Oracle.COM int ret = SA_OK;
538*13080SPavan.Mettu@Oracle.COM char *name;
539*13080SPavan.Mettu@Oracle.COM char *value, *instance = NULL;
540*13080SPavan.Mettu@Oracle.COM scf_type_t sctype;
541*13080SPavan.Mettu@Oracle.COM
542*13080SPavan.Mettu@Oracle.COM name = sa_get_property_attr(prop, "type");
543*13080SPavan.Mettu@Oracle.COM value = sa_get_property_attr(prop, "value");
544*13080SPavan.Mettu@Oracle.COM if (name != NULL && value != NULL) {
545*13080SPavan.Mettu@Oracle.COM int index = findprotoopt(name);
546*13080SPavan.Mettu@Oracle.COM if (index >= 0) {
547*13080SPavan.Mettu@Oracle.COM ret = autofs_validate_proto_prop(index, name, value);
548*13080SPavan.Mettu@Oracle.COM if (ret == SA_OK) {
549*13080SPavan.Mettu@Oracle.COM sctype = proto_options[index].type;
550*13080SPavan.Mettu@Oracle.COM if (sctype == SCF_TYPE_BOOLEAN) {
551*13080SPavan.Mettu@Oracle.COM if (value != NULL)
552*13080SPavan.Mettu@Oracle.COM sa_free_attr_string(value);
553*13080SPavan.Mettu@Oracle.COM if (string_to_boolean(value) == 0)
554*13080SPavan.Mettu@Oracle.COM value = strdup("0");
555*13080SPavan.Mettu@Oracle.COM else
556*13080SPavan.Mettu@Oracle.COM value = strdup("1");
557*13080SPavan.Mettu@Oracle.COM }
558*13080SPavan.Mettu@Oracle.COM ret = autofs_smf_set_prop(name, value,
559*13080SPavan.Mettu@Oracle.COM instance, sctype, AUTOFS_FMRI);
560*13080SPavan.Mettu@Oracle.COM /*
561*13080SPavan.Mettu@Oracle.COM * Make an instance based FMRI.
562*13080SPavan.Mettu@Oracle.COM * For now its DEFAULT_AUTOFS_FMRI.
563*13080SPavan.Mettu@Oracle.COM */
564*13080SPavan.Mettu@Oracle.COM if (ret == SA_OK)
565*13080SPavan.Mettu@Oracle.COM restart_service(AUTOFS_DEFAULT_FMRI);
566*13080SPavan.Mettu@Oracle.COM }
567*13080SPavan.Mettu@Oracle.COM } else {
568*13080SPavan.Mettu@Oracle.COM ret = SA_NO_SUCH_PROP;
569*13080SPavan.Mettu@Oracle.COM }
570*13080SPavan.Mettu@Oracle.COM } else {
571*13080SPavan.Mettu@Oracle.COM ret = SA_CONFIG_ERR;
572*13080SPavan.Mettu@Oracle.COM }
573*13080SPavan.Mettu@Oracle.COM
574*13080SPavan.Mettu@Oracle.COM if (name != NULL)
575*13080SPavan.Mettu@Oracle.COM sa_free_attr_string(name);
576*13080SPavan.Mettu@Oracle.COM if (value != NULL)
577*13080SPavan.Mettu@Oracle.COM sa_free_attr_string(value);
578*13080SPavan.Mettu@Oracle.COM return (ret);
579*13080SPavan.Mettu@Oracle.COM }
580*13080SPavan.Mettu@Oracle.COM
581*13080SPavan.Mettu@Oracle.COM
582*13080SPavan.Mettu@Oracle.COM static sa_protocol_properties_t
autofs_get_proto_set(void)583*13080SPavan.Mettu@Oracle.COM autofs_get_proto_set(void)
584*13080SPavan.Mettu@Oracle.COM {
585*13080SPavan.Mettu@Oracle.COM return (protoset);
586*13080SPavan.Mettu@Oracle.COM }
587*13080SPavan.Mettu@Oracle.COM
588*13080SPavan.Mettu@Oracle.COM static uint64_t
autofs_features(void)589*13080SPavan.Mettu@Oracle.COM autofs_features(void)
590*13080SPavan.Mettu@Oracle.COM {
591*13080SPavan.Mettu@Oracle.COM return (0);
592*13080SPavan.Mettu@Oracle.COM }
593*13080SPavan.Mettu@Oracle.COM
594*13080SPavan.Mettu@Oracle.COM static char *
autofs_get_status(void)595*13080SPavan.Mettu@Oracle.COM autofs_get_status(void)
596*13080SPavan.Mettu@Oracle.COM {
597*13080SPavan.Mettu@Oracle.COM char *state = NULL;
598*13080SPavan.Mettu@Oracle.COM state = smf_get_state(AUTOFS_DEFAULT_FMRI);
599*13080SPavan.Mettu@Oracle.COM return (state != NULL ? state : "-");
600*13080SPavan.Mettu@Oracle.COM }
601