4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * SMB specific functions
29 */
30 #include <stdio.h>
31 #include <string.h>
32 #include <ctype.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <zone.h>
36 #include <errno.h>
37 #include <locale.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <syslog.h>
42 #include "libshare.h"
43 #include "libshare_impl.h"
44 #include <pwd.h>
67 static int smb_disable_share(sa_share_t share, char *);
68 static int smb_validate_property(sa_handle_t, sa_property_t, sa_optionset_t);
69 static int smb_set_proto_prop(sa_property_t);
70 static sa_protocol_properties_t smb_get_proto_set(void);
71 static char *smb_get_status(void);
72 static int smb_parse_optstring(sa_group_t, char *);
73 static char *smb_format_options(sa_group_t, int);
74
75 static int smb_enable_service(void);
76
77 static int range_check_validator(int, char *);
78 static int range_check_validator_zero_ok(int, char *);
79 static int string_length_check_validator(int, char *);
80 static int print_enable_validator(int, char *);
81 static int true_false_validator(int, char *);
82 static int ipv4_validator(int, char *);
83 static int hostname_validator(int, char *);
84 static int path_validator(int, char *);
85 static int cmd_validator(int, char *);
86 static int disposition_validator(int, char *);
87 static int max_protocol_validator(int, char *);
88
89 static int smb_enable_resource(sa_resource_t);
90 static int smb_disable_resource(sa_resource_t);
91 static uint64_t smb_share_features(void);
92 static int smb_list_transient(sa_handle_t);
93
94 static int smb_build_shareinfo(sa_share_t, sa_resource_t, smb_share_t *);
95 static void smb_csc_option(const char *, smb_share_t *);
96 static char *smb_csc_name(const smb_share_t *);
97 static sa_group_t smb_get_defaultgrp(sa_handle_t);
98 static int interface_validator(int, char *);
99 static int smb_update_optionset_props(sa_handle_t, sa_resource_t, nvlist_t *);
100
101 static boolean_t smb_saprop_getbool(sa_optionset_t, char *);
102 static boolean_t smb_saprop_getstr(sa_optionset_t, char *, char *, size_t);
103
104 static struct {
105 char *value;
106 uint32_t flag;
107 } cscopt[] = {
108 { "disabled", SMB_SHRF_CSC_DISABLED },
109 { "manual", SMB_SHRF_CSC_MANUAL },
110 { "auto", SMB_SHRF_CSC_AUTO },
111 { "vdo", SMB_SHRF_CSC_VDO }
112 };
113
114 /* size of basic format allocation */
115 #define OPT_CHUNK 1024
116
117 /* size of string for types - big enough to hold "dependency" */
118 #define SCFTYPE_LEN 32
119
120 /*
121 * Indexes of entries in smb_proto_options table.
161 smb_list_transient,
162 smb_resource_changed,
163 smb_rename_resource,
164 NULL, /* run_command */
165 NULL, /* command_help */
166 NULL /* delete_proto_section */
167 };
168
169 struct option_defs optdefs[] = {
170 { SHOPT_AD_CONTAINER, OPT_TYPE_STRING },
171 { SHOPT_ABE, OPT_TYPE_BOOLEAN },
172 { SHOPT_NAME, OPT_TYPE_NAME },
173 { SHOPT_RO, OPT_TYPE_ACCLIST },
174 { SHOPT_RW, OPT_TYPE_ACCLIST },
175 { SHOPT_NONE, OPT_TYPE_ACCLIST },
176 { SHOPT_CATIA, OPT_TYPE_BOOLEAN },
177 { SHOPT_CSC, OPT_TYPE_CSC },
178 { SHOPT_GUEST, OPT_TYPE_BOOLEAN },
179 { SHOPT_DFSROOT, OPT_TYPE_BOOLEAN },
180 { SHOPT_DESCRIPTION, OPT_TYPE_STRING },
181 { NULL, NULL }
182 };
183
184 /*
185 * findopt(name)
186 *
187 * Lookup option "name" in the option table and return the table
188 * index.
189 */
190 static int
191 findopt(char *name)
192 {
193 int i;
194 if (name != NULL) {
195 for (i = 0; optdefs[i].tag != NULL; i++) {
196 if (strcmp(optdefs[i].tag, name) == 0)
197 return (i);
198 }
199 }
200 return (-1);
369 if ((str = smf_get_state(SMBD_DEFAULT_INSTANCE_FMRI)) != NULL) {
370 ret = (strcmp(str, SCF_STATE_STRING_MAINT) == 0);
371 free(str);
372 }
373 return (ret);
374 }
375
376 /*
377 * smb_enable_share tells the implementation that it is to enable the share.
378 * This entails converting the path and options into the appropriate ioctl
379 * calls. It is assumed that all error checking of paths, etc. were
380 * done earlier.
381 */
382 static int
383 smb_enable_share(sa_share_t share)
384 {
385 char *path;
386 smb_share_t si;
387 sa_resource_t resource;
388 boolean_t iszfs;
389 boolean_t privileged;
390 int err = SA_OK;
391 priv_set_t *priv_effective;
392 boolean_t online;
393
394 /*
395 * Don't support Trusted Extensions.
396 */
397 if (is_system_labeled()) {
398 (void) printf(dgettext(TEXT_DOMAIN,
399 "SMB: service not supported with Trusted Extensions\n"));
400 return (SA_NOT_SUPPORTED);
401 }
402
403 priv_effective = priv_allocset();
404 (void) getppriv(PRIV_EFFECTIVE, priv_effective);
405 privileged = (priv_isfullset(priv_effective) == B_TRUE);
406 priv_freeset(priv_effective);
407
408 /* get the path since it is important in several places */
409 path = sa_get_share_attr(share, "path");
410 if (path == NULL)
411 return (SA_NO_SUCH_PATH);
412
413 /*
414 * If administratively disabled, don't try to start anything.
415 */
416 online = smb_isonline();
417 if (!online && !smb_isautoenable() && smb_isdisabled())
418 goto done;
419
420 iszfs = sa_path_is_zfs(path);
421
422 if (iszfs) {
423
424 if (privileged == B_FALSE && !online) {
425
426 if (!online) {
427 (void) printf(dgettext(TEXT_DOMAIN,
428 "SMB: Cannot share remove "
429 "file system: %s\n"), path);
430 (void) printf(dgettext(TEXT_DOMAIN,
431 "SMB: Service needs to be enabled "
432 "by a privileged user\n"));
433 err = SA_NO_PERMISSION;
434 errno = EPERM;
435 }
436 if (err) {
437 sa_free_attr_string(path);
438 return (err);
439 }
440
441 }
442 }
443
444 if (privileged == B_TRUE && !online) {
445 err = smb_enable_service();
446 if (err != SA_OK) {
447 (void) printf(dgettext(TEXT_DOMAIN,
448 "SMB: Unable to enable service\n"));
449 } else {
450 online = B_TRUE;
451 }
452 }
453
454 /*
455 * Don't bother trying to start shares if the service isn't
456 * running.
457 */
458 if (!online)
459 goto done;
460
461 /* Each share can have multiple resources */
462 for (resource = sa_get_share_resource(share, NULL);
463 resource != NULL;
464 resource = sa_get_next_resource(resource)) {
897 SMB_REFRESH_REFRESH },
898 { SMB_CI_RESTRICT_ANON, 0, 0, true_false_validator,
899 SMB_REFRESH_REFRESH },
900 { SMB_CI_DOMAIN_SRV, 0, MAX_VALUE_BUFLEN,
901 hostname_validator, SMB_REFRESH_REFRESH },
902 { SMB_CI_ADS_SITE, 0, MAX_VALUE_BUFLEN,
903 string_length_check_validator, SMB_REFRESH_REFRESH },
904 { SMB_CI_DYNDNS_ENABLE, 0, 0, true_false_validator, 0 },
905 { SMB_CI_AUTOHOME_MAP, 0, MAX_VALUE_BUFLEN, path_validator, 0 },
906 { SMB_CI_IPV6_ENABLE, 0, 0, true_false_validator,
907 SMB_REFRESH_REFRESH },
908 { SMB_CI_PRINT_ENABLE, 0, 0, print_enable_validator,
909 SMB_REFRESH_REFRESH },
910 { SMB_CI_TRAVERSE_MOUNTS, 0, 0, true_false_validator,
911 SMB_REFRESH_REFRESH },
912 { SMB_CI_MAP, 0, MAX_VALUE_BUFLEN, cmd_validator, SMB_REFRESH_REFRESH },
913 { SMB_CI_UNMAP, 0, MAX_VALUE_BUFLEN, cmd_validator,
914 SMB_REFRESH_REFRESH },
915 { SMB_CI_DISPOSITION, 0, MAX_VALUE_BUFLEN,
916 disposition_validator, SMB_REFRESH_REFRESH },
917 { SMB_CI_MAX_PROTOCOL, 0, MAX_VALUE_BUFLEN, max_protocol_validator,
918 SMB_REFRESH_REFRESH },
919 };
920
921 #define SMB_OPT_NUM \
922 (sizeof (smb_proto_options) / sizeof (smb_proto_options[0]))
923
924 /*
925 * Check the range of value as int range.
926 */
927 static int
928 range_check_validator(int index, char *value)
929 {
930 int ret = SA_OK;
931
932 if (!is_a_number(value)) {
933 ret = SA_BAD_VALUE;
934 } else {
935 int val;
936 val = strtoul(value, NULL, 0);
937 if (val < smb_proto_options[index].minval ||
938 val > smb_proto_options[index].maxval)
939 ret = SA_BAD_VALUE;
940 }
941 return (ret);
942 }
943
1517 static int
1518 smb_set_proto_prop(sa_property_t prop)
1519 {
1520 int ret = SA_OK;
1521 char *name;
1522 char *value;
1523 int index = -1;
1524 struct smb_proto_option_defs *opt;
1525
1526 name = sa_get_property_attr(prop, "type");
1527 value = sa_get_property_attr(prop, "value");
1528 if (name != NULL && value != NULL) {
1529 index = findprotoopt(name);
1530 if (index >= 0) {
1531 /* should test for valid value */
1532 ret = smb_validate_proto_prop(index, name, value);
1533 if (ret == SA_OK) {
1534 opt = &smb_proto_options[index];
1535
1536 /* Save to SMF */
1537 (void) smb_config_set(opt->smb_index, value);
1538 /*
1539 * Specialized refresh mechanisms can
1540 * be flagged in the proto_options and
1541 * processed here.
1542 */
1543 if (opt->refresh & SMB_REFRESH_REFRESH)
1544 (void) smf_refresh_instance(
1545 SMBD_DEFAULT_INSTANCE_FMRI);
1546 else if (opt->refresh & SMB_REFRESH_RESTART)
1547 (void) smf_restart_instance(
1548 SMBD_DEFAULT_INSTANCE_FMRI);
1549 }
1550 }
1551 }
1552
1553 if (name != NULL)
1554 sa_free_attr_string(name);
1555 if (value != NULL)
1556 sa_free_attr_string(value);
1557
1558 return (ret);
1559 }
1560
1561 /*
1562 * smb_get_status()
1563 *
1564 * What is the current status of the smbd? We use the SMF state here.
1565 * Caller must free the returned value.
1566 */
1567
1568 static char *
1569 smb_get_status(void)
1570 {
1571 return (smf_get_state(SMBD_DEFAULT_INSTANCE_FMRI));
1572 }
2098 break;
2099 case NERR_DuplicateShare:
2100 ret = SA_DUPLICATE_NAME;
2101 break;
2102 default:
2103 ret = SA_CONFIG_ERR;
2104 break;
2105 }
2106
2107 return (ret);
2108 }
2109
2110 static int
2111 smb_build_shareinfo(sa_share_t share, sa_resource_t resource, smb_share_t *si)
2112 {
2113 sa_optionset_t opts;
2114 char *path;
2115 char *rname;
2116 char *val = NULL;
2117 char csc_value[SMB_CSC_BUFSZ];
2118
2119 bzero(si, sizeof (smb_share_t));
2120
2121 if ((path = sa_get_share_attr(share, "path")) == NULL)
2122 return (SA_NO_SUCH_PATH);
2123
2124 if ((rname = sa_get_resource_attr(resource, "name")) == NULL) {
2125 sa_free_attr_string(path);
2126 return (SA_NO_SUCH_RESOURCE);
2127 }
2128
2129 (void) strlcpy(si->shr_path, path, sizeof (si->shr_path));
2130 (void) strlcpy(si->shr_name, rname, sizeof (si->shr_name));
2131 sa_free_attr_string(path);
2132 sa_free_attr_string(rname);
2133
2134 val = sa_get_resource_description(resource);
2135 if (val == NULL)
2136 val = sa_get_share_description(share);
2137
2138 if (val != NULL) {
2139 (void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt));
2140 sa_free_share_description(val);
2141 }
2142
2143 si->shr_flags = (sa_is_persistent(share))
2144 ? SMB_SHRF_PERM : SMB_SHRF_TRANS;
2145
2146 opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1);
2147 if (opts == NULL)
2148 return (SA_OK);
2149
2150 if (smb_saprop_getbool(opts, SHOPT_CATIA))
2151 si->shr_flags |= SMB_SHRF_CATIA;
2152
2153 if (smb_saprop_getbool(opts, SHOPT_ABE))
2154 si->shr_flags |= SMB_SHRF_ABE;
2155
2156 if (smb_saprop_getbool(opts, SHOPT_GUEST))
2157 si->shr_flags |= SMB_SHRF_GUEST_OK;
2158
2159 if (smb_saprop_getbool(opts, SHOPT_DFSROOT))
2160 si->shr_flags |= SMB_SHRF_DFSROOT;
2161
2162 (void) smb_saprop_getstr(opts, SHOPT_AD_CONTAINER, si->shr_container,
2163 sizeof (si->shr_container));
2164
2165 if (smb_saprop_getstr(opts, SHOPT_CSC, csc_value, sizeof (csc_value)))
2166 smb_csc_option(csc_value, si);
2167
2168 if (smb_saprop_getstr(opts, SHOPT_RO, si->shr_access_ro,
2169 sizeof (si->shr_access_ro)))
2170 si->shr_flags |= SMB_SHRF_ACC_RO;
2171
2172 if (smb_saprop_getstr(opts, SHOPT_RW, si->shr_access_rw,
2173 sizeof (si->shr_access_rw)))
2174 si->shr_flags |= SMB_SHRF_ACC_RW;
2175
2176 if (smb_saprop_getstr(opts, SHOPT_NONE, si->shr_access_none,
2177 sizeof (si->shr_access_none)))
2178 si->shr_flags |= SMB_SHRF_ACC_NONE;
2179
2180 sa_free_derived_optionset(opts);
2181 return (SA_OK);
2330
2331 /*ARGSUSED*/
2332 static int
2333 disposition_validator(int index, char *value)
2334 {
2335 if (value == NULL)
2336 return (SA_BAD_VALUE);
2337
2338 if (*value == '\0')
2339 return (SA_OK);
2340
2341 if ((strcasecmp(value, SMB_EXEC_DISP_CONTINUE) == 0) ||
2342 (strcasecmp(value, SMB_EXEC_DISP_TERMINATE) == 0))
2343 return (SA_OK);
2344
2345 return (SA_BAD_VALUE);
2346 }
2347
2348 /*ARGSUSED*/
2349 static int
2350 max_protocol_validator(int index, char *value)
2351 {
2352 if (value == NULL)
2353 return (SA_BAD_VALUE);
2354
2355 if (*value == '\0')
2356 return (SA_OK);
2357
2358 if (smb_config_check_protocol(value) == 0)
2359 return (SA_OK);
2360
2361 return (SA_BAD_VALUE);
2362
2363 }
2364
2365 /*
2366 * Updates the optionset properties of the share resource.
2367 * The properties are given as a list of name-value pair.
2368 * The name argument should be the optionset property name and the value
2369 * should be a valid value for the specified property.
2370 *
2406 (void) sa_remove_property(prop);
2407 break;
2408 }
2409 }
2410 err = sa_add_property(opts, prop);
2411 if (err != SA_OK)
2412 break;
2413 } else {
2414 err = sa_update_property(prop, val);
2415 if (err != SA_OK)
2416 break;
2417 }
2418
2419 cur = nvlist_next_nvpair(nvl, cur);
2420 }
2421
2422 return (err);
2423 }
2424
2425 static boolean_t
2426 smb_saprop_getbool(sa_optionset_t opts, char *propname)
2427 {
2428 sa_property_t prop;
2429 char *val;
2430 boolean_t propval = B_FALSE;
2431
2432 prop = sa_get_property(opts, propname);
2433 if ((val = sa_get_property_attr(prop, "value")) != NULL) {
2434 if ((strcasecmp(val, "true") == 0) || (strcmp(val, "1") == 0))
2435 propval = B_TRUE;
2436 free(val);
2437 }
2438
2439 return (propval);
2440 }
2441
2442 static boolean_t
2443 smb_saprop_getstr(sa_optionset_t opts, char *propname, char *buf, size_t bufsz)
2444 {
2445 sa_property_t prop;
2446 char *val;
2447
2448 prop = sa_get_property(opts, propname);
2449 if ((val = sa_get_property_attr(prop, "value")) != NULL) {
2450 (void) strlcpy(buf, val, bufsz);
2451 free(val);
2452 return (B_TRUE);
2453 }
2454
2455 return (B_FALSE);
2456 }
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * SMB specific functions
29 */
30 #include <stdio.h>
31 #include <string.h>
32 #include <ctype.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <zone.h>
36 #include <errno.h>
37 #include <locale.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <syslog.h>
42 #include "libshare.h"
43 #include "libshare_impl.h"
44 #include <pwd.h>
67 static int smb_disable_share(sa_share_t share, char *);
68 static int smb_validate_property(sa_handle_t, sa_property_t, sa_optionset_t);
69 static int smb_set_proto_prop(sa_property_t);
70 static sa_protocol_properties_t smb_get_proto_set(void);
71 static char *smb_get_status(void);
72 static int smb_parse_optstring(sa_group_t, char *);
73 static char *smb_format_options(sa_group_t, int);
74
75 static int smb_enable_service(void);
76
77 static int range_check_validator(int, char *);
78 static int range_check_validator_zero_ok(int, char *);
79 static int string_length_check_validator(int, char *);
80 static int print_enable_validator(int, char *);
81 static int true_false_validator(int, char *);
82 static int ipv4_validator(int, char *);
83 static int hostname_validator(int, char *);
84 static int path_validator(int, char *);
85 static int cmd_validator(int, char *);
86 static int disposition_validator(int, char *);
87 static int protocol_validator(int, char *);
88 static int require_validator(int, char *);
89
90 static int smb_enable_resource(sa_resource_t);
91 static int smb_disable_resource(sa_resource_t);
92 static uint64_t smb_share_features(void);
93 static int smb_list_transient(sa_handle_t);
94
95 static int smb_build_shareinfo(sa_share_t, sa_resource_t, smb_share_t *);
96 static void smb_csc_option(const char *, smb_share_t *);
97 static char *smb_csc_name(const smb_share_t *);
98 static sa_group_t smb_get_defaultgrp(sa_handle_t);
99 static int interface_validator(int, char *);
100 static int smb_update_optionset_props(sa_handle_t, sa_resource_t, nvlist_t *);
101
102 static boolean_t smb_saprop_getbool(sa_optionset_t, char *, boolean_t);
103 static boolean_t smb_saprop_getstr(sa_optionset_t, char *, char *, size_t);
104
105 static struct {
106 char *value;
107 uint32_t flag;
108 } cscopt[] = {
109 { "disabled", SMB_SHRF_CSC_DISABLED },
110 { "manual", SMB_SHRF_CSC_MANUAL },
111 { "auto", SMB_SHRF_CSC_AUTO },
112 { "vdo", SMB_SHRF_CSC_VDO }
113 };
114
115 /* size of basic format allocation */
116 #define OPT_CHUNK 1024
117
118 /* size of string for types - big enough to hold "dependency" */
119 #define SCFTYPE_LEN 32
120
121 /*
122 * Indexes of entries in smb_proto_options table.
162 smb_list_transient,
163 smb_resource_changed,
164 smb_rename_resource,
165 NULL, /* run_command */
166 NULL, /* command_help */
167 NULL /* delete_proto_section */
168 };
169
170 struct option_defs optdefs[] = {
171 { SHOPT_AD_CONTAINER, OPT_TYPE_STRING },
172 { SHOPT_ABE, OPT_TYPE_BOOLEAN },
173 { SHOPT_NAME, OPT_TYPE_NAME },
174 { SHOPT_RO, OPT_TYPE_ACCLIST },
175 { SHOPT_RW, OPT_TYPE_ACCLIST },
176 { SHOPT_NONE, OPT_TYPE_ACCLIST },
177 { SHOPT_CATIA, OPT_TYPE_BOOLEAN },
178 { SHOPT_CSC, OPT_TYPE_CSC },
179 { SHOPT_GUEST, OPT_TYPE_BOOLEAN },
180 { SHOPT_DFSROOT, OPT_TYPE_BOOLEAN },
181 { SHOPT_DESCRIPTION, OPT_TYPE_STRING },
182 { SHOPT_CA, OPT_TYPE_BOOLEAN },
183 { SHOPT_FSO, OPT_TYPE_BOOLEAN },
184 { SHOPT_QUOTAS, OPT_TYPE_BOOLEAN },
185 { SHOPT_ENCRYPT, OPT_TYPE_STRING },
186 { NULL, NULL }
187 };
188
189 /*
190 * findopt(name)
191 *
192 * Lookup option "name" in the option table and return the table
193 * index.
194 */
195 static int
196 findopt(char *name)
197 {
198 int i;
199 if (name != NULL) {
200 for (i = 0; optdefs[i].tag != NULL; i++) {
201 if (strcmp(optdefs[i].tag, name) == 0)
202 return (i);
203 }
204 }
205 return (-1);
374 if ((str = smf_get_state(SMBD_DEFAULT_INSTANCE_FMRI)) != NULL) {
375 ret = (strcmp(str, SCF_STATE_STRING_MAINT) == 0);
376 free(str);
377 }
378 return (ret);
379 }
380
381 /*
382 * smb_enable_share tells the implementation that it is to enable the share.
383 * This entails converting the path and options into the appropriate ioctl
384 * calls. It is assumed that all error checking of paths, etc. were
385 * done earlier.
386 */
387 static int
388 smb_enable_share(sa_share_t share)
389 {
390 char *path;
391 smb_share_t si;
392 sa_resource_t resource;
393 boolean_t iszfs;
394 int err = SA_OK;
395 boolean_t online;
396
397 /*
398 * Don't support Trusted Extensions.
399 */
400 if (is_system_labeled()) {
401 (void) printf(dgettext(TEXT_DOMAIN,
402 "SMB: service not supported with Trusted Extensions\n"));
403 return (SA_NOT_SUPPORTED);
404 }
405
406 /* get the path since it is important in several places */
407 path = sa_get_share_attr(share, "path");
408 if (path == NULL)
409 return (SA_NO_SUCH_PATH);
410
411 /*
412 * If administratively disabled, don't try to start anything.
413 */
414 online = smb_isonline();
415 if (!online && !smb_isautoenable() && smb_isdisabled())
416 goto done;
417
418 iszfs = sa_path_is_zfs(path);
419
420 if (!online) {
421 err = smb_enable_service();
422 if (err != SA_OK) {
423 (void) printf(dgettext(TEXT_DOMAIN,
424 "SMB: Unable to enable service\n"));
425 } else {
426 online = B_TRUE;
427 }
428 }
429
430 /*
431 * Don't bother trying to start shares if the service isn't
432 * running.
433 */
434 if (!online)
435 goto done;
436
437 /* Each share can have multiple resources */
438 for (resource = sa_get_share_resource(share, NULL);
439 resource != NULL;
440 resource = sa_get_next_resource(resource)) {
873 SMB_REFRESH_REFRESH },
874 { SMB_CI_RESTRICT_ANON, 0, 0, true_false_validator,
875 SMB_REFRESH_REFRESH },
876 { SMB_CI_DOMAIN_SRV, 0, MAX_VALUE_BUFLEN,
877 hostname_validator, SMB_REFRESH_REFRESH },
878 { SMB_CI_ADS_SITE, 0, MAX_VALUE_BUFLEN,
879 string_length_check_validator, SMB_REFRESH_REFRESH },
880 { SMB_CI_DYNDNS_ENABLE, 0, 0, true_false_validator, 0 },
881 { SMB_CI_AUTOHOME_MAP, 0, MAX_VALUE_BUFLEN, path_validator, 0 },
882 { SMB_CI_IPV6_ENABLE, 0, 0, true_false_validator,
883 SMB_REFRESH_REFRESH },
884 { SMB_CI_PRINT_ENABLE, 0, 0, print_enable_validator,
885 SMB_REFRESH_REFRESH },
886 { SMB_CI_TRAVERSE_MOUNTS, 0, 0, true_false_validator,
887 SMB_REFRESH_REFRESH },
888 { SMB_CI_MAP, 0, MAX_VALUE_BUFLEN, cmd_validator, SMB_REFRESH_REFRESH },
889 { SMB_CI_UNMAP, 0, MAX_VALUE_BUFLEN, cmd_validator,
890 SMB_REFRESH_REFRESH },
891 { SMB_CI_DISPOSITION, 0, MAX_VALUE_BUFLEN,
892 disposition_validator, SMB_REFRESH_REFRESH },
893 { SMB_CI_MAX_PROTOCOL, 0, MAX_VALUE_BUFLEN, protocol_validator,
894 SMB_REFRESH_REFRESH },
895 { SMB_CI_ENCRYPT, 0, MAX_VALUE_BUFLEN, require_validator,
896 SMB_REFRESH_REFRESH },
897 { SMB_CI_MIN_PROTOCOL, 0, MAX_VALUE_BUFLEN, protocol_validator,
898 SMB_REFRESH_REFRESH },
899 { SMB_CI_BYPASS_TRAVERSE_CHECKING, 0, 0, true_false_validator,
900 SMB_REFRESH_REFRESH },
901 { SMB_CI_OPLOCK_ENABLE, 0, 0, true_false_validator,
902 SMB_REFRESH_REFRESH },
903 };
904
905 #define SMB_OPT_NUM \
906 (sizeof (smb_proto_options) / sizeof (smb_proto_options[0]))
907
908 static int
909 require_validator(int index, char *value)
910 {
911 if (string_length_check_validator(index, value) != SA_OK)
912 return (SA_BAD_VALUE);
913
914 if (strcmp(value, "required") == 0)
915 return (SA_OK);
916
917 if (strcmp(value, "disabled") == 0)
918 return (SA_OK);
919
920 if (strcmp(value, "enabled") == 0)
921 return (SA_OK);
922
923 return (SA_BAD_VALUE);
924 }
925
926 /*
927 * Check the range of value as int range.
928 */
929 static int
930 range_check_validator(int index, char *value)
931 {
932 int ret = SA_OK;
933
934 if (!is_a_number(value)) {
935 ret = SA_BAD_VALUE;
936 } else {
937 int val;
938 val = strtoul(value, NULL, 0);
939 if (val < smb_proto_options[index].minval ||
940 val > smb_proto_options[index].maxval)
941 ret = SA_BAD_VALUE;
942 }
943 return (ret);
944 }
945
1519 static int
1520 smb_set_proto_prop(sa_property_t prop)
1521 {
1522 int ret = SA_OK;
1523 char *name;
1524 char *value;
1525 int index = -1;
1526 struct smb_proto_option_defs *opt;
1527
1528 name = sa_get_property_attr(prop, "type");
1529 value = sa_get_property_attr(prop, "value");
1530 if (name != NULL && value != NULL) {
1531 index = findprotoopt(name);
1532 if (index >= 0) {
1533 /* should test for valid value */
1534 ret = smb_validate_proto_prop(index, name, value);
1535 if (ret == SA_OK) {
1536 opt = &smb_proto_options[index];
1537
1538 /* Save to SMF */
1539 if (smb_config_set(opt->smb_index,
1540 value) != 0) {
1541 ret = SA_BAD_VALUE;
1542 goto out;
1543 }
1544 /*
1545 * Specialized refresh mechanisms can
1546 * be flagged in the proto_options and
1547 * processed here.
1548 */
1549 if (opt->refresh & SMB_REFRESH_REFRESH)
1550 (void) smf_refresh_instance(
1551 SMBD_DEFAULT_INSTANCE_FMRI);
1552 else if (opt->refresh & SMB_REFRESH_RESTART)
1553 (void) smf_restart_instance(
1554 SMBD_DEFAULT_INSTANCE_FMRI);
1555 }
1556 }
1557 }
1558
1559 out:
1560 if (name != NULL)
1561 sa_free_attr_string(name);
1562 if (value != NULL)
1563 sa_free_attr_string(value);
1564
1565 return (ret);
1566 }
1567
1568 /*
1569 * smb_get_status()
1570 *
1571 * What is the current status of the smbd? We use the SMF state here.
1572 * Caller must free the returned value.
1573 */
1574
1575 static char *
1576 smb_get_status(void)
1577 {
1578 return (smf_get_state(SMBD_DEFAULT_INSTANCE_FMRI));
1579 }
2105 break;
2106 case NERR_DuplicateShare:
2107 ret = SA_DUPLICATE_NAME;
2108 break;
2109 default:
2110 ret = SA_CONFIG_ERR;
2111 break;
2112 }
2113
2114 return (ret);
2115 }
2116
2117 static int
2118 smb_build_shareinfo(sa_share_t share, sa_resource_t resource, smb_share_t *si)
2119 {
2120 sa_optionset_t opts;
2121 char *path;
2122 char *rname;
2123 char *val = NULL;
2124 char csc_value[SMB_CSC_BUFSZ];
2125 char strbuf[sizeof ("required")];
2126
2127 bzero(si, sizeof (smb_share_t));
2128
2129 if ((path = sa_get_share_attr(share, "path")) == NULL)
2130 return (SA_NO_SUCH_PATH);
2131
2132 if ((rname = sa_get_resource_attr(resource, "name")) == NULL) {
2133 sa_free_attr_string(path);
2134 return (SA_NO_SUCH_RESOURCE);
2135 }
2136
2137 (void) strlcpy(si->shr_path, path, sizeof (si->shr_path));
2138 (void) strlcpy(si->shr_name, rname, sizeof (si->shr_name));
2139 sa_free_attr_string(path);
2140 sa_free_attr_string(rname);
2141
2142 val = sa_get_resource_description(resource);
2143 if (val == NULL)
2144 val = sa_get_share_description(share);
2145
2146 if (val != NULL) {
2147 (void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt));
2148 sa_free_share_description(val);
2149 }
2150
2151 si->shr_flags = (sa_is_persistent(share))
2152 ? SMB_SHRF_PERM : SMB_SHRF_TRANS;
2153
2154 opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1);
2155 if (opts == NULL)
2156 return (SA_OK);
2157
2158 if (smb_saprop_getbool(opts, SHOPT_CATIA, B_FALSE))
2159 si->shr_flags |= SMB_SHRF_CATIA;
2160
2161 if (smb_saprop_getbool(opts, SHOPT_ABE, B_FALSE))
2162 si->shr_flags |= SMB_SHRF_ABE;
2163
2164 if (smb_saprop_getbool(opts, SHOPT_GUEST, B_FALSE))
2165 si->shr_flags |= SMB_SHRF_GUEST_OK;
2166
2167 if (smb_saprop_getbool(opts, SHOPT_DFSROOT, B_FALSE))
2168 si->shr_flags |= SMB_SHRF_DFSROOT;
2169
2170 if (smb_saprop_getbool(opts, SHOPT_CA, B_FALSE))
2171 si->shr_flags |= SMB_SHRF_CA;
2172
2173 if (smb_saprop_getbool(opts, SHOPT_FSO, B_FALSE))
2174 si->shr_flags |= SMB_SHRF_FSO;
2175
2176 /* Quotas are enabled by default. */
2177 if (smb_saprop_getbool(opts, SHOPT_QUOTAS, B_TRUE))
2178 si->shr_flags |= SMB_SHRF_QUOTAS;
2179
2180 if (smb_saprop_getstr(opts, SHOPT_ENCRYPT, strbuf, sizeof (strbuf)))
2181 smb_cfg_set_require(strbuf, &si->shr_encrypt);
2182
2183 (void) smb_saprop_getstr(opts, SHOPT_AD_CONTAINER, si->shr_container,
2184 sizeof (si->shr_container));
2185
2186 if (smb_saprop_getstr(opts, SHOPT_CSC, csc_value, sizeof (csc_value)))
2187 smb_csc_option(csc_value, si);
2188
2189 if (smb_saprop_getstr(opts, SHOPT_RO, si->shr_access_ro,
2190 sizeof (si->shr_access_ro)))
2191 si->shr_flags |= SMB_SHRF_ACC_RO;
2192
2193 if (smb_saprop_getstr(opts, SHOPT_RW, si->shr_access_rw,
2194 sizeof (si->shr_access_rw)))
2195 si->shr_flags |= SMB_SHRF_ACC_RW;
2196
2197 if (smb_saprop_getstr(opts, SHOPT_NONE, si->shr_access_none,
2198 sizeof (si->shr_access_none)))
2199 si->shr_flags |= SMB_SHRF_ACC_NONE;
2200
2201 sa_free_derived_optionset(opts);
2202 return (SA_OK);
2351
2352 /*ARGSUSED*/
2353 static int
2354 disposition_validator(int index, char *value)
2355 {
2356 if (value == NULL)
2357 return (SA_BAD_VALUE);
2358
2359 if (*value == '\0')
2360 return (SA_OK);
2361
2362 if ((strcasecmp(value, SMB_EXEC_DISP_CONTINUE) == 0) ||
2363 (strcasecmp(value, SMB_EXEC_DISP_TERMINATE) == 0))
2364 return (SA_OK);
2365
2366 return (SA_BAD_VALUE);
2367 }
2368
2369 /*ARGSUSED*/
2370 static int
2371 protocol_validator(int index, char *value)
2372 {
2373 if (value == NULL)
2374 return (SA_BAD_VALUE);
2375
2376 if (*value == '\0')
2377 return (SA_OK);
2378
2379 if (smb_config_check_protocol(value) == 0)
2380 return (SA_OK);
2381
2382 return (SA_BAD_VALUE);
2383
2384 }
2385
2386 /*
2387 * Updates the optionset properties of the share resource.
2388 * The properties are given as a list of name-value pair.
2389 * The name argument should be the optionset property name and the value
2390 * should be a valid value for the specified property.
2391 *
2427 (void) sa_remove_property(prop);
2428 break;
2429 }
2430 }
2431 err = sa_add_property(opts, prop);
2432 if (err != SA_OK)
2433 break;
2434 } else {
2435 err = sa_update_property(prop, val);
2436 if (err != SA_OK)
2437 break;
2438 }
2439
2440 cur = nvlist_next_nvpair(nvl, cur);
2441 }
2442
2443 return (err);
2444 }
2445
2446 static boolean_t
2447 smb_saprop_getbool(sa_optionset_t opts, char *propname, boolean_t def)
2448 {
2449 sa_property_t prop;
2450 char *val;
2451 boolean_t ret = def;
2452
2453 prop = sa_get_property(opts, propname);
2454 if ((val = sa_get_property_attr(prop, "value")) != NULL) {
2455 if (def) {
2456 /* Default is true, ret false if... */
2457 if ((strcasecmp(val, "false") == 0) ||
2458 (strcmp(val, "0") == 0))
2459 ret = B_FALSE;
2460 } else {
2461 /* Default is false, ret true if... */
2462 if ((strcasecmp(val, "true") == 0) ||
2463 (strcmp(val, "1") == 0))
2464 ret = B_TRUE;
2465 }
2466 free(val);
2467 }
2468
2469 return (ret);
2470 }
2471
2472 static boolean_t
2473 smb_saprop_getstr(sa_optionset_t opts, char *propname, char *buf, size_t bufsz)
2474 {
2475 sa_property_t prop;
2476 char *val;
2477
2478 prop = sa_get_property(opts, propname);
2479 if ((val = sa_get_property_attr(prop, "value")) != NULL) {
2480 (void) strlcpy(buf, val, bufsz);
2481 free(val);
2482 return (B_TRUE);
2483 }
2484
2485 return (B_FALSE);
2486 }
|