14bff34e3Sthurlow /* 24bff34e3Sthurlow * CDDL HEADER START 34bff34e3Sthurlow * 44bff34e3Sthurlow * The contents of this file are subject to the terms of the 54bff34e3Sthurlow * Common Development and Distribution License (the "License"). 64bff34e3Sthurlow * You may not use this file except in compliance with the License. 74bff34e3Sthurlow * 84bff34e3Sthurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94bff34e3Sthurlow * or http://www.opensolaris.org/os/licensing. 104bff34e3Sthurlow * See the License for the specific language governing permissions 114bff34e3Sthurlow * and limitations under the License. 124bff34e3Sthurlow * 134bff34e3Sthurlow * When distributing Covered Code, include this CDDL HEADER in each 144bff34e3Sthurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154bff34e3Sthurlow * If applicable, add the following below this CDDL HEADER, with the 164bff34e3Sthurlow * fields enclosed by brackets "[]" replaced with your own identifying 174bff34e3Sthurlow * information: Portions Copyright [yyyy] [name of copyright owner] 184bff34e3Sthurlow * 194bff34e3Sthurlow * CDDL HEADER END 204bff34e3Sthurlow */ 214bff34e3Sthurlow 224bff34e3Sthurlow /* 234bff34e3Sthurlow * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 244bff34e3Sthurlow * Use is subject to license terms. 254bff34e3Sthurlow */ 264bff34e3Sthurlow 274bff34e3Sthurlow /* 284bff34e3Sthurlow * SMB specific functions 294bff34e3Sthurlow */ 304bff34e3Sthurlow #include <stdio.h> 314bff34e3Sthurlow #include <string.h> 324bff34e3Sthurlow #include <ctype.h> 334bff34e3Sthurlow #include <stdlib.h> 344bff34e3Sthurlow #include <unistd.h> 354bff34e3Sthurlow #include <zone.h> 364bff34e3Sthurlow #include <errno.h> 374bff34e3Sthurlow #include <locale.h> 384bff34e3Sthurlow #include <signal.h> 394bff34e3Sthurlow #include <fcntl.h> 404bff34e3Sthurlow #include <sys/types.h> 414bff34e3Sthurlow #include <sys/stat.h> 424bff34e3Sthurlow #include <syslog.h> 434bff34e3Sthurlow #include "libshare.h" 444bff34e3Sthurlow #include "libshare_impl.h" 454bff34e3Sthurlow #include <pwd.h> 464bff34e3Sthurlow #include <limits.h> 474bff34e3Sthurlow #include <libscf.h> 484bff34e3Sthurlow #include <strings.h> 494bff34e3Sthurlow #include "libshare_smbfs.h" 504bff34e3Sthurlow #include <rpcsvc/daemon_utils.h> 514bff34e3Sthurlow #include <arpa/inet.h> 524bff34e3Sthurlow #include <uuid/uuid.h> 534bff34e3Sthurlow #include <netsmb/smb_lib.h> 544bff34e3Sthurlow 554bff34e3Sthurlow #define SMBFS_PROTOCOL_NAME "smbfs" 564bff34e3Sthurlow 574bff34e3Sthurlow /* internal functions */ 584bff34e3Sthurlow static uint64_t smbfs_features(); 594bff34e3Sthurlow static int smbfs_init(); 604bff34e3Sthurlow static void smbfs_fini(); 614bff34e3Sthurlow static int smbfs_set_proto_prop(sa_property_t); 624bff34e3Sthurlow static sa_protocol_properties_t smbfs_get_proto_set(); 634bff34e3Sthurlow static char *smbfs_get_status(); 644bff34e3Sthurlow static int smbfs_delete_section(char *); 654bff34e3Sthurlow static int smbfs_delete_property_group(char *); 664bff34e3Sthurlow 674bff34e3Sthurlow static int range_check_validator(int, char *, char *); 684bff34e3Sthurlow static int string_length_check_validator(int, char *, char *); 694bff34e3Sthurlow static int yes_no_validator(int, char *, char *); 704bff34e3Sthurlow static int ip_address_validator(int, char *, char *); 714bff34e3Sthurlow static int minauth_validator(int, char *, char *); 724bff34e3Sthurlow static int password_validator(int, char *, char *); 739c9af259SGordon Ross static int signing_validator(int, char *, char *); 744bff34e3Sthurlow 754bff34e3Sthurlow int propset_changed = 0; 764bff34e3Sthurlow 774bff34e3Sthurlow /* 784bff34e3Sthurlow * ops vector that provides the protocol specific info and operations 794bff34e3Sthurlow * for share management. 804bff34e3Sthurlow */ 814bff34e3Sthurlow 824bff34e3Sthurlow struct sa_plugin_ops sa_plugin_ops = { 834bff34e3Sthurlow SA_PLUGIN_VERSION, 844bff34e3Sthurlow SMBFS_PROTOCOL_NAME, 854bff34e3Sthurlow smbfs_init, 864bff34e3Sthurlow smbfs_fini, 874bff34e3Sthurlow NULL, /* share */ 884bff34e3Sthurlow NULL, /* unshare */ 894bff34e3Sthurlow NULL, /* valid_prop */ 904bff34e3Sthurlow NULL, /* valid_space */ 914bff34e3Sthurlow NULL, /* security_prop */ 924bff34e3Sthurlow NULL, /* legacy_opts */ 934bff34e3Sthurlow NULL, /* legacy_format */ 944bff34e3Sthurlow smbfs_set_proto_prop, 954bff34e3Sthurlow smbfs_get_proto_set, 964bff34e3Sthurlow smbfs_get_status, 974bff34e3Sthurlow NULL, /* space_alias */ 984bff34e3Sthurlow NULL, /* update_legacy */ 994bff34e3Sthurlow NULL, /* delete_legacy */ 1004bff34e3Sthurlow NULL, /* change_notify */ 1014bff34e3Sthurlow NULL, /* enable_resource */ 1024bff34e3Sthurlow NULL, /* disable_resource */ 1034bff34e3Sthurlow smbfs_features, 1044bff34e3Sthurlow NULL, /* get_transient_shares */ 1054bff34e3Sthurlow NULL, /* notify_resource */ 1064bff34e3Sthurlow NULL, /* rename_resource */ 1074bff34e3Sthurlow NULL, /* run_command */ 1084bff34e3Sthurlow NULL, /* command_help */ 1094bff34e3Sthurlow smbfs_delete_section, 1104bff34e3Sthurlow }; 1114bff34e3Sthurlow 1124bff34e3Sthurlow /* 1134bff34e3Sthurlow * is_a_number(number) 1144bff34e3Sthurlow * 1154bff34e3Sthurlow * is the string a number in one of the forms we want to use? 1164bff34e3Sthurlow */ 1174bff34e3Sthurlow 1184bff34e3Sthurlow static int 1194bff34e3Sthurlow is_a_number(char *number) 1204bff34e3Sthurlow { 1214bff34e3Sthurlow int ret = 1; 1224bff34e3Sthurlow int hex = 0; 1234bff34e3Sthurlow 1244bff34e3Sthurlow if (strncmp(number, "0x", 2) == 0) { 1254bff34e3Sthurlow number += 2; 1264bff34e3Sthurlow hex = 1; 1274bff34e3Sthurlow } else if (*number == '-') { 1284bff34e3Sthurlow number++; /* skip the minus */ 1294bff34e3Sthurlow } 1304bff34e3Sthurlow 1314bff34e3Sthurlow while (ret == 1 && *number != '\0') { 1324bff34e3Sthurlow if (hex) { 1334bff34e3Sthurlow ret = isxdigit(*number++); 1344bff34e3Sthurlow } else { 1354bff34e3Sthurlow ret = isdigit(*number++); 1364bff34e3Sthurlow } 1374bff34e3Sthurlow } 1384bff34e3Sthurlow return (ret); 1394bff34e3Sthurlow } 1404bff34e3Sthurlow 1414bff34e3Sthurlow /* 1424bff34e3Sthurlow * Protocol management functions 1434bff34e3Sthurlow * 1444bff34e3Sthurlow * properties defined in the default files are defined in 1454bff34e3Sthurlow * proto_option_defs for parsing and validation. 1464bff34e3Sthurlow */ 1474bff34e3Sthurlow 1484bff34e3Sthurlow struct smbclnt_proto_option_defs smbclnt_proto_options[] = { 1494bff34e3Sthurlow { "section", NULL, PROTO_OPT_SECTION, 1504bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1514bff34e3Sthurlow string_length_check_validator}, 1524bff34e3Sthurlow { "addr", NULL, PROTO_OPT_ADDR, 1534bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1544bff34e3Sthurlow ip_address_validator}, 1554bff34e3Sthurlow { "minauth", NULL, PROTO_OPT_MINAUTH, 1564bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1574bff34e3Sthurlow minauth_validator}, 1584bff34e3Sthurlow { "nbns_broadcast", NULL, PROTO_OPT_NBNS_BROADCAST, 1594bff34e3Sthurlow 0, 0, 0, 1604bff34e3Sthurlow yes_no_validator}, 1614bff34e3Sthurlow { "nbns_enable", NULL, PROTO_OPT_NBNS_ENABLE, 1624bff34e3Sthurlow 0, 0, 0, 1634bff34e3Sthurlow yes_no_validator}, 1644bff34e3Sthurlow { "nbns", NULL, PROTO_OPT_NBNSADDR, 1654bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1664bff34e3Sthurlow ip_address_validator}, 1674bff34e3Sthurlow { "password", NULL, PROTO_OPT_PASSWORD, 1684bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1694bff34e3Sthurlow password_validator}, 1704bff34e3Sthurlow { "timeout", NULL, PROTO_OPT_TIMEOUT, 1714bff34e3Sthurlow 0, 0, 60, 1724bff34e3Sthurlow range_check_validator}, 1734bff34e3Sthurlow { "user", NULL, PROTO_OPT_USER, 1744bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1754bff34e3Sthurlow string_length_check_validator}, 1764bff34e3Sthurlow { "domain", NULL, PROTO_OPT_DOMAIN, 1774bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1784bff34e3Sthurlow string_length_check_validator}, 1794bff34e3Sthurlow { "workgroup", NULL, PROTO_OPT_WORKGROUP, 1804bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1814bff34e3Sthurlow string_length_check_validator}, 1829c9af259SGordon Ross { "signing", NULL, PROTO_OPT_SIGNING, 1834bff34e3Sthurlow 0, 0, MAX_VALUE_BUFLEN, 1849c9af259SGordon Ross signing_validator}, 1854bff34e3Sthurlow {NULL} 1864bff34e3Sthurlow }; 1874bff34e3Sthurlow 1884bff34e3Sthurlow /* 1894bff34e3Sthurlow * Check the range of value as int range. 1904bff34e3Sthurlow */ 1914bff34e3Sthurlow /*ARGSUSED*/ 1924bff34e3Sthurlow static int 1934bff34e3Sthurlow range_check_validator(int index, char *section, char *value) 1944bff34e3Sthurlow { 1954bff34e3Sthurlow int ret = SA_OK; 1964bff34e3Sthurlow 1974bff34e3Sthurlow if (value == NULL) 1984bff34e3Sthurlow return (SA_BAD_VALUE); 1994bff34e3Sthurlow if (strlen(value) == 0) 2004bff34e3Sthurlow return (SA_OK); 2014bff34e3Sthurlow if (!is_a_number(value)) { 2024bff34e3Sthurlow ret = SA_BAD_VALUE; 2034bff34e3Sthurlow } else { 2044bff34e3Sthurlow int val; 2054bff34e3Sthurlow val = strtoul(value, NULL, 0); 2064bff34e3Sthurlow if (val < smbclnt_proto_options[index].minval || 2074bff34e3Sthurlow val > smbclnt_proto_options[index].maxval) 2084bff34e3Sthurlow ret = SA_BAD_VALUE; 2094bff34e3Sthurlow } 2104bff34e3Sthurlow return (ret); 2114bff34e3Sthurlow } 2124bff34e3Sthurlow 2134bff34e3Sthurlow /* 2144bff34e3Sthurlow * Check the length of the string 2154bff34e3Sthurlow */ 2164bff34e3Sthurlow /*ARGSUSED*/ 2174bff34e3Sthurlow static int 2184bff34e3Sthurlow string_length_check_validator(int index, char *section, char *value) 2194bff34e3Sthurlow { 2204bff34e3Sthurlow int ret = SA_OK; 2214bff34e3Sthurlow 2224bff34e3Sthurlow if (value == NULL) 2234bff34e3Sthurlow return (SA_BAD_VALUE); 2244bff34e3Sthurlow if (strlen(value) == 0) 2254bff34e3Sthurlow return (SA_OK); 2264bff34e3Sthurlow if (strlen(value) > smbclnt_proto_options[index].maxval) 2274bff34e3Sthurlow ret = SA_BAD_VALUE; 2284bff34e3Sthurlow return (ret); 2294bff34e3Sthurlow } 2304bff34e3Sthurlow 2314bff34e3Sthurlow /* 2324bff34e3Sthurlow * Check yes/no 2334bff34e3Sthurlow */ 2344bff34e3Sthurlow /*ARGSUSED*/ 2354bff34e3Sthurlow static int 2364bff34e3Sthurlow yes_no_validator(int index, char *section, char *value) 2374bff34e3Sthurlow { 2384bff34e3Sthurlow if (value == NULL) 2394bff34e3Sthurlow return (SA_BAD_VALUE); 2404bff34e3Sthurlow if (strlen(value) == 0) 2414bff34e3Sthurlow return (SA_OK); 2424bff34e3Sthurlow if ((strcasecmp(value, "yes") == 0) || 2434bff34e3Sthurlow (strcasecmp(value, "no") == 0) || 2444bff34e3Sthurlow (strcasecmp(value, "true") == 0) || 2454bff34e3Sthurlow (strcasecmp(value, "false") == 0)) 2464bff34e3Sthurlow return (SA_OK); 2474bff34e3Sthurlow return (SA_BAD_VALUE); 2484bff34e3Sthurlow } 2494bff34e3Sthurlow 2504bff34e3Sthurlow /* 2514bff34e3Sthurlow * Check IP address. 2524bff34e3Sthurlow */ 2534bff34e3Sthurlow /*ARGSUSED*/ 2544bff34e3Sthurlow static int 2554bff34e3Sthurlow ip_address_validator(int index, char *section, char *value) 2564bff34e3Sthurlow { 2574bff34e3Sthurlow int len; 2584bff34e3Sthurlow 2594bff34e3Sthurlow if (value == NULL) 2604bff34e3Sthurlow return (SA_BAD_VALUE); 2614bff34e3Sthurlow len = strlen(value); 2624bff34e3Sthurlow if (len == 0) 2634bff34e3Sthurlow return (SA_OK); 2644bff34e3Sthurlow if (len > MAX_VALUE_BUFLEN) 2654bff34e3Sthurlow return (SA_BAD_VALUE); 2664bff34e3Sthurlow return (SA_OK); 2674bff34e3Sthurlow } 2684bff34e3Sthurlow 2694bff34e3Sthurlow /*ARGSUSED*/ 2704bff34e3Sthurlow static int 2714bff34e3Sthurlow minauth_validator(int index, char *section, char *value) 2724bff34e3Sthurlow { 2734bff34e3Sthurlow if (value == NULL) 2744bff34e3Sthurlow return (SA_BAD_VALUE); 2754bff34e3Sthurlow if (strlen(value) == 0) 2764bff34e3Sthurlow return (SA_OK); 2774bff34e3Sthurlow if (strcmp(value, "kerberos") == 0 || 2784bff34e3Sthurlow strcmp(value, "ntlmv2") == 0 || 2794bff34e3Sthurlow strcmp(value, "ntlm") == 0 || 2804bff34e3Sthurlow strcmp(value, "lm") == 0 || 2814bff34e3Sthurlow strcmp(value, "none") == 0) 2824bff34e3Sthurlow return (SA_OK); 2834bff34e3Sthurlow else 2844bff34e3Sthurlow return (SA_BAD_VALUE); 2854bff34e3Sthurlow } 2864bff34e3Sthurlow 2874bff34e3Sthurlow /*ARGSUSED*/ 2884bff34e3Sthurlow static int 2899c9af259SGordon Ross signing_validator(int index, char *section, char *value) 2904bff34e3Sthurlow { 2919c9af259SGordon Ross if (value == NULL) 2929c9af259SGordon Ross return (SA_BAD_VALUE); 2939c9af259SGordon Ross if (strlen(value) == 0) 2944bff34e3Sthurlow return (SA_OK); 2959c9af259SGordon Ross if (strcmp(value, "disabled") == 0 || 2969c9af259SGordon Ross strcmp(value, "enabled") == 0 || 2979c9af259SGordon Ross strcmp(value, "required") == 0) 2989c9af259SGordon Ross return (SA_OK); 2999c9af259SGordon Ross else 3009c9af259SGordon Ross return (SA_BAD_VALUE); 3014bff34e3Sthurlow } 3024bff34e3Sthurlow 3034bff34e3Sthurlow /*ARGSUSED*/ 3044bff34e3Sthurlow static int 3054bff34e3Sthurlow password_validator(int index, char *section, char *value) 3064bff34e3Sthurlow { 3074bff34e3Sthurlow char buffer[100]; 3084bff34e3Sthurlow 3094bff34e3Sthurlow /* mangled passwords will start with this pattern */ 3104bff34e3Sthurlow if (strlen(value) == 0) 3114bff34e3Sthurlow return (SA_OK); 3124bff34e3Sthurlow if (strncmp(value, "$$1", 3) != 0) 3134bff34e3Sthurlow return (SA_PASSWORD_ENC); 3144bff34e3Sthurlow if (smb_simpledecrypt(buffer, value) != 0) 3154bff34e3Sthurlow return (SA_BAD_VALUE); 3164bff34e3Sthurlow return (SA_OK); 3174bff34e3Sthurlow } 3184bff34e3Sthurlow 3194bff34e3Sthurlow 3204bff34e3Sthurlow /* 3214bff34e3Sthurlow * the protoset holds the defined options so we don't have to read 3224bff34e3Sthurlow * them multiple times 3234bff34e3Sthurlow */ 3244bff34e3Sthurlow sa_protocol_properties_t protoset; 3254bff34e3Sthurlow 3264bff34e3Sthurlow static int 3274bff34e3Sthurlow findprotoopt(char *name) 3284bff34e3Sthurlow { 3294bff34e3Sthurlow int i; 3304bff34e3Sthurlow for (i = 0; smbclnt_proto_options[i].name != NULL; i++) { 3314bff34e3Sthurlow if (strcasecmp(smbclnt_proto_options[i].name, name) == 0) 3324bff34e3Sthurlow return (i); 3334bff34e3Sthurlow } 3344bff34e3Sthurlow return (-1); 3354bff34e3Sthurlow } 3364bff34e3Sthurlow 3374bff34e3Sthurlow /* 3384bff34e3Sthurlow * Load the persistent settings from SMF. Each section is an SMF 3394bff34e3Sthurlow * property group with an "S-" prefix and a UUID, and the section 3404bff34e3Sthurlow * is itself a property which can have a more flexible name than 3414bff34e3Sthurlow * a property group name can have. The section name need not be 3424bff34e3Sthurlow * the first property, so we have to be a little flexible, but 3434bff34e3Sthurlow * the change of name of the property groups is a reliable way 3444bff34e3Sthurlow * to know that we're seeing a different section. 3454bff34e3Sthurlow */ 3464bff34e3Sthurlow int 3474bff34e3Sthurlow smbclnt_config_load() 3484bff34e3Sthurlow { 3494bff34e3Sthurlow scf_simple_app_props_t *props = NULL; 3504bff34e3Sthurlow scf_simple_prop_t *prop = NULL, *lastprop = NULL; 3514bff34e3Sthurlow char *lastpgname = NULL, *pgname = NULL; 3524bff34e3Sthurlow char *name = NULL, *value = NULL; 3534bff34e3Sthurlow sa_property_t sect, node; 3544bff34e3Sthurlow 3554bff34e3Sthurlow props = scf_simple_app_props_get(NULL, SMBC_DEFAULT_INSTANCE_FMRI); 3564bff34e3Sthurlow if (props == NULL) 3574bff34e3Sthurlow return (-1); 3584bff34e3Sthurlow 3599c9af259SGordon Ross for (;;) { 3609c9af259SGordon Ross lastprop = prop; 3619c9af259SGordon Ross prop = (scf_simple_prop_t *) 3629c9af259SGordon Ross scf_simple_app_props_next(props, lastprop); 3639c9af259SGordon Ross if (prop == NULL) 3649c9af259SGordon Ross break; 3654bff34e3Sthurlow 3664bff34e3Sthurlow /* Ignore properties that don't have our prefix */ 3674bff34e3Sthurlow pgname = scf_simple_prop_pgname(prop); 3689c9af259SGordon Ross if (strncmp("S-", pgname, 2) != 0) 3694bff34e3Sthurlow continue; 3704bff34e3Sthurlow 3719c9af259SGordon Ross /* 3729c9af259SGordon Ross * Note property group name changes, which mark sections 3739c9af259SGordon Ross * 3749c9af259SGordon Ross * The memory allocated by sa_create_section is 3759c9af259SGordon Ross * linked into the list of children under protoset, 3769c9af259SGordon Ross * and will eventually be freed via that list. 3779c9af259SGordon Ross */ 3784bff34e3Sthurlow if (lastpgname == NULL || strcmp(lastpgname, pgname) != 0) { 3794bff34e3Sthurlow sect = sa_create_section(NULL, pgname+2); 3804bff34e3Sthurlow (void) xmlSetProp(sect, (xmlChar *)"type", 3814bff34e3Sthurlow (xmlChar *)SMBFS_PROTOCOL_NAME); 3829c9af259SGordon Ross (void) sa_add_protocol_property(protoset, sect); 3834bff34e3Sthurlow if (lastpgname) 3844bff34e3Sthurlow free(lastpgname); 3854bff34e3Sthurlow lastpgname = strdup(pgname); 3864bff34e3Sthurlow } 3874bff34e3Sthurlow name = scf_simple_prop_name(prop); 3884bff34e3Sthurlow value = scf_simple_prop_next_astring(prop); 3894bff34e3Sthurlow 3904bff34e3Sthurlow /* If we get a section name, apply it and consume it */ 3914bff34e3Sthurlow if (strncmp("section", name, 7) == 0 && value != NULL) { 3924bff34e3Sthurlow (void) xmlSetProp(sect, (xmlChar *)"name", 3934bff34e3Sthurlow (xmlChar *)value); 3944bff34e3Sthurlow continue; 3954bff34e3Sthurlow } 3969c9af259SGordon Ross 3974bff34e3Sthurlow /* 3989c9af259SGordon Ross * We have an ordinary property. Add to the section. 3999c9af259SGordon Ross * 4009c9af259SGordon Ross * The memory allocated by sa_create_property is 4019c9af259SGordon Ross * linked into the list of children under "sect", 4029c9af259SGordon Ross * and will eventually be freed via that list. 4034bff34e3Sthurlow */ 4044bff34e3Sthurlow node = sa_create_property(name, value); 4054bff34e3Sthurlow (void) sa_add_protocol_property(sect, node); 4064bff34e3Sthurlow } 4074bff34e3Sthurlow scf_simple_app_props_free(props); 4089c9af259SGordon Ross 4094bff34e3Sthurlow if (lastpgname) 4104bff34e3Sthurlow free(lastpgname); 4114bff34e3Sthurlow return (0); 4124bff34e3Sthurlow } 4134bff34e3Sthurlow 4144bff34e3Sthurlow /* 4154bff34e3Sthurlow * Save the set of properties for a particular section, which is 4164bff34e3Sthurlow * stored as a single property group. Properties will have been 4174bff34e3Sthurlow * changed earlier by one or more calls to smbfs_save_property(), 4184bff34e3Sthurlow * which only set the value in our array and marked them as 4194bff34e3Sthurlow * SMBC_MODIFIED. 4204bff34e3Sthurlow */ 4214bff34e3Sthurlow int 4224bff34e3Sthurlow smbfs_save_propset() 4234bff34e3Sthurlow { 4244bff34e3Sthurlow smb_scfhandle_t *handle = NULL; 4254bff34e3Sthurlow char propgroup[256]; 4264bff34e3Sthurlow char *section = smbclnt_proto_options[PROTO_OPT_SECTION].value; 4274bff34e3Sthurlow char *uu = NULL; 4284bff34e3Sthurlow uuid_t uuid; 4294bff34e3Sthurlow int i, ret = 0; 4304bff34e3Sthurlow sa_property_t propset; 4314bff34e3Sthurlow int new = 0, nonnull = 0; 4324bff34e3Sthurlow 4334bff34e3Sthurlow propset = sa_get_protocol_section(protoset, section); 4349c9af259SGordon Ross (void) strlcpy(propgroup, SMBC_PG_PREFIX, sizeof (propgroup)); 4354bff34e3Sthurlow propgroup[SMBC_PG_PREFIX_LEN] = '\0'; 4364bff34e3Sthurlow uu = sa_get_property_attr(propset, "extra"); 4374bff34e3Sthurlow if (uu != NULL) { 4389c9af259SGordon Ross (void) strlcat(propgroup, uu, sizeof (propgroup)); 4394bff34e3Sthurlow free(uu); 4404bff34e3Sthurlow } else { 4414bff34e3Sthurlow new = 1; 4424bff34e3Sthurlow smbclnt_proto_options[PROTO_OPT_SECTION].flags |= SMBC_MODIFIED; 4434bff34e3Sthurlow uuid_generate(uuid); 4444bff34e3Sthurlow uuid_unparse(uuid, &propgroup[SMBC_PG_PREFIX_LEN]); 4454bff34e3Sthurlow } 4464bff34e3Sthurlow 4474bff34e3Sthurlow handle = smb_smf_scf_init(SMBC_FMRI_PREFIX); 4484bff34e3Sthurlow if (handle == NULL) { 4494bff34e3Sthurlow return (1); 4504bff34e3Sthurlow } 4514bff34e3Sthurlow 4524bff34e3Sthurlow if ((ret = smb_smf_instance_create(handle, SMBC_FMRI_PREFIX, 4534bff34e3Sthurlow SMBC_PG_INSTANCE)) != SMBC_SMF_OK) { 4544bff34e3Sthurlow goto out; 4554bff34e3Sthurlow } 4564bff34e3Sthurlow 4574bff34e3Sthurlow if ((ret = smb_smf_create_instance_pgroup(handle, propgroup)) 4584bff34e3Sthurlow != SMBC_SMF_OK) { 4594bff34e3Sthurlow goto out; 4604bff34e3Sthurlow } 4614bff34e3Sthurlow 4624bff34e3Sthurlow if ((ret = smb_smf_start_transaction(handle)) != SMBC_SMF_OK) { 4634bff34e3Sthurlow goto out; 4644bff34e3Sthurlow } 4654bff34e3Sthurlow 4664bff34e3Sthurlow for (i = PROTO_OPT_SECTION+1; i <= SMBC_OPT_MAX; i++) { 4674bff34e3Sthurlow if ((smbclnt_proto_options[i].flags & SMBC_MODIFIED) == 0) 4684bff34e3Sthurlow continue; 4694bff34e3Sthurlow if (strcmp(smbclnt_proto_options[i].value, "") == 0) 4704bff34e3Sthurlow ret = smb_smf_delete_property(handle, 4714bff34e3Sthurlow smbclnt_proto_options[i].name); 4724bff34e3Sthurlow else { 4734bff34e3Sthurlow ret = smb_smf_set_string_property(handle, 4744bff34e3Sthurlow smbclnt_proto_options[i].name, 4754bff34e3Sthurlow smbclnt_proto_options[i].value); 4764bff34e3Sthurlow nonnull = 1; 4774bff34e3Sthurlow } 4784bff34e3Sthurlow free(smbclnt_proto_options[i].value); 4794bff34e3Sthurlow smbclnt_proto_options[i].value = NULL; 4804bff34e3Sthurlow smbclnt_proto_options[i].flags &= ~SMBC_MODIFIED; 4814bff34e3Sthurlow if (ret != SMBC_SMF_OK) 4824bff34e3Sthurlow goto outtrans; 4834bff34e3Sthurlow } 4844bff34e3Sthurlow /* 4854bff34e3Sthurlow * Suppress new, null entries by not saving the section name. 4864bff34e3Sthurlow */ 4874bff34e3Sthurlow if (!new || nonnull) { 4884bff34e3Sthurlow ret = smb_smf_set_string_property(handle, 4894bff34e3Sthurlow smbclnt_proto_options[PROTO_OPT_SECTION].name, 4904bff34e3Sthurlow smbclnt_proto_options[PROTO_OPT_SECTION].value); 4914bff34e3Sthurlow free(smbclnt_proto_options[PROTO_OPT_SECTION].value); 4924bff34e3Sthurlow smbclnt_proto_options[PROTO_OPT_SECTION].value = NULL; 4934bff34e3Sthurlow smbclnt_proto_options[PROTO_OPT_SECTION].flags &= 4944bff34e3Sthurlow ~SMBC_MODIFIED; 4954bff34e3Sthurlow } 4964bff34e3Sthurlow propset_changed = 0; 4974bff34e3Sthurlow 4984bff34e3Sthurlow outtrans: 4994bff34e3Sthurlow ret = smb_smf_end_transaction(handle); 5004bff34e3Sthurlow out: 5014bff34e3Sthurlow smb_smf_scf_fini(handle); 5024bff34e3Sthurlow return (ret); 5034bff34e3Sthurlow } 5044bff34e3Sthurlow 5054bff34e3Sthurlow /* 5064bff34e3Sthurlow * initprotofromdefault() 5074bff34e3Sthurlow * 5084bff34e3Sthurlow * read the default file(s) and add the defined values to the 5094bff34e3Sthurlow * protoset. Note that default values are known from the built in 5104bff34e3Sthurlow * table in case the file doesn't have a definition. 5114bff34e3Sthurlow */ 5124bff34e3Sthurlow 5134bff34e3Sthurlow static int 5144bff34e3Sthurlow initprotofromdefault() 5154bff34e3Sthurlow { 5164bff34e3Sthurlow protoset = sa_create_protocol_properties(SMBFS_PROTOCOL_NAME); 5174bff34e3Sthurlow if (protoset == NULL) 5184bff34e3Sthurlow return (SA_NO_MEMORY); 5194bff34e3Sthurlow if (smbclnt_config_load() != 0) 5204bff34e3Sthurlow return (SA_OK); 5214bff34e3Sthurlow 5224bff34e3Sthurlow return (SA_OK); 5234bff34e3Sthurlow } 5244bff34e3Sthurlow 5254bff34e3Sthurlow /* 5264bff34e3Sthurlow * 5274bff34e3Sthurlow * smbfs_features() 5284bff34e3Sthurlow * 5294bff34e3Sthurlow * Report the plugin's features 5304bff34e3Sthurlow */ 5314bff34e3Sthurlow static uint64_t 5324bff34e3Sthurlow smbfs_features() 5334bff34e3Sthurlow { 5344bff34e3Sthurlow return (SA_FEATURE_HAS_SECTIONS | SA_FEATURE_ADD_PROPERTIES); 5354bff34e3Sthurlow } 5364bff34e3Sthurlow 5374bff34e3Sthurlow /* 5384bff34e3Sthurlow * smbfs_init() 5394bff34e3Sthurlow * 5404bff34e3Sthurlow * Initialize the smb plugin. 5414bff34e3Sthurlow */ 5424bff34e3Sthurlow 5434bff34e3Sthurlow static int 5444bff34e3Sthurlow smbfs_init() 5454bff34e3Sthurlow { 5464bff34e3Sthurlow int ret = SA_OK; 5474bff34e3Sthurlow 5484bff34e3Sthurlow if (sa_plugin_ops.sa_init != smbfs_init) { 5494bff34e3Sthurlow return (SA_SYSTEM_ERR); 5504bff34e3Sthurlow } 5514bff34e3Sthurlow 5524bff34e3Sthurlow if (initprotofromdefault() != SA_OK) { 5534bff34e3Sthurlow return (SA_SYSTEM_ERR); 5544bff34e3Sthurlow } 5554bff34e3Sthurlow 5564bff34e3Sthurlow return (ret); 5574bff34e3Sthurlow } 5584bff34e3Sthurlow 5594bff34e3Sthurlow /* 5604bff34e3Sthurlow * smbfs_fini() 5614bff34e3Sthurlow * 5624bff34e3Sthurlow * uninitialize the smb plugin. Want to avoid memory leaks. 5634bff34e3Sthurlow */ 5644bff34e3Sthurlow 5654bff34e3Sthurlow static void 5664bff34e3Sthurlow smbfs_fini() 5674bff34e3Sthurlow { 5684bff34e3Sthurlow if (propset_changed) 5694bff34e3Sthurlow (void) smbfs_save_propset(); 5709c9af259SGordon Ross xmlFreeNode(protoset); 5719c9af259SGordon Ross protoset = NULL; 5724bff34e3Sthurlow } 5734bff34e3Sthurlow 5744bff34e3Sthurlow /* 5754bff34e3Sthurlow * smbfs_get_proto_set() 5764bff34e3Sthurlow * 5774bff34e3Sthurlow * Return an optionset with all the protocol specific properties in 5784bff34e3Sthurlow * it. 5794bff34e3Sthurlow */ 5804bff34e3Sthurlow 5814bff34e3Sthurlow static sa_protocol_properties_t 5824bff34e3Sthurlow smbfs_get_proto_set() 5834bff34e3Sthurlow { 5844bff34e3Sthurlow return (protoset); 5854bff34e3Sthurlow } 5864bff34e3Sthurlow 5874bff34e3Sthurlow /* 5884bff34e3Sthurlow * smbfs_validate_proto_prop(index, name, value) 5894bff34e3Sthurlow * 5904bff34e3Sthurlow * Verify that the property specifed by name can take the new 5914bff34e3Sthurlow * value. This is a sanity check to prevent bad values getting into 5924bff34e3Sthurlow * the default files. 5934bff34e3Sthurlow */ 5944bff34e3Sthurlow static int 5954bff34e3Sthurlow smbfs_validate_proto_prop(int index, char *section, char *name, char *value) 5964bff34e3Sthurlow { 5974bff34e3Sthurlow if ((section == NULL) || (name == NULL) || (index < 0)) 5984bff34e3Sthurlow return (SA_BAD_VALUE); 5994bff34e3Sthurlow 6004bff34e3Sthurlow if (smbclnt_proto_options[index].validator == NULL) 6014bff34e3Sthurlow return (SA_OK); 6024bff34e3Sthurlow 6034bff34e3Sthurlow return (smbclnt_proto_options[index].validator(index, section, value)); 6044bff34e3Sthurlow } 6054bff34e3Sthurlow 6064bff34e3Sthurlow /* 6074bff34e3Sthurlow * Save a property to our array; it will be stored to SMF later by 6084bff34e3Sthurlow * smbfs_save_propset(). 6094bff34e3Sthurlow */ 6104bff34e3Sthurlow int 6114bff34e3Sthurlow smbfs_save_property(int index, char *section, char *value) 6124bff34e3Sthurlow { 6134bff34e3Sthurlow char *s; 6144bff34e3Sthurlow 6154bff34e3Sthurlow if (index == PROTO_OPT_WORKGROUP) { 6164bff34e3Sthurlow index = PROTO_OPT_DOMAIN; 6174bff34e3Sthurlow } 6184bff34e3Sthurlow propset_changed = 1; 6194bff34e3Sthurlow s = strdup(section); 6204bff34e3Sthurlow if (s == NULL) 6214bff34e3Sthurlow return (-1); 6224bff34e3Sthurlow smbclnt_proto_options[PROTO_OPT_SECTION].value = s; 6234bff34e3Sthurlow s = strdup(value); 6244bff34e3Sthurlow if (s == NULL) 6254bff34e3Sthurlow return (-1); 6264bff34e3Sthurlow smbclnt_proto_options[index].value = s; 6274bff34e3Sthurlow smbclnt_proto_options[index].flags |= SMBC_MODIFIED; 6284bff34e3Sthurlow return (0); 6294bff34e3Sthurlow } 6304bff34e3Sthurlow 6314bff34e3Sthurlow /* 6324bff34e3Sthurlow * smbfs_set_proto_prop(prop) 6334bff34e3Sthurlow * 6344bff34e3Sthurlow * check that prop is valid. 6354bff34e3Sthurlow */ 6364bff34e3Sthurlow /*ARGSUSED*/ 6374bff34e3Sthurlow static int 6384bff34e3Sthurlow smbfs_set_proto_prop(sa_property_t prop) 6394bff34e3Sthurlow { 6404bff34e3Sthurlow int ret = SA_OK; 6414bff34e3Sthurlow char *name; 6424bff34e3Sthurlow char *value; 6434bff34e3Sthurlow char *section; 6444bff34e3Sthurlow int i = -1; 6454bff34e3Sthurlow 6464bff34e3Sthurlow section = sa_get_property_attr(prop, "section"); 6474bff34e3Sthurlow if (section == NULL) 6484bff34e3Sthurlow return (SA_NO_SECTION); 6494bff34e3Sthurlow name = sa_get_property_attr(prop, "type"); 6504bff34e3Sthurlow value = sa_get_property_attr(prop, "value"); 6514bff34e3Sthurlow if (name != NULL && value != NULL) { 6524bff34e3Sthurlow i = findprotoopt(name); 6534bff34e3Sthurlow if (i >= 0) { 6544bff34e3Sthurlow ret = smbfs_validate_proto_prop(i, section, 6554bff34e3Sthurlow name, value); 6564bff34e3Sthurlow if (ret == SA_OK) { 6574bff34e3Sthurlow if (smbfs_save_property(i, section, 6584bff34e3Sthurlow value) != 0) { 6594bff34e3Sthurlow ret = SA_SYSTEM_ERR; 6604bff34e3Sthurlow errno = EIO; 6614bff34e3Sthurlow } 6624bff34e3Sthurlow } 6634bff34e3Sthurlow } else 6644bff34e3Sthurlow ret = SA_INVALID_NAME; 6654bff34e3Sthurlow } 6664bff34e3Sthurlow if (name != NULL) 6674bff34e3Sthurlow sa_free_attr_string(name); 6684bff34e3Sthurlow if (value != NULL) 6694bff34e3Sthurlow sa_free_attr_string(value); 6709c9af259SGordon Ross if (section != NULL) 6719c9af259SGordon Ross sa_free_attr_string(section); 6724bff34e3Sthurlow 6734bff34e3Sthurlow return (ret); 6744bff34e3Sthurlow } 6754bff34e3Sthurlow 6764bff34e3Sthurlow /* 6774bff34e3Sthurlow * smbfs_get_status() 6784bff34e3Sthurlow * 6794bff34e3Sthurlow * What is the current status of the smbd? We use the SMF state here. 6804bff34e3Sthurlow * Caller must free the returned value. 6814bff34e3Sthurlow */ 6824bff34e3Sthurlow 6834bff34e3Sthurlow static char * 6844bff34e3Sthurlow smbfs_get_status() 6854bff34e3Sthurlow { 686*652601fbSRobert Mustacchi return (smf_get_state(SMBC_DEFAULT_INSTANCE_FMRI)); 6874bff34e3Sthurlow } 6884bff34e3Sthurlow 6894bff34e3Sthurlow /* 6904bff34e3Sthurlow * Delete a section by its name, which we will have read into an 6914bff34e3Sthurlow * XML optionset above. We need to find it and find its UUID to 6924bff34e3Sthurlow * be able to generate the property group name in order to call 6934bff34e3Sthurlow * smbfs_delete_property_group(). 6944bff34e3Sthurlow */ 6954bff34e3Sthurlow static int 6964bff34e3Sthurlow smbfs_delete_section(char *section) 6974bff34e3Sthurlow { 6984bff34e3Sthurlow char propgroup[256]; 6994bff34e3Sthurlow char *uu = NULL; 7004bff34e3Sthurlow sa_property_t propset; 7014bff34e3Sthurlow int ret = SA_SYSTEM_ERR; 7024bff34e3Sthurlow 7034bff34e3Sthurlow propset = sa_get_protocol_section(protoset, section); 7049c9af259SGordon Ross (void) strlcpy(propgroup, SMBC_PG_PREFIX, sizeof (propgroup)); 7054bff34e3Sthurlow propgroup[SMBC_PG_PREFIX_LEN] = '\0'; 7064bff34e3Sthurlow uu = sa_get_property_attr(propset, "extra"); 7074bff34e3Sthurlow if (uu == NULL) 7084bff34e3Sthurlow goto out; 7099c9af259SGordon Ross (void) strlcat(propgroup, uu, sizeof (propgroup)); 7104bff34e3Sthurlow free(uu); 7114bff34e3Sthurlow if ((ret = smbfs_delete_property_group(propgroup)) != SMBC_SMF_OK) 7124bff34e3Sthurlow goto out; 7134bff34e3Sthurlow ret = SA_OK; 7144bff34e3Sthurlow out: 7154bff34e3Sthurlow return (ret); 7164bff34e3Sthurlow } 7174bff34e3Sthurlow 7184bff34e3Sthurlow /* 7194bff34e3Sthurlow * Delete a property group by its name. Called to do a 'delsect' 7204bff34e3Sthurlow * or called when smbclnt_config_load() notices an empty section 7214bff34e3Sthurlow * at the end of the properties. 7224bff34e3Sthurlow */ 7234bff34e3Sthurlow static int 7244bff34e3Sthurlow smbfs_delete_property_group(char *propgroup) 7254bff34e3Sthurlow { 7264bff34e3Sthurlow smb_scfhandle_t *handle = NULL; 7274bff34e3Sthurlow int ret = SA_SYSTEM_ERR; 7284bff34e3Sthurlow 7294bff34e3Sthurlow handle = smb_smf_scf_init(SMBC_FMRI_PREFIX); 7304bff34e3Sthurlow if (handle == NULL) 7314bff34e3Sthurlow goto out; 7324bff34e3Sthurlow 7334bff34e3Sthurlow if ((ret = smb_smf_instance_create(handle, SMBC_FMRI_PREFIX, 7344bff34e3Sthurlow SMBC_PG_INSTANCE)) != SMBC_SMF_OK) 7354bff34e3Sthurlow goto out; 7364bff34e3Sthurlow 7374bff34e3Sthurlow if ((ret = smb_smf_delete_instance_pgroup(handle, propgroup)) 7384bff34e3Sthurlow != SMBC_SMF_OK) 7394bff34e3Sthurlow goto out; 7404bff34e3Sthurlow ret = SA_OK; 7414bff34e3Sthurlow out: 7424bff34e3Sthurlow smb_smf_scf_fini(handle); 7434bff34e3Sthurlow return (ret); 7444bff34e3Sthurlow } 745