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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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 * 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