Print this page
NEX-19857 ads_site broken in sharectl get/set smb
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-17523 Enable SMB3 server by default
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-17289 Minimal SMB 3.0.2 support
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-9497 SMB should bypass ACL traverse checking
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-10019 SMB server min_protocol setting
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3611 CLONE NEX-3550 Replace smb2_enable with max_protocol
Reviewed by: Yuri Pankov <Yuri.Pankov@nexenta.com>
NEX-2314 SMB server debug logging needs improvement
NEX-1852 re-enable Kerberos-style AD join (try 2)
NEX-1638 Updated DC Locator
Includes work by: matt.barden@nexenta.com, kevin.crowe@nexenta.com
NEX-1050 enable_smb2 should be smb2_enable
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-56 extended security NTLMSSP, inbound
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
SFR-56 Identity Management for UNIX (IDMU) authentication support
re #6813 rb1757 port 2976 Child folder visibility through shares
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
+++ new/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * CIFS configuration management library
28 28 */
29 29
30 30 #include <stdio.h>
31 31 #include <stdlib.h>
32 32 #include <unistd.h>
33 33 #include <synch.h>
34 34 #include <string.h>
35 35 #include <strings.h>
36 36 #include <syslog.h>
37 37 #include <netdb.h>
38 38 #include <ctype.h>
39 39 #include <sys/types.h>
40 40 #include <libscf.h>
41 41 #include <assert.h>
42 42 #include <uuid/uuid.h>
43 43 #include <smbsrv/libsmb.h>
44 44
45 45 typedef struct smb_cfg_param {
46 46 smb_cfg_id_t sc_id;
47 47 char *sc_name;
48 48 int sc_type;
49 49 uint32_t sc_flags;
50 50 } smb_cfg_param_t;
51 51
52 52 struct str_val {
53 53 char *str;
54 54 uint32_t val;
55 55 };
56 56
57 57 /*
58 58 * config parameter flags
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
59 59 */
60 60 #define SMB_CF_PROTECTED 0x01
61 61 #define SMB_CF_EXEC 0x02
62 62
63 63 /* idmap SMF fmri and Property Group */
64 64 #define IDMAP_FMRI_PREFIX "system/idmap"
65 65 #define MACHINE_SID "machine_sid"
66 66 #define MACHINE_UUID "machine_uuid"
67 67 #define IDMAP_DOMAIN "domain_name"
68 68 #define IDMAP_PREF_DC "preferred_dc"
69 +#define IDMAP_SITE_NAME "site_name"
69 70 #define IDMAP_PG_NAME "config"
70 71
71 72 #define SMB_SECMODE_WORKGRP_STR "workgroup"
72 73 #define SMB_SECMODE_DOMAIN_STR "domain"
73 74
74 75 #define SMB_ENC_LEN 1024
75 76 #define SMB_DEC_LEN 256
76 77
77 78 static char *b64_data =
78 79 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
79 80
80 81 static smb_cfg_param_t smb_cfg_table[] =
81 82 {
82 83 {SMB_CI_VERSION, "sv_version", SCF_TYPE_ASTRING, 0},
83 84
84 85 /* Oplock configuration, Kernel Only */
85 86 {SMB_CI_OPLOCK_ENABLE, "oplock_enable", SCF_TYPE_BOOLEAN, 0},
86 87
87 88 /* Autohome configuration */
88 89 {SMB_CI_AUTOHOME_MAP, "autohome_map", SCF_TYPE_ASTRING, 0},
89 90
90 91 /* Domain/PDC configuration */
91 92 {SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0},
92 93 {SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0},
93 94 {SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0},
94 95 {SMB_CI_DOMAIN_FQDN, "fqdn", SCF_TYPE_ASTRING, 0},
95 96 {SMB_CI_DOMAIN_FOREST, "forest", SCF_TYPE_ASTRING, 0},
96 97 {SMB_CI_DOMAIN_GUID, "domain_guid", SCF_TYPE_ASTRING, 0},
97 98 {SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0},
98 99
99 100 /* WINS configuration */
100 101 {SMB_CI_WINS_SRV1, "wins_server_1", SCF_TYPE_ASTRING, 0},
101 102 {SMB_CI_WINS_SRV2, "wins_server_2", SCF_TYPE_ASTRING, 0},
102 103 {SMB_CI_WINS_EXCL, "wins_exclude", SCF_TYPE_ASTRING, 0},
103 104
104 105 /* Kmod specific configuration */
105 106 {SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0},
106 107 {SMB_CI_MAX_CONNECTIONS, "max_connections", SCF_TYPE_INTEGER, 0},
107 108 {SMB_CI_KEEPALIVE, "keep_alive", SCF_TYPE_INTEGER, 0},
108 109 {SMB_CI_RESTRICT_ANON, "restrict_anonymous", SCF_TYPE_BOOLEAN, 0},
109 110
110 111 {SMB_CI_SIGNING_ENABLE, "signing_enabled", SCF_TYPE_BOOLEAN, 0},
111 112 {SMB_CI_SIGNING_REQD, "signing_required", SCF_TYPE_BOOLEAN, 0},
112 113
113 114 /* Kmod tuning configuration */
114 115 {SMB_CI_SYNC_ENABLE, "sync_enable", SCF_TYPE_BOOLEAN, 0},
115 116
116 117 /* SMBd configuration */
117 118 {SMB_CI_SECURITY, "security", SCF_TYPE_ASTRING, 0},
118 119 {SMB_CI_NETBIOS_ENABLE, "netbios_enable", SCF_TYPE_BOOLEAN, 0},
119 120 {SMB_CI_NBSCOPE, "netbios_scope", SCF_TYPE_ASTRING, 0},
120 121 {SMB_CI_SYS_CMNT, "system_comment", SCF_TYPE_ASTRING, 0},
121 122 {SMB_CI_LM_LEVEL, "lmauth_level", SCF_TYPE_INTEGER, 0},
122 123
123 124 /* ADS Configuration */
124 125 {SMB_CI_ADS_SITE, "ads_site", SCF_TYPE_ASTRING, 0},
125 126
126 127 /* Dynamic DNS */
127 128 {SMB_CI_DYNDNS_ENABLE, "ddns_enable", SCF_TYPE_BOOLEAN, 0},
128 129
129 130 {SMB_CI_MACHINE_PASSWD, "machine_passwd", SCF_TYPE_ASTRING,
130 131 SMB_CF_PROTECTED},
131 132
132 133 {SMB_CI_MACHINE_UUID, "machine_uuid", SCF_TYPE_ASTRING, 0},
133 134 {SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING, 0},
134 135 {SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING, 0},
135 136 {SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER, 0},
136 137 {SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER, 0},
137 138 {SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0},
|
↓ open down ↓ |
59 lines elided |
↑ open up ↑ |
138 139 {SMB_CI_PRINT_ENABLE, "print_enable", SCF_TYPE_BOOLEAN, 0},
139 140 {SMB_CI_MAP, "map", SCF_TYPE_ASTRING, SMB_CF_EXEC},
140 141 {SMB_CI_UNMAP, "unmap", SCF_TYPE_ASTRING, SMB_CF_EXEC},
141 142 {SMB_CI_DISPOSITION, "disposition", SCF_TYPE_ASTRING, SMB_CF_EXEC},
142 143 {SMB_CI_DFS_STDROOT_NUM, "dfs_stdroot_num", SCF_TYPE_INTEGER, 0},
143 144 {SMB_CI_TRAVERSE_MOUNTS, "traverse_mounts", SCF_TYPE_BOOLEAN, 0},
144 145 {SMB_CI_SMB2_ENABLE_OLD, "smb2_enable", SCF_TYPE_BOOLEAN, 0},
145 146 {SMB_CI_INITIAL_CREDITS, "initial_credits", SCF_TYPE_INTEGER, 0},
146 147 {SMB_CI_MAXIMUM_CREDITS, "maximum_credits", SCF_TYPE_INTEGER, 0},
147 148 {SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0},
149 + {SMB_CI_ENCRYPT, "encrypt", SCF_TYPE_ASTRING, 0},
150 + {SMB_CI_MIN_PROTOCOL, "min_protocol", SCF_TYPE_ASTRING, 0},
151 + {SMB_CI_BYPASS_TRAVERSE_CHECKING,
152 + "bypass_traverse_checking", SCF_TYPE_BOOLEAN, 0},
148 153
149 154 /* SMB_CI_MAX */
150 155 };
151 156
157 +/*
158 + * We store the max SMB protocol version in SMF as a string,
159 + * (for convenience of svccfg etc) but the programmatic get/set
160 + * interfaces use the numeric form.
161 + *
162 + * The numeric values are as defined in the [MS-SMB2] spec.
163 + * except for how we represent "1" (for SMB1) which is an
164 + * arbitrary value below SMB2_VERS_BASE.
165 + */
166 +static struct str_val
167 +smb_versions[] = {
168 + { "3.02", SMB_VERS_3_02 },
169 + { "3.0", SMB_VERS_3_0 },
170 + { "2.1", SMB_VERS_2_1 },
171 + { "2.002", SMB_VERS_2_002 },
172 + { "1", SMB_VERS_1 },
173 + { NULL, 0 }
174 +};
175 +
152 176 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
153 177
154 178 static boolean_t smb_is_base64(unsigned char c);
155 179 static char *smb_base64_encode(char *str_to_encode);
156 180 static char *smb_base64_decode(char *encoded_str);
157 181 static int smb_config_get_idmap_preferred_dc(char *, int);
158 182 static int smb_config_set_idmap_preferred_dc(char *);
183 +static int smb_config_get_idmap_site_name(char *, int);
184 +static int smb_config_set_idmap_site_name(char *);
159 185
186 +static uint32_t
187 +smb_convert_version_str(const char *version)
188 +{
189 + uint32_t dialect = 0;
190 + int i;
191 +
192 + for (i = 0; smb_versions[i].str != NULL; i++) {
193 + if (strcmp(version, smb_versions[i].str) == 0)
194 + dialect = smb_versions[i].val;
195 + }
196 +
197 + return (dialect);
198 +}
199 +
160 200 char *
161 201 smb_config_getname(smb_cfg_id_t id)
162 202 {
163 203 smb_cfg_param_t *cfg;
164 204 cfg = smb_config_getent(id);
165 205 return (cfg->sc_name);
166 206 }
167 207
168 208 static boolean_t
169 209 smb_is_base64(unsigned char c)
170 210 {
171 211 return (isalnum(c) || (c == '+') || (c == '/'));
172 212 }
173 213
174 214 /*
175 215 * smb_base64_encode
176 216 *
177 217 * Encode a string using base64 algorithm.
178 218 * Caller should free the returned buffer when done.
179 219 */
180 220 static char *
181 221 smb_base64_encode(char *str_to_encode)
182 222 {
183 223 int ret_cnt = 0;
184 224 int i = 0, j = 0;
185 225 char arr_3[3], arr_4[4];
186 226 int len = strlen(str_to_encode);
187 227 char *ret = malloc(SMB_ENC_LEN);
188 228
189 229 if (ret == NULL) {
190 230 return (NULL);
191 231 }
192 232
193 233 while (len--) {
194 234 arr_3[i++] = *(str_to_encode++);
195 235 if (i == 3) {
196 236 arr_4[0] = (arr_3[0] & 0xfc) >> 2;
197 237 arr_4[1] = ((arr_3[0] & 0x03) << 4) +
198 238 ((arr_3[1] & 0xf0) >> 4);
199 239 arr_4[2] = ((arr_3[1] & 0x0f) << 2) +
200 240 ((arr_3[2] & 0xc0) >> 6);
201 241 arr_4[3] = arr_3[2] & 0x3f;
202 242
203 243 for (i = 0; i < 4; i++)
204 244 ret[ret_cnt++] = b64_data[arr_4[i]];
205 245 i = 0;
206 246 }
207 247 }
208 248
209 249 if (i) {
210 250 for (j = i; j < 3; j++)
211 251 arr_3[j] = '\0';
212 252
213 253 arr_4[0] = (arr_3[0] & 0xfc) >> 2;
214 254 arr_4[1] = ((arr_3[0] & 0x03) << 4) +
215 255 ((arr_3[1] & 0xf0) >> 4);
216 256 arr_4[2] = ((arr_3[1] & 0x0f) << 2) +
217 257 ((arr_3[2] & 0xc0) >> 6);
218 258 arr_4[3] = arr_3[2] & 0x3f;
219 259
220 260 for (j = 0; j < (i + 1); j++)
221 261 ret[ret_cnt++] = b64_data[arr_4[j]];
222 262
223 263 while (i++ < 3)
224 264 ret[ret_cnt++] = '=';
225 265 }
226 266
227 267 ret[ret_cnt++] = '\0';
228 268 return (ret);
229 269 }
230 270
231 271 /*
232 272 * smb_base64_decode
233 273 *
234 274 * Decode using base64 algorithm.
235 275 * Caller should free the returned buffer when done.
236 276 */
237 277 static char *
238 278 smb_base64_decode(char *encoded_str)
239 279 {
240 280 int len = strlen(encoded_str);
241 281 int i = 0, j = 0;
242 282 int en_ind = 0;
243 283 char arr_4[4], arr_3[3];
244 284 int ret_cnt = 0;
245 285 char *ret = malloc(SMB_DEC_LEN);
246 286 char *p;
247 287
248 288 if (ret == NULL) {
249 289 return (NULL);
250 290 }
251 291
252 292 while (len-- && (encoded_str[en_ind] != '=') &&
253 293 smb_is_base64(encoded_str[en_ind])) {
254 294 arr_4[i++] = encoded_str[en_ind];
255 295 en_ind++;
256 296 if (i == 4) {
257 297 for (i = 0; i < 4; i++) {
258 298 if ((p = strchr(b64_data, arr_4[i])) == NULL)
259 299 return (NULL);
260 300
261 301 arr_4[i] = (int)(p - b64_data);
262 302 }
263 303
264 304 arr_3[0] = (arr_4[0] << 2) +
265 305 ((arr_4[1] & 0x30) >> 4);
266 306 arr_3[1] = ((arr_4[1] & 0xf) << 4) +
267 307 ((arr_4[2] & 0x3c) >> 2);
268 308 arr_3[2] = ((arr_4[2] & 0x3) << 6) +
269 309 arr_4[3];
270 310
271 311 for (i = 0; i < 3; i++)
272 312 ret[ret_cnt++] = arr_3[i];
273 313
274 314 i = 0;
275 315 }
276 316 }
277 317
278 318 if (i) {
279 319 for (j = i; j < 4; j++)
280 320 arr_4[j] = 0;
281 321
282 322 for (j = 0; j < 4; j++) {
283 323 if ((p = strchr(b64_data, arr_4[j])) == NULL)
284 324 return (NULL);
285 325
286 326 arr_4[j] = (int)(p - b64_data);
287 327 }
288 328 arr_3[0] = (arr_4[0] << 2) +
289 329 ((arr_4[1] & 0x30) >> 4);
290 330 arr_3[1] = ((arr_4[1] & 0xf) << 4) +
291 331 ((arr_4[2] & 0x3c) >> 2);
292 332 arr_3[2] = ((arr_4[2] & 0x3) << 6) +
293 333 arr_4[3];
294 334 for (j = 0; j < (i - 1); j++)
295 335 ret[ret_cnt++] = arr_3[j];
296 336 }
297 337
298 338 ret[ret_cnt++] = '\0';
299 339 return (ret);
300 340 }
301 341
302 342 static char *
303 343 smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp)
304 344 {
305 345 smb_scfhandle_t *handle;
306 346 char *value;
307 347
308 348 if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL)
309 349 return (NULL);
310 350
311 351 handle = smb_smf_scf_init(svc_fmri_prefix);
312 352 if (handle == NULL) {
313 353 free(value);
314 354 return (NULL);
315 355 }
316 356
317 357 (void) smb_smf_create_service_pgroup(handle, svc_propgrp);
318 358
319 359 if (smb_smf_get_string_property(handle, name, value,
320 360 sizeof (char) * MAX_VALUE_BUFLEN) != 0) {
321 361 smb_smf_scf_fini(handle);
322 362 free(value);
323 363 return (NULL);
324 364 }
325 365
326 366 smb_smf_scf_fini(handle);
327 367 return (value);
328 368
329 369 }
330 370
331 371 static int
332 372 smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp,
333 373 char *name, char *value)
334 374 {
335 375 smb_scfhandle_t *handle = NULL;
336 376 int rc = 0;
337 377
338 378
339 379 handle = smb_smf_scf_init(svc_fmri_prefix);
340 380 if (handle == NULL) {
341 381 return (1);
342 382 }
343 383
344 384 (void) smb_smf_create_service_pgroup(handle, svc_propgrp);
345 385
346 386 if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) {
347 387 smb_smf_scf_fini(handle);
348 388 return (1);
349 389 }
350 390
351 391 if (smb_smf_set_string_property(handle, name, value) != SMBD_SMF_OK)
352 392 rc = 1;
353 393
354 394 if (smb_smf_end_transaction(handle) != SMBD_SMF_OK)
355 395 rc = 1;
356 396
357 397 smb_smf_scf_fini(handle);
358 398 return (rc);
359 399 }
360 400
361 401 /*
362 402 * smb_config_getstr
363 403 *
364 404 * Fetch the specified string configuration item from SMF
365 405 */
366 406 int
367 407 smb_config_getstr(smb_cfg_id_t id, char *cbuf, int bufsz)
368 408 {
369 409 smb_scfhandle_t *handle;
|
↓ open down ↓ |
200 lines elided |
↑ open up ↑ |
370 410 smb_cfg_param_t *cfg;
371 411 int rc = SMBD_SMF_OK;
372 412 char *pg;
373 413 char protbuf[SMB_ENC_LEN];
374 414 char *tmp;
375 415
376 416 *cbuf = '\0';
377 417 cfg = smb_config_getent(id);
378 418 assert(cfg->sc_type == SCF_TYPE_ASTRING);
379 419
420 + if (id == SMB_CI_ADS_SITE)
421 + return (smb_config_get_idmap_site_name(cbuf, bufsz));
380 422 if (id == SMB_CI_DOMAIN_SRV)
381 423 return (smb_config_get_idmap_preferred_dc(cbuf, bufsz));
382 424
383 425 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
384 426 if (handle == NULL)
385 427 return (SMBD_SMF_SYSTEM_ERR);
386 428
387 429 if (cfg->sc_flags & SMB_CF_PROTECTED) {
388 430 if ((rc = smb_smf_create_service_pgroup(handle,
389 431 SMBD_PROTECTED_PG_NAME)) != SMBD_SMF_OK)
390 432 goto error;
391 433
392 434 if ((rc = smb_smf_get_string_property(handle, cfg->sc_name,
393 435 protbuf, sizeof (protbuf))) != SMBD_SMF_OK)
394 436 goto error;
395 437
396 438 if (*protbuf != '\0') {
397 439 tmp = smb_base64_decode(protbuf);
398 440 (void) strlcpy(cbuf, tmp, bufsz);
399 441 free(tmp);
400 442 }
401 443 } else {
402 444 pg = (cfg->sc_flags & SMB_CF_EXEC) ? SMBD_EXEC_PG_NAME :
403 445 SMBD_PG_NAME;
404 446 rc = smb_smf_create_service_pgroup(handle, pg);
405 447 if (rc == SMBD_SMF_OK)
406 448 rc = smb_smf_get_string_property(handle, cfg->sc_name,
407 449 cbuf, bufsz);
408 450 }
409 451
410 452 error:
411 453 smb_smf_scf_fini(handle);
412 454 return (rc);
413 455 }
414 456
415 457 /*
416 458 * Translate the value of an astring SMF property into a binary
417 459 * IP address. If the value is neither a valid IPv4 nor IPv6
418 460 * address, attempt to look it up as a hostname using the
419 461 * configured address type.
420 462 */
421 463 int
422 464 smb_config_getip(smb_cfg_id_t sc_id, smb_inaddr_t *ipaddr)
423 465 {
424 466 int rc, error;
425 467 int a_family;
426 468 char ipstr[MAXHOSTNAMELEN];
427 469 struct hostent *h;
428 470 smb_cfg_param_t *cfg;
429 471
430 472 if (ipaddr == NULL)
431 473 return (SMBD_SMF_INVALID_ARG);
432 474
433 475 bzero(ipaddr, sizeof (smb_inaddr_t));
434 476 rc = smb_config_getstr(sc_id, ipstr, sizeof (ipstr));
435 477 if (rc == SMBD_SMF_OK) {
436 478 if (*ipstr == '\0')
437 479 return (SMBD_SMF_INVALID_ARG);
438 480
439 481 if (inet_pton(AF_INET, ipstr, &ipaddr->a_ipv4) == 1) {
440 482 ipaddr->a_family = AF_INET;
441 483 return (SMBD_SMF_OK);
442 484 }
443 485
444 486 if (inet_pton(AF_INET6, ipstr, &ipaddr->a_ipv6) == 1) {
445 487 ipaddr->a_family = AF_INET6;
446 488 return (SMBD_SMF_OK);
447 489 }
448 490
449 491 /*
450 492 * The value is neither an IPv4 nor IPv6 address;
451 493 * so check if it's a hostname.
452 494 */
453 495 a_family = smb_config_getbool(SMB_CI_IPV6_ENABLE) ?
454 496 AF_INET6 : AF_INET;
455 497 h = getipnodebyname(ipstr, a_family, AI_DEFAULT,
456 498 &error);
457 499 if (h != NULL) {
458 500 bcopy(*(h->h_addr_list), &ipaddr->a_ip,
459 501 h->h_length);
460 502 ipaddr->a_family = a_family;
461 503 freehostent(h);
462 504 rc = SMBD_SMF_OK;
463 505 } else {
464 506 cfg = smb_config_getent(sc_id);
465 507 syslog(LOG_ERR, "smbd/%s: %s unable to get %s "
466 508 "address: %d", cfg->sc_name, ipstr,
467 509 a_family == AF_INET ? "IPv4" : "IPv6", error);
468 510 rc = SMBD_SMF_INVALID_ARG;
469 511 }
470 512 }
471 513
472 514 return (rc);
473 515 }
474 516
475 517 /*
476 518 * smb_config_getnum
477 519 *
478 520 * Returns the value of a numeric config param.
479 521 */
480 522 int
481 523 smb_config_getnum(smb_cfg_id_t id, int64_t *cint)
482 524 {
483 525 smb_scfhandle_t *handle;
484 526 smb_cfg_param_t *cfg;
485 527 int rc = SMBD_SMF_OK;
486 528
487 529 *cint = 0;
488 530 cfg = smb_config_getent(id);
489 531 assert(cfg->sc_type == SCF_TYPE_INTEGER);
490 532
491 533 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
492 534 if (handle == NULL)
493 535 return (SMBD_SMF_SYSTEM_ERR);
494 536
495 537 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
496 538 if (rc == SMBD_SMF_OK)
497 539 rc = smb_smf_get_integer_property(handle, cfg->sc_name, cint);
498 540 smb_smf_scf_fini(handle);
499 541
500 542 return (rc);
501 543 }
502 544
503 545 /*
504 546 * smb_config_getbool
505 547 *
506 548 * Returns the value of a boolean config param.
507 549 */
508 550 boolean_t
509 551 smb_config_getbool(smb_cfg_id_t id)
510 552 {
511 553 smb_scfhandle_t *handle;
512 554 smb_cfg_param_t *cfg;
513 555 int rc = SMBD_SMF_OK;
514 556 uint8_t vbool;
515 557
516 558 cfg = smb_config_getent(id);
517 559 assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
518 560
519 561 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
520 562 if (handle == NULL)
521 563 return (B_FALSE);
522 564
523 565 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
524 566 if (rc == SMBD_SMF_OK)
525 567 rc = smb_smf_get_boolean_property(handle, cfg->sc_name, &vbool);
526 568 smb_smf_scf_fini(handle);
527 569
528 570 return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE);
529 571 }
530 572
531 573 /*
532 574 * smb_config_get
533 575 *
534 576 * This function returns the value of the requested config
535 577 * iterm regardless of its type in string format. This should
536 578 * be used when the config item type is not known by the caller.
537 579 */
538 580 int
539 581 smb_config_get(smb_cfg_id_t id, char *cbuf, int bufsz)
540 582 {
541 583 smb_cfg_param_t *cfg;
542 584 int64_t cint;
543 585 int rc;
544 586
545 587 cfg = smb_config_getent(id);
546 588 switch (cfg->sc_type) {
547 589 case SCF_TYPE_ASTRING:
548 590 return (smb_config_getstr(id, cbuf, bufsz));
549 591
550 592 case SCF_TYPE_INTEGER:
551 593 rc = smb_config_getnum(id, &cint);
552 594 if (rc == SMBD_SMF_OK)
553 595 (void) snprintf(cbuf, bufsz, "%lld", cint);
554 596 return (rc);
555 597
556 598 case SCF_TYPE_BOOLEAN:
557 599 if (smb_config_getbool(id))
558 600 (void) strlcpy(cbuf, "true", bufsz);
559 601 else
560 602 (void) strlcpy(cbuf, "false", bufsz);
561 603 return (SMBD_SMF_OK);
562 604 }
563 605
564 606 return (SMBD_SMF_INVALID_ARG);
565 607 }
566 608
567 609 /*
568 610 * smb_config_setstr
569 611 *
570 612 * Set the specified config param with the given
571 613 * value.
572 614 */
573 615 int
574 616 smb_config_setstr(smb_cfg_id_t id, char *value)
575 617 {
|
↓ open down ↓ |
186 lines elided |
↑ open up ↑ |
576 618 smb_scfhandle_t *handle;
577 619 smb_cfg_param_t *cfg;
578 620 int rc = SMBD_SMF_OK;
579 621 boolean_t protected;
580 622 char *tmp = NULL;
581 623 char *pg;
582 624
583 625 cfg = smb_config_getent(id);
584 626 assert(cfg->sc_type == SCF_TYPE_ASTRING);
585 627
628 + if (id == SMB_CI_ADS_SITE)
629 + return (smb_config_set_idmap_site_name(value));
586 630 if (id == SMB_CI_DOMAIN_SRV)
587 631 return (smb_config_set_idmap_preferred_dc(value));
588 632
589 633 protected = B_FALSE;
590 634
591 635 switch (cfg->sc_flags) {
592 636 case SMB_CF_PROTECTED:
593 637 protected = B_TRUE;
594 638 pg = SMBD_PROTECTED_PG_NAME;
595 639 break;
596 640 case SMB_CF_EXEC:
597 641 pg = SMBD_EXEC_PG_NAME;
598 642 break;
599 643 default:
600 644 pg = SMBD_PG_NAME;
601 645 break;
602 646 }
603 647
604 648 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
605 649 if (handle == NULL)
606 650 return (SMBD_SMF_SYSTEM_ERR);
607 651
608 652 rc = smb_smf_create_service_pgroup(handle, pg);
609 653 if (rc == SMBD_SMF_OK)
610 654 rc = smb_smf_start_transaction(handle);
611 655
612 656 if (rc != SMBD_SMF_OK) {
613 657 smb_smf_scf_fini(handle);
614 658 return (rc);
615 659 }
616 660
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
617 661 if (protected && value && (*value != '\0')) {
618 662 if ((tmp = smb_base64_encode(value)) == NULL) {
619 663 (void) smb_smf_end_transaction(handle);
620 664 smb_smf_scf_fini(handle);
621 665 return (SMBD_SMF_NO_MEMORY);
622 666 }
623 667
624 668 value = tmp;
625 669 }
626 670
627 - rc = smb_smf_set_string_property(handle, cfg->sc_name, value);
671 + /*
672 + * We don't want people who care enough about protecting their data
673 + * by requiring encryption to accidentally expose their data
674 + * by lowering the protocol, so prevent them from going below 3.0
675 + * if encryption is required.
676 + * Also, ensure that max_protocol >= min_protocol.
677 + */
678 + if (id == SMB_CI_MAX_PROTOCOL) {
679 + smb_cfg_val_t encrypt;
680 + uint32_t min;
681 + uint32_t val;
628 682
683 + encrypt = smb_config_get_require(SMB_CI_ENCRYPT);
684 + min = smb_config_get_min_protocol();
685 + val = smb_convert_version_str(value);
686 +
687 + if (encrypt == SMB_CONFIG_REQUIRED &&
688 + val < SMB_VERS_3_0) {
689 + syslog(LOG_ERR, "Cannot set smbd/max_protocol below 3.0"
690 + " while smbd/encrypt == required.");
691 + rc = SMBD_SMF_INVALID_ARG;
692 + } else if (val < min) {
693 + syslog(LOG_ERR, "Cannot set smbd/max_protocol to less"
694 + " than smbd/min_protocol.");
695 + rc = SMBD_SMF_INVALID_ARG;
696 + }
697 + } else if (id == SMB_CI_MIN_PROTOCOL) {
698 + uint32_t max;
699 + uint32_t val;
700 +
701 + max = smb_config_get_max_protocol();
702 + val = smb_convert_version_str(value);
703 +
704 + if (val > max) {
705 + syslog(LOG_ERR, "Cannot set smbd/min_protocol to more"
706 + " than smbd/max_protocol.");
707 + rc = SMBD_SMF_INVALID_ARG;
708 + }
709 + }
710 +
711 + if (rc == SMBD_SMF_OK) {
712 + rc = smb_smf_set_string_property(handle, cfg->sc_name, value);
713 + }
714 +
629 715 free(tmp);
630 716 (void) smb_smf_end_transaction(handle);
631 717 smb_smf_scf_fini(handle);
632 718 return (rc);
633 719 }
634 720
635 721 /*
636 722 * smb_config_setnum
637 723 *
638 724 * Sets a numeric configuration iterm
639 725 */
640 726 int
641 727 smb_config_setnum(smb_cfg_id_t id, int64_t value)
642 728 {
643 729 smb_scfhandle_t *handle;
644 730 smb_cfg_param_t *cfg;
645 731 int rc = SMBD_SMF_OK;
646 732
647 733 cfg = smb_config_getent(id);
648 734 assert(cfg->sc_type == SCF_TYPE_INTEGER);
649 735
650 736 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
651 737 if (handle == NULL)
652 738 return (SMBD_SMF_SYSTEM_ERR);
653 739
654 740 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
655 741 if (rc == SMBD_SMF_OK)
656 742 rc = smb_smf_start_transaction(handle);
657 743
658 744 if (rc != SMBD_SMF_OK) {
659 745 smb_smf_scf_fini(handle);
660 746 return (rc);
661 747 }
662 748
663 749 rc = smb_smf_set_integer_property(handle, cfg->sc_name, value);
664 750
665 751 (void) smb_smf_end_transaction(handle);
666 752 smb_smf_scf_fini(handle);
667 753 return (rc);
668 754 }
669 755
670 756 /*
671 757 * smb_config_setbool
672 758 *
673 759 * Sets a boolean configuration iterm
674 760 */
675 761 int
676 762 smb_config_setbool(smb_cfg_id_t id, boolean_t value)
677 763 {
678 764 smb_scfhandle_t *handle;
679 765 smb_cfg_param_t *cfg;
680 766 int rc = SMBD_SMF_OK;
681 767
682 768 cfg = smb_config_getent(id);
683 769 assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
684 770
685 771 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
686 772 if (handle == NULL)
687 773 return (SMBD_SMF_SYSTEM_ERR);
688 774
689 775 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
690 776 if (rc == SMBD_SMF_OK)
691 777 rc = smb_smf_start_transaction(handle);
692 778
693 779 if (rc != SMBD_SMF_OK) {
694 780 smb_smf_scf_fini(handle);
695 781 return (rc);
696 782 }
697 783
698 784 rc = smb_smf_set_boolean_property(handle, cfg->sc_name, value);
699 785
700 786 (void) smb_smf_end_transaction(handle);
701 787 smb_smf_scf_fini(handle);
702 788 return (rc);
703 789 }
704 790
705 791 /*
706 792 * smb_config_set
707 793 *
708 794 * This function sets the value of the specified config
709 795 * iterm regardless of its type in string format. This should
710 796 * be used when the config item type is not known by the caller.
711 797 */
712 798 int
713 799 smb_config_set(smb_cfg_id_t id, char *value)
714 800 {
715 801 smb_cfg_param_t *cfg;
716 802 int64_t cint;
717 803
718 804 cfg = smb_config_getent(id);
719 805 switch (cfg->sc_type) {
720 806 case SCF_TYPE_ASTRING:
721 807 return (smb_config_setstr(id, value));
722 808
723 809 case SCF_TYPE_INTEGER:
724 810 cint = atoi(value);
725 811 return (smb_config_setnum(id, cint));
726 812
727 813 case SCF_TYPE_BOOLEAN:
728 814 return (smb_config_setbool(id, strcasecmp(value, "true") == 0));
729 815 }
730 816
731 817 return (SMBD_SMF_INVALID_ARG);
732 818 }
733 819
734 820 int
735 821 smb_config_get_debug()
736 822 {
737 823 int64_t val64;
738 824 int val = 0; /* default */
739 825 smb_scfhandle_t *handle = NULL;
740 826
741 827 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
742 828 if (handle == NULL) {
743 829 return (val);
744 830 }
745 831
746 832 if (smb_smf_create_service_pgroup(handle,
747 833 SMBD_PG_NAME) != SMBD_SMF_OK) {
748 834 smb_smf_scf_fini(handle);
749 835 return (val);
750 836 }
751 837
752 838 if (smb_smf_get_integer_property(handle, "debug", &val64) != 0) {
753 839 smb_smf_scf_fini(handle);
754 840 return (val);
755 841 }
756 842 val = (int)val64;
757 843
758 844 smb_smf_scf_fini(handle);
759 845
760 846 return (val);
761 847 }
762 848
763 849 uint8_t
764 850 smb_config_get_fg_flag()
765 851 {
766 852 uint8_t run_fg = 0; /* Default is to run in daemon mode */
767 853 smb_scfhandle_t *handle = NULL;
768 854
769 855 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
770 856 if (handle == NULL) {
771 857 return (run_fg);
772 858 }
773 859
774 860 if (smb_smf_create_service_pgroup(handle,
775 861 SMBD_PG_NAME) != SMBD_SMF_OK) {
776 862 smb_smf_scf_fini(handle);
777 863 return (run_fg);
778 864 }
779 865
780 866 if (smb_smf_get_boolean_property(handle, "run_fg", &run_fg) != 0) {
781 867 smb_smf_scf_fini(handle);
782 868 return (run_fg);
783 869 }
784 870
785 871 smb_smf_scf_fini(handle);
786 872
787 873 return (run_fg);
788 874 }
789 875
790 876 /*
791 877 * smb_config_get_ads_enable
792 878 *
793 879 * Returns value of the "config/use_ads" parameter
794 880 * from the IDMAP SMF configuration repository.
795 881 *
796 882 */
797 883 boolean_t
798 884 smb_config_get_ads_enable(void)
799 885 {
800 886 smb_scfhandle_t *handle = NULL;
801 887 uint8_t vbool;
802 888 int rc = 0;
803 889
804 890 handle = smb_smf_scf_init(IDMAP_FMRI_PREFIX);
805 891 if (handle == NULL)
806 892 return (B_FALSE);
807 893
808 894 rc = smb_smf_create_service_pgroup(handle, IDMAP_PG_NAME);
809 895 if (rc == SMBD_SMF_OK)
810 896 rc = smb_smf_get_boolean_property(handle, "use_ads", &vbool);
811 897 smb_smf_scf_fini(handle);
812 898
813 899 return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_TRUE);
814 900 }
815 901
816 902 /*
817 903 * smb_config_get_localsid
818 904 *
819 905 * Returns value of the "config/machine_sid" parameter
820 906 * from the IDMAP SMF configuration repository.
821 907 * Result is allocated; caller should free.
822 908 */
823 909 char *
824 910 smb_config_get_localsid(void)
825 911 {
826 912 return (smb_config_getenv_generic(MACHINE_SID, IDMAP_FMRI_PREFIX,
827 913 IDMAP_PG_NAME));
828 914 }
829 915
830 916 /*
831 917 * smb_config_get_localuuid
832 918 *
833 919 * Returns value of the "config/machine_uuid" parameter
834 920 * from the IDMAP SMF configuration repository.
835 921 *
836 922 */
837 923 int
838 924 smb_config_get_localuuid(uuid_t uu)
839 925 {
840 926 char *s;
841 927
842 928 uuid_clear(uu);
843 929 s = smb_config_getenv_generic(MACHINE_UUID, IDMAP_FMRI_PREFIX,
844 930 IDMAP_PG_NAME);
845 931 if (s == NULL)
846 932 return (-1);
847 933
848 934 if (uuid_parse(s, uu) < 0) {
849 935 free(s);
850 936 return (-1);
851 937 }
852 938
853 939 return (0);
854 940 }
855 941
856 942 static int
857 943 smb_config_get_idmap_preferred_dc(char *cbuf, int bufsz)
858 944 {
859 945 char *s;
860 946 int len, rc = -1;
861 947
862 948 s = smb_config_getenv_generic(IDMAP_PREF_DC,
863 949 IDMAP_FMRI_PREFIX, IDMAP_PG_NAME);
864 950 if (s != NULL) {
865 951 len = strlcpy(cbuf, s, bufsz);
866 952 if (len < bufsz)
867 953 rc = 0;
868 954 free(s);
869 955 }
|
↓ open down ↓ |
231 lines elided |
↑ open up ↑ |
870 956 return (rc);
871 957 }
872 958
873 959 static int
874 960 smb_config_set_idmap_preferred_dc(char *value)
875 961 {
876 962 return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME,
877 963 IDMAP_PREF_DC, value));
878 964 }
879 965
966 +static int
967 +smb_config_get_idmap_site_name(char *cbuf, int bufsz)
968 +{
969 + char *s;
970 + int len, rc = -1;
971 +
972 + s = smb_config_getenv_generic(IDMAP_SITE_NAME,
973 + IDMAP_FMRI_PREFIX, IDMAP_PG_NAME);
974 + if (s != NULL) {
975 + len = strlcpy(cbuf, s, bufsz);
976 + if (len < bufsz)
977 + rc = 0;
978 + free(s);
979 + }
980 + return (rc);
981 +}
982 +
983 +static int
984 +smb_config_set_idmap_site_name(char *value)
985 +{
986 + return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME,
987 + IDMAP_SITE_NAME, value));
988 +}
989 +
880 990 /*
881 991 * smb_config_set_idmap_domain
882 992 *
883 993 * Set the "config/domain_name" parameter from IDMAP SMF repository.
884 994 */
885 995 int
886 996 smb_config_set_idmap_domain(char *value)
887 997 {
888 998 return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME,
889 999 IDMAP_DOMAIN, value));
890 1000 }
891 1001
892 1002 /*
893 1003 * smb_config_refresh_idmap
894 1004 *
895 1005 * Refresh IDMAP SMF service after making changes to its configuration.
896 1006 */
897 1007 int
898 1008 smb_config_refresh_idmap(void)
899 1009 {
900 1010 char instance[32];
901 1011
902 1012 (void) snprintf(instance, sizeof (instance), "%s:default",
903 1013 IDMAP_FMRI_PREFIX);
904 1014 return (smf_refresh_instance(instance));
905 1015 }
906 1016
907 1017 int
908 1018 smb_config_secmode_fromstr(char *secmode)
909 1019 {
910 1020 if (secmode == NULL)
911 1021 return (SMB_SECMODE_WORKGRP);
912 1022
913 1023 if (strcasecmp(secmode, SMB_SECMODE_DOMAIN_STR) == 0)
914 1024 return (SMB_SECMODE_DOMAIN);
915 1025
916 1026 return (SMB_SECMODE_WORKGRP);
917 1027 }
918 1028
919 1029 char *
920 1030 smb_config_secmode_tostr(int secmode)
921 1031 {
922 1032 if (secmode == SMB_SECMODE_DOMAIN)
923 1033 return (SMB_SECMODE_DOMAIN_STR);
924 1034
925 1035 return (SMB_SECMODE_WORKGRP_STR);
926 1036 }
927 1037
928 1038 int
929 1039 smb_config_get_secmode()
930 1040 {
931 1041 char p[16];
932 1042
933 1043 (void) smb_config_getstr(SMB_CI_SECURITY, p, sizeof (p));
934 1044 return (smb_config_secmode_fromstr(p));
935 1045 }
936 1046
937 1047 int
938 1048 smb_config_set_secmode(int secmode)
939 1049 {
940 1050 char *p;
941 1051
942 1052 p = smb_config_secmode_tostr(secmode);
943 1053 return (smb_config_setstr(SMB_CI_SECURITY, p));
944 1054 }
945 1055
946 1056 void
947 1057 smb_config_getdomaininfo(char *domain, char *fqdn, char *sid, char *forest,
948 1058 char *guid)
949 1059 {
950 1060 if (domain)
951 1061 (void) smb_config_getstr(SMB_CI_DOMAIN_NAME, domain,
952 1062 NETBIOS_NAME_SZ);
953 1063
954 1064 if (fqdn)
955 1065 (void) smb_config_getstr(SMB_CI_DOMAIN_FQDN, fqdn,
956 1066 MAXHOSTNAMELEN);
957 1067
958 1068 if (sid)
959 1069 (void) smb_config_getstr(SMB_CI_DOMAIN_SID, sid,
960 1070 SMB_SID_STRSZ);
961 1071
962 1072 if (forest)
963 1073 (void) smb_config_getstr(SMB_CI_DOMAIN_FOREST, forest,
964 1074 MAXHOSTNAMELEN);
965 1075
966 1076 if (guid)
967 1077 (void) smb_config_getstr(SMB_CI_DOMAIN_GUID, guid,
968 1078 UUID_PRINTABLE_STRING_LENGTH);
969 1079 }
970 1080
971 1081 void
972 1082 smb_config_setdomaininfo(char *domain, char *fqdn, char *sid, char *forest,
973 1083 char *guid)
974 1084 {
975 1085 if (domain)
976 1086 (void) smb_config_setstr(SMB_CI_DOMAIN_NAME, domain);
977 1087 if (fqdn)
978 1088 (void) smb_config_setstr(SMB_CI_DOMAIN_FQDN, fqdn);
979 1089 if (sid)
980 1090 (void) smb_config_setstr(SMB_CI_DOMAIN_SID, sid);
981 1091 if (forest)
982 1092 (void) smb_config_setstr(SMB_CI_DOMAIN_FOREST, forest);
983 1093 if (guid)
984 1094 (void) smb_config_setstr(SMB_CI_DOMAIN_GUID, guid);
985 1095 }
986 1096
987 1097 /*
988 1098 * The version stored in SMF in string format as N.N where
989 1099 * N is a number defined by Microsoft. The first number represents
990 1100 * the major version and the second number is the minor version.
991 1101 * Current defined values can be found here in 'ver_table'.
992 1102 *
993 1103 * This function reads the SMF string value and converts it to
994 1104 * two numbers returned in the given 'version' structure.
995 1105 * Current default version number is 5.0 which is for Windows 2000.
996 1106 */
997 1107 void
998 1108 smb_config_get_version(smb_version_t *version)
999 1109 {
1000 1110 smb_version_t tmpver;
1001 1111 char verstr[SMB_VERSTR_LEN];
1002 1112 char *p;
1003 1113 int rc, i;
1004 1114 static smb_version_t ver_table [] = {
1005 1115 { 0, SMB_MAJOR_NT, SMB_MINOR_NT, 1381, 0 },
1006 1116 { 0, SMB_MAJOR_2000, SMB_MINOR_2000, 2195, 0 },
1007 1117 { 0, SMB_MAJOR_XP, SMB_MINOR_XP, 2196, 0 },
1008 1118 { 0, SMB_MAJOR_2003, SMB_MINOR_2003, 2196, 0 },
1009 1119 { 0, SMB_MAJOR_VISTA, SMB_MINOR_VISTA, 6000, 0 },
1010 1120 { 0, SMB_MAJOR_2008, SMB_MINOR_2008, 6000, 0 },
1011 1121 { 0, SMB_MAJOR_2008R2, SMB_MINOR_2008R2, 7007, 0 },
1012 1122 { 0, SMB_MAJOR_7, SMB_MINOR_7, 7007, 0 }
1013 1123 };
1014 1124
1015 1125 *version = ver_table[1];
1016 1126 version->sv_size = sizeof (smb_version_t);
1017 1127
1018 1128 rc = smb_config_getstr(SMB_CI_VERSION, verstr, sizeof (verstr));
1019 1129 if (rc != SMBD_SMF_OK)
1020 1130 return;
1021 1131
1022 1132 if ((p = strchr(verstr, '.')) == NULL)
1023 1133 return;
1024 1134
1025 1135 *p = '\0';
1026 1136 tmpver.sv_major = (uint8_t)atoi(verstr);
1027 1137 tmpver.sv_minor = (uint8_t)atoi(p + 1);
1028 1138
1029 1139 for (i = 0; i < sizeof (ver_table)/sizeof (ver_table[0]); ++i) {
1030 1140 if ((tmpver.sv_major == ver_table[i].sv_major) &&
1031 1141 (tmpver.sv_minor == ver_table[i].sv_minor)) {
1032 1142 *version = ver_table[i];
1033 1143 version->sv_size = sizeof (smb_version_t);
1034 1144 break;
1035 1145 }
1036 1146 }
1037 1147 }
1038 1148
1039 1149 /*
1040 1150 * Reads share exec script properties
1041 1151 */
1042 1152 uint32_t
1043 1153 smb_config_get_execinfo(char *map, char *unmap, size_t bufsz)
1044 1154 {
1045 1155 char buf[MAXPATHLEN];
1046 1156 uint32_t flags = 0;
1047 1157
1048 1158 if (map == NULL) {
1049 1159 map = buf;
1050 1160 bufsz = MAXPATHLEN;
1051 1161 }
1052 1162
1053 1163 *map = '\0';
1054 1164 (void) smb_config_getstr(SMB_CI_MAP, map, bufsz);
1055 1165 if (*map != '\0')
1056 1166 flags |= SMB_EXEC_MAP;
1057 1167
1058 1168 if (unmap == NULL) {
1059 1169 unmap = buf;
1060 1170 bufsz = MAXPATHLEN;
1061 1171 }
1062 1172
1063 1173 *unmap = '\0';
1064 1174 (void) smb_config_getstr(SMB_CI_UNMAP, unmap, bufsz);
1065 1175 if (*unmap != '\0')
1066 1176 flags |= SMB_EXEC_UNMAP;
1067 1177
1068 1178 *buf = '\0';
1069 1179 (void) smb_config_getstr(SMB_CI_DISPOSITION, buf, sizeof (buf));
1070 1180 if (*buf != '\0')
1071 1181 if (strcasecmp(buf, SMB_EXEC_DISP_TERMINATE) == 0)
1072 1182 flags |= SMB_EXEC_TERM;
1073 1183
1074 1184 return (flags);
1075 1185 }
1076 1186
1077 1187 static smb_cfg_param_t *
1078 1188 smb_config_getent(smb_cfg_id_t id)
1079 1189 {
|
↓ open down ↓ |
190 lines elided |
↑ open up ↑ |
1080 1190 int i;
1081 1191
1082 1192 for (i = 0; i < SMB_CI_MAX; i++)
1083 1193 if (smb_cfg_table[i].sc_id == id)
1084 1194 return (&smb_cfg_table[id]);
1085 1195
1086 1196 assert(0);
1087 1197 return (NULL);
1088 1198 }
1089 1199
1200 +static uint32_t
1201 +smb_config_get_protocol(smb_cfg_id_t id, char *name, uint32_t default_val)
1202 +{
1203 + char str[SMB_VERSTR_LEN];
1204 + int rc;
1205 + uint32_t val;
1090 1206
1207 + rc = smb_config_getstr(id, str, sizeof (str));
1208 + if (rc == SMBD_SMF_OK) {
1209 + val = smb_convert_version_str(str);
1210 + if (val != 0)
1211 + return (val);
1212 + if (str[0] != '\0') {
1213 + syslog(LOG_ERR, "smbd/%s value invalid: %s", name, str);
1214 + }
1215 + }
1216 +
1217 + return (default_val);
1218 +}
1219 +
1091 1220 /*
1092 - * We store the max SMB protocol version in SMF as a string,
1093 - * (for convenience of svccfg etc) but the programmatic get/set
1094 - * interfaces use the numeric form.
1095 - *
1096 - * The numeric values are as defined in the [MS-SMB2] spec.
1097 - * except for how we represent "1" (for SMB1) which is an
1098 - * arbitrary value below SMB2_VERS_BASE.
1221 + * The service manifest has empty values by default for min_protocol and
1222 + * max_protocol. The expectation is that when those values are empty, we don't
1223 + * constrain the range of supported protocol versions (and allow use of the
1224 + * whole range that we implement). For that reason, this should usually be the
1225 + * highest protocol version we implement.
1099 1226 */
1100 -static struct str_val
1101 -smb_versions[] = {
1102 - { "3.0", SMB_VERS_3_0 },
1103 - { "2.1", SMB_VERS_2_1 },
1104 - { "2.002", SMB_VERS_2_002 },
1105 - { "1", SMB_VERS_1 },
1106 - { NULL, 0 }
1107 -};
1227 +uint32_t max_protocol_default = SMB_VERS_3_02;
1108 1228
1229 +uint32_t
1230 +smb_config_get_max_protocol(void)
1231 +{
1232 + uint32_t max;
1233 +
1234 + max = smb_config_get_protocol(SMB_CI_MAX_PROTOCOL, "max_protocol",
1235 + max_protocol_default);
1236 +
1237 + return (max);
1238 +}
1239 +
1109 1240 /*
1110 - * This really should be the latest (SMB_VERS_3_0)
1111 - * but we're being cautious with SMB3 for a while.
1241 + * This should eventually be SMB_VERS_2_BASE
1112 1242 */
1113 -uint32_t max_protocol_default = SMB_VERS_2_1;
1243 +uint32_t min_protocol_default = SMB_VERS_1;
1114 1244
1115 1245 uint32_t
1116 -smb_config_get_max_protocol(void)
1246 +smb_config_get_min_protocol(void)
1117 1247 {
1118 - char str[SMB_VERSTR_LEN];
1119 - int i, rc;
1248 + uint32_t min;
1120 1249
1121 - rc = smb_config_getstr(SMB_CI_MAX_PROTOCOL, str, sizeof (str));
1122 - if (rc == SMBD_SMF_OK) {
1123 - for (i = 0; smb_versions[i].str != NULL; i++) {
1124 - if (strcmp(str, smb_versions[i].str) == 0)
1125 - return (smb_versions[i].val);
1126 - }
1127 - if (str[0] != '\0') {
1128 - syslog(LOG_ERR, "smbd/max_protocol value invalid");
1129 - }
1130 - }
1250 + min = smb_config_get_protocol(SMB_CI_MIN_PROTOCOL, "min_protocol",
1251 + min_protocol_default);
1131 1252
1132 - return (max_protocol_default);
1253 + return (min);
1133 1254 }
1134 1255
1135 1256 int
1136 1257 smb_config_check_protocol(char *value)
1137 1258 {
1138 - int i;
1259 + if (smb_convert_version_str(value) != 0)
1260 + return (0);
1139 1261
1140 - for (i = 0; smb_versions[i].str != NULL; i++) {
1141 - if (strcmp(value, smb_versions[i].str) == 0)
1142 - return (0);
1143 - }
1144 -
1145 1262 return (-1);
1146 1263 }
1147 1264
1148 1265 /*
1149 1266 * If smb2_enable is present and max_protocol is empty,
1150 1267 * set max_protocol. Delete smb2_enable.
1151 1268 */
1152 1269 static void
1153 1270 upgrade_smb2_enable()
1154 1271 {
1155 1272 smb_scfhandle_t *handle;
1156 1273 char *s2e_name = "smb2_enable";
1157 1274 char *s2e_sval;
1158 1275 uint8_t s2e_bval;
1159 1276 char *maxp_name = "max_protocol";
1160 1277 char *maxp_sval;
1161 1278 char verstr[SMB_VERSTR_LEN];
1162 1279 int rc;
1163 1280
1164 1281 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
1165 1282 if (handle == NULL)
1166 1283 return;
1167 1284 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
1168 1285 if (rc != SMBD_SMF_OK)
1169 1286 goto out;
1170 1287
1171 1288 /* Is there an "smb2_enable" property? */
1172 1289 rc = smb_smf_get_boolean_property(handle, s2e_name, &s2e_bval);
1173 1290 if (rc != SMBD_SMF_OK) {
1174 1291 syslog(LOG_DEBUG, "upgrade: smb2_enable not found");
1175 1292 goto out;
1176 1293 }
1177 1294
1178 1295 /*
1179 1296 * We will try to delete the smb2_enable property, so we need
1180 1297 * the transaction to start now, before we modify max_protocol
1181 1298 */
1182 1299 if ((rc = smb_smf_start_transaction(handle)) != 0) {
1183 1300 syslog(LOG_DEBUG, "upgrade_smb2_enable: start trans (%d)", rc);
1184 1301 goto out;
1185 1302 }
1186 1303
1187 1304 /*
1188 1305 * Old (smb2_enable) property exists.
1189 1306 * Does the new one? (max_protocol)
1190 1307 */
1191 1308 rc = smb_smf_get_string_property(handle, maxp_name,
1192 1309 verstr, sizeof (verstr));
1193 1310 if (rc == SMBD_SMF_OK && !smb_config_check_protocol(verstr)) {
1194 1311 syslog(LOG_DEBUG, "upgrade: found %s = %s",
1195 1312 maxp_name, verstr);
1196 1313 /* Leave existing max_protocol as we found it. */
1197 1314 } else {
1198 1315 /*
1199 1316 * New property missing or invalid.
1200 1317 * Upgrade from "smb2_enable".
1201 1318 */
1202 1319 if (s2e_bval == 0) {
1203 1320 s2e_sval = "false";
1204 1321 maxp_sval = "1";
1205 1322 } else {
1206 1323 s2e_sval = "true";
1207 1324 maxp_sval = "2.1";
1208 1325 }
1209 1326 /*
1210 1327 * Note: Need this in the same transaction as the
1211 1328 * delete of smb2_enable below.
1212 1329 */
1213 1330 rc = smb_smf_set_string_property(handle, maxp_name, maxp_sval);
1214 1331 if (rc != SMBD_SMF_OK) {
1215 1332 syslog(LOG_ERR, "failed to set smbd/%d (%d)",
1216 1333 maxp_name, rc);
1217 1334 goto out;
1218 1335 }
1219 1336 syslog(LOG_INFO, "upgrade smbd/smb2_enable=%s "
1220 1337 "converted to smbd/max_protocol=%s",
1221 1338 s2e_sval, maxp_sval);
1222 1339 }
1223 1340
1224 1341 /*
1225 1342 * Delete the old smb2_enable property.
1226 1343 */
1227 1344 if ((rc = smb_smf_delete_property(handle, s2e_name)) != 0) {
1228 1345 syslog(LOG_DEBUG, "upgrade_smb2_enable: delete prop (%d)", rc);
1229 1346 } else if ((rc = smb_smf_end_transaction(handle)) != 0) {
1230 1347 syslog(LOG_DEBUG, "upgrade_smb2_enable: end trans (%d)", rc);
1231 1348 }
1232 1349 if (rc != 0) {
1233 1350 syslog(LOG_ERR, "failed to delete property smbd/%d (%d)",
1234 1351 s2e_name, rc);
1235 1352 }
1236 1353
1237 1354 out:
1238 1355 (void) smb_smf_end_transaction(handle);
1239 1356 smb_smf_scf_fini(handle);
|
↓ open down ↓ |
85 lines elided |
↑ open up ↑ |
1240 1357 }
1241 1358
1242 1359
1243 1360 /*
1244 1361 * Run once at startup convert old SMF settings to current.
1245 1362 */
1246 1363 void
1247 1364 smb_config_upgrade(void)
1248 1365 {
1249 1366 upgrade_smb2_enable();
1367 +}
1368 +
1369 +smb_cfg_val_t
1370 +smb_config_get_require(smb_cfg_id_t id)
1371 +{
1372 + int rc;
1373 + char str[sizeof ("required")];
1374 +
1375 + rc = smb_config_getstr(id, str, sizeof (str));
1376 + if (rc != SMBD_SMF_OK)
1377 + return (SMB_CONFIG_DISABLED);
1378 +
1379 + if (strncmp(str, "required", sizeof (str)) == 0)
1380 + return (SMB_CONFIG_REQUIRED);
1381 + if (strncmp(str, "enabled", sizeof (str)) == 0)
1382 + return (SMB_CONFIG_ENABLED);
1383 +
1384 + return (SMB_CONFIG_DISABLED);
1250 1385 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX