1 /* 2 * CDDL HEADER START 3 * 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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 /* 27 * CIFS configuration management library 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <synch.h> 34 #include <string.h> 35 #include <strings.h> 36 #include <syslog.h> 37 #include <netdb.h> 38 #include <ctype.h> 39 #include <sys/types.h> 40 #include <libscf.h> 41 #include <assert.h> 42 #include <uuid/uuid.h> 43 #include <smbsrv/libsmb.h> 44 45 typedef struct smb_cfg_param { 46 smb_cfg_id_t sc_id; 47 char *sc_name; 48 int sc_type; 49 uint32_t sc_flags; 50 } smb_cfg_param_t; 51 52 struct str_val { 53 char *str; 54 uint32_t val; 55 }; 56 57 /* 58 * config parameter flags 59 */ 60 #define SMB_CF_PROTECTED 0x01 61 #define SMB_CF_EXEC 0x02 62 63 /* idmap SMF fmri and Property Group */ 64 #define IDMAP_FMRI_PREFIX "system/idmap" 65 #define MACHINE_SID "machine_sid" 66 #define MACHINE_UUID "machine_uuid" 67 #define IDMAP_DOMAIN "domain_name" 68 #define IDMAP_PREF_DC "preferred_dc" 69 #define IDMAP_SITE_NAME "site_name" 70 #define IDMAP_PG_NAME "config" 71 72 #define SMB_SECMODE_WORKGRP_STR "workgroup" 73 #define SMB_SECMODE_DOMAIN_STR "domain" 74 75 #define SMB_ENC_LEN 1024 76 #define SMB_DEC_LEN 256 77 78 static char *b64_data = 79 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 80 81 static smb_cfg_param_t smb_cfg_table[] = 82 { 83 {SMB_CI_VERSION, "sv_version", SCF_TYPE_ASTRING, 0}, 84 85 /* Oplock configuration, Kernel Only */ 86 {SMB_CI_OPLOCK_ENABLE, "oplock_enable", SCF_TYPE_BOOLEAN, 0}, 87 88 /* Autohome configuration */ 89 {SMB_CI_AUTOHOME_MAP, "autohome_map", SCF_TYPE_ASTRING, 0}, 90 91 /* Domain/PDC configuration */ 92 {SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0}, 93 {SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0}, 94 {SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0}, 95 {SMB_CI_DOMAIN_FQDN, "fqdn", SCF_TYPE_ASTRING, 0}, 96 {SMB_CI_DOMAIN_FOREST, "forest", SCF_TYPE_ASTRING, 0}, 97 {SMB_CI_DOMAIN_GUID, "domain_guid", SCF_TYPE_ASTRING, 0}, 98 {SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0}, 99 100 /* WINS configuration */ 101 {SMB_CI_WINS_SRV1, "wins_server_1", SCF_TYPE_ASTRING, 0}, 102 {SMB_CI_WINS_SRV2, "wins_server_2", SCF_TYPE_ASTRING, 0}, 103 {SMB_CI_WINS_EXCL, "wins_exclude", SCF_TYPE_ASTRING, 0}, 104 105 /* Kmod specific configuration */ 106 {SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0}, 107 {SMB_CI_MAX_CONNECTIONS, "max_connections", SCF_TYPE_INTEGER, 0}, 108 {SMB_CI_KEEPALIVE, "keep_alive", SCF_TYPE_INTEGER, 0}, 109 {SMB_CI_RESTRICT_ANON, "restrict_anonymous", SCF_TYPE_BOOLEAN, 0}, 110 111 {SMB_CI_SIGNING_ENABLE, "signing_enabled", SCF_TYPE_BOOLEAN, 0}, 112 {SMB_CI_SIGNING_REQD, "signing_required", SCF_TYPE_BOOLEAN, 0}, 113 114 /* Kmod tuning configuration */ 115 {SMB_CI_SYNC_ENABLE, "sync_enable", SCF_TYPE_BOOLEAN, 0}, 116 117 /* SMBd configuration */ 118 {SMB_CI_SECURITY, "security", SCF_TYPE_ASTRING, 0}, 119 {SMB_CI_NETBIOS_ENABLE, "netbios_enable", SCF_TYPE_BOOLEAN, 0}, 120 {SMB_CI_NBSCOPE, "netbios_scope", SCF_TYPE_ASTRING, 0}, 121 {SMB_CI_SYS_CMNT, "system_comment", SCF_TYPE_ASTRING, 0}, 122 {SMB_CI_LM_LEVEL, "lmauth_level", SCF_TYPE_INTEGER, 0}, 123 124 /* ADS Configuration */ 125 {SMB_CI_ADS_SITE, "ads_site", SCF_TYPE_ASTRING, 0}, 126 127 /* Dynamic DNS */ 128 {SMB_CI_DYNDNS_ENABLE, "ddns_enable", SCF_TYPE_BOOLEAN, 0}, 129 130 {SMB_CI_MACHINE_PASSWD, "machine_passwd", SCF_TYPE_ASTRING, 131 SMB_CF_PROTECTED}, 132 133 {SMB_CI_MACHINE_UUID, "machine_uuid", SCF_TYPE_ASTRING, 0}, 134 {SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING, 0}, 135 {SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING, 0}, 136 {SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER, 0}, 137 {SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER, 0}, 138 {SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0}, 139 {SMB_CI_PRINT_ENABLE, "print_enable", SCF_TYPE_BOOLEAN, 0}, 140 {SMB_CI_MAP, "map", SCF_TYPE_ASTRING, SMB_CF_EXEC}, 141 {SMB_CI_UNMAP, "unmap", SCF_TYPE_ASTRING, SMB_CF_EXEC}, 142 {SMB_CI_DISPOSITION, "disposition", SCF_TYPE_ASTRING, SMB_CF_EXEC}, 143 {SMB_CI_DFS_STDROOT_NUM, "dfs_stdroot_num", SCF_TYPE_INTEGER, 0}, 144 {SMB_CI_TRAVERSE_MOUNTS, "traverse_mounts", SCF_TYPE_BOOLEAN, 0}, 145 {SMB_CI_SMB2_ENABLE_OLD, "smb2_enable", SCF_TYPE_BOOLEAN, 0}, 146 {SMB_CI_INITIAL_CREDITS, "initial_credits", SCF_TYPE_INTEGER, 0}, 147 {SMB_CI_MAXIMUM_CREDITS, "maximum_credits", SCF_TYPE_INTEGER, 0}, 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}, 153 154 /* SMB_CI_MAX */ 155 }; 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 176 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t); 177 178 static boolean_t smb_is_base64(unsigned char c); 179 static char *smb_base64_encode(char *str_to_encode); 180 static char *smb_base64_decode(char *encoded_str); 181 static int smb_config_get_idmap_preferred_dc(char *, int); 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 *); 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 200 char * 201 smb_config_getname(smb_cfg_id_t id) 202 { 203 smb_cfg_param_t *cfg; 204 cfg = smb_config_getent(id); 205 return (cfg->sc_name); 206 } 207 208 static boolean_t 209 smb_is_base64(unsigned char c) 210 { 211 return (isalnum(c) || (c == '+') || (c == '/')); 212 } 213 214 /* 215 * smb_base64_encode 216 * 217 * Encode a string using base64 algorithm. 218 * Caller should free the returned buffer when done. 219 */ 220 static char * 221 smb_base64_encode(char *str_to_encode) 222 { 223 int ret_cnt = 0; 224 int i = 0, j = 0; 225 char arr_3[3], arr_4[4]; 226 int len = strlen(str_to_encode); 227 char *ret = malloc(SMB_ENC_LEN); 228 229 if (ret == NULL) { 230 return (NULL); 231 } 232 233 while (len--) { 234 arr_3[i++] = *(str_to_encode++); 235 if (i == 3) { 236 arr_4[0] = (arr_3[0] & 0xfc) >> 2; 237 arr_4[1] = ((arr_3[0] & 0x03) << 4) + 238 ((arr_3[1] & 0xf0) >> 4); 239 arr_4[2] = ((arr_3[1] & 0x0f) << 2) + 240 ((arr_3[2] & 0xc0) >> 6); 241 arr_4[3] = arr_3[2] & 0x3f; 242 243 for (i = 0; i < 4; i++) 244 ret[ret_cnt++] = b64_data[arr_4[i]]; 245 i = 0; 246 } 247 } 248 249 if (i) { 250 for (j = i; j < 3; j++) 251 arr_3[j] = '\0'; 252 253 arr_4[0] = (arr_3[0] & 0xfc) >> 2; 254 arr_4[1] = ((arr_3[0] & 0x03) << 4) + 255 ((arr_3[1] & 0xf0) >> 4); 256 arr_4[2] = ((arr_3[1] & 0x0f) << 2) + 257 ((arr_3[2] & 0xc0) >> 6); 258 arr_4[3] = arr_3[2] & 0x3f; 259 260 for (j = 0; j < (i + 1); j++) 261 ret[ret_cnt++] = b64_data[arr_4[j]]; 262 263 while (i++ < 3) 264 ret[ret_cnt++] = '='; 265 } 266 267 ret[ret_cnt++] = '\0'; 268 return (ret); 269 } 270 271 /* 272 * smb_base64_decode 273 * 274 * Decode using base64 algorithm. 275 * Caller should free the returned buffer when done. 276 */ 277 static char * 278 smb_base64_decode(char *encoded_str) 279 { 280 int len = strlen(encoded_str); 281 int i = 0, j = 0; 282 int en_ind = 0; 283 char arr_4[4], arr_3[3]; 284 int ret_cnt = 0; 285 char *ret = malloc(SMB_DEC_LEN); 286 char *p; 287 288 if (ret == NULL) { 289 return (NULL); 290 } 291 292 while (len-- && (encoded_str[en_ind] != '=') && 293 smb_is_base64(encoded_str[en_ind])) { 294 arr_4[i++] = encoded_str[en_ind]; 295 en_ind++; 296 if (i == 4) { 297 for (i = 0; i < 4; i++) { 298 if ((p = strchr(b64_data, arr_4[i])) == NULL) 299 return (NULL); 300 301 arr_4[i] = (int)(p - b64_data); 302 } 303 304 arr_3[0] = (arr_4[0] << 2) + 305 ((arr_4[1] & 0x30) >> 4); 306 arr_3[1] = ((arr_4[1] & 0xf) << 4) + 307 ((arr_4[2] & 0x3c) >> 2); 308 arr_3[2] = ((arr_4[2] & 0x3) << 6) + 309 arr_4[3]; 310 311 for (i = 0; i < 3; i++) 312 ret[ret_cnt++] = arr_3[i]; 313 314 i = 0; 315 } 316 } 317 318 if (i) { 319 for (j = i; j < 4; j++) 320 arr_4[j] = 0; 321 322 for (j = 0; j < 4; j++) { 323 if ((p = strchr(b64_data, arr_4[j])) == NULL) 324 return (NULL); 325 326 arr_4[j] = (int)(p - b64_data); 327 } 328 arr_3[0] = (arr_4[0] << 2) + 329 ((arr_4[1] & 0x30) >> 4); 330 arr_3[1] = ((arr_4[1] & 0xf) << 4) + 331 ((arr_4[2] & 0x3c) >> 2); 332 arr_3[2] = ((arr_4[2] & 0x3) << 6) + 333 arr_4[3]; 334 for (j = 0; j < (i - 1); j++) 335 ret[ret_cnt++] = arr_3[j]; 336 } 337 338 ret[ret_cnt++] = '\0'; 339 return (ret); 340 } 341 342 static char * 343 smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp) 344 { 345 smb_scfhandle_t *handle; 346 char *value; 347 348 if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL) 349 return (NULL); 350 351 handle = smb_smf_scf_init(svc_fmri_prefix); 352 if (handle == NULL) { 353 free(value); 354 return (NULL); 355 } 356 357 (void) smb_smf_create_service_pgroup(handle, svc_propgrp); 358 359 if (smb_smf_get_string_property(handle, name, value, 360 sizeof (char) * MAX_VALUE_BUFLEN) != 0) { 361 smb_smf_scf_fini(handle); 362 free(value); 363 return (NULL); 364 } 365 366 smb_smf_scf_fini(handle); 367 return (value); 368 369 } 370 371 static int 372 smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp, 373 char *name, char *value) 374 { 375 smb_scfhandle_t *handle = NULL; 376 int rc = 0; 377 378 379 handle = smb_smf_scf_init(svc_fmri_prefix); 380 if (handle == NULL) { 381 return (1); 382 } 383 384 (void) smb_smf_create_service_pgroup(handle, svc_propgrp); 385 386 if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) { 387 smb_smf_scf_fini(handle); 388 return (1); 389 } 390 391 if (smb_smf_set_string_property(handle, name, value) != SMBD_SMF_OK) 392 rc = 1; 393 394 if (smb_smf_end_transaction(handle) != SMBD_SMF_OK) 395 rc = 1; 396 397 smb_smf_scf_fini(handle); 398 return (rc); 399 } 400 401 /* 402 * smb_config_getstr 403 * 404 * Fetch the specified string configuration item from SMF 405 */ 406 int 407 smb_config_getstr(smb_cfg_id_t id, char *cbuf, int bufsz) 408 { 409 smb_scfhandle_t *handle; 410 smb_cfg_param_t *cfg; 411 int rc = SMBD_SMF_OK; 412 char *pg; 413 char protbuf[SMB_ENC_LEN]; 414 char *tmp; 415 416 *cbuf = '\0'; 417 cfg = smb_config_getent(id); 418 assert(cfg->sc_type == SCF_TYPE_ASTRING); 419 420 if (id == SMB_CI_ADS_SITE) 421 return (smb_config_get_idmap_site_name(cbuf, bufsz)); 422 if (id == SMB_CI_DOMAIN_SRV) 423 return (smb_config_get_idmap_preferred_dc(cbuf, bufsz)); 424 425 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 426 if (handle == NULL) 427 return (SMBD_SMF_SYSTEM_ERR); 428 429 if (cfg->sc_flags & SMB_CF_PROTECTED) { 430 if ((rc = smb_smf_create_service_pgroup(handle, 431 SMBD_PROTECTED_PG_NAME)) != SMBD_SMF_OK) 432 goto error; 433 434 if ((rc = smb_smf_get_string_property(handle, cfg->sc_name, 435 protbuf, sizeof (protbuf))) != SMBD_SMF_OK) 436 goto error; 437 438 if (*protbuf != '\0') { 439 tmp = smb_base64_decode(protbuf); 440 (void) strlcpy(cbuf, tmp, bufsz); 441 free(tmp); 442 } 443 } else { 444 pg = (cfg->sc_flags & SMB_CF_EXEC) ? SMBD_EXEC_PG_NAME : 445 SMBD_PG_NAME; 446 rc = smb_smf_create_service_pgroup(handle, pg); 447 if (rc == SMBD_SMF_OK) 448 rc = smb_smf_get_string_property(handle, cfg->sc_name, 449 cbuf, bufsz); 450 } 451 452 error: 453 smb_smf_scf_fini(handle); 454 return (rc); 455 } 456 457 /* 458 * Translate the value of an astring SMF property into a binary 459 * IP address. If the value is neither a valid IPv4 nor IPv6 460 * address, attempt to look it up as a hostname using the 461 * configured address type. 462 */ 463 int 464 smb_config_getip(smb_cfg_id_t sc_id, smb_inaddr_t *ipaddr) 465 { 466 int rc, error; 467 int a_family; 468 char ipstr[MAXHOSTNAMELEN]; 469 struct hostent *h; 470 smb_cfg_param_t *cfg; 471 472 if (ipaddr == NULL) 473 return (SMBD_SMF_INVALID_ARG); 474 475 bzero(ipaddr, sizeof (smb_inaddr_t)); 476 rc = smb_config_getstr(sc_id, ipstr, sizeof (ipstr)); 477 if (rc == SMBD_SMF_OK) { 478 if (*ipstr == '\0') 479 return (SMBD_SMF_INVALID_ARG); 480 481 if (inet_pton(AF_INET, ipstr, &ipaddr->a_ipv4) == 1) { 482 ipaddr->a_family = AF_INET; 483 return (SMBD_SMF_OK); 484 } 485 486 if (inet_pton(AF_INET6, ipstr, &ipaddr->a_ipv6) == 1) { 487 ipaddr->a_family = AF_INET6; 488 return (SMBD_SMF_OK); 489 } 490 491 /* 492 * The value is neither an IPv4 nor IPv6 address; 493 * so check if it's a hostname. 494 */ 495 a_family = smb_config_getbool(SMB_CI_IPV6_ENABLE) ? 496 AF_INET6 : AF_INET; 497 h = getipnodebyname(ipstr, a_family, AI_DEFAULT, 498 &error); 499 if (h != NULL) { 500 bcopy(*(h->h_addr_list), &ipaddr->a_ip, 501 h->h_length); 502 ipaddr->a_family = a_family; 503 freehostent(h); 504 rc = SMBD_SMF_OK; 505 } else { 506 cfg = smb_config_getent(sc_id); 507 syslog(LOG_ERR, "smbd/%s: %s unable to get %s " 508 "address: %d", cfg->sc_name, ipstr, 509 a_family == AF_INET ? "IPv4" : "IPv6", error); 510 rc = SMBD_SMF_INVALID_ARG; 511 } 512 } 513 514 return (rc); 515 } 516 517 /* 518 * smb_config_getnum 519 * 520 * Returns the value of a numeric config param. 521 */ 522 int 523 smb_config_getnum(smb_cfg_id_t id, int64_t *cint) 524 { 525 smb_scfhandle_t *handle; 526 smb_cfg_param_t *cfg; 527 int rc = SMBD_SMF_OK; 528 529 *cint = 0; 530 cfg = smb_config_getent(id); 531 assert(cfg->sc_type == SCF_TYPE_INTEGER); 532 533 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 534 if (handle == NULL) 535 return (SMBD_SMF_SYSTEM_ERR); 536 537 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 538 if (rc == SMBD_SMF_OK) 539 rc = smb_smf_get_integer_property(handle, cfg->sc_name, cint); 540 smb_smf_scf_fini(handle); 541 542 return (rc); 543 } 544 545 /* 546 * smb_config_getbool 547 * 548 * Returns the value of a boolean config param. 549 */ 550 boolean_t 551 smb_config_getbool(smb_cfg_id_t id) 552 { 553 smb_scfhandle_t *handle; 554 smb_cfg_param_t *cfg; 555 int rc = SMBD_SMF_OK; 556 uint8_t vbool; 557 558 cfg = smb_config_getent(id); 559 assert(cfg->sc_type == SCF_TYPE_BOOLEAN); 560 561 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 562 if (handle == NULL) 563 return (B_FALSE); 564 565 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 566 if (rc == SMBD_SMF_OK) 567 rc = smb_smf_get_boolean_property(handle, cfg->sc_name, &vbool); 568 smb_smf_scf_fini(handle); 569 570 return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE); 571 } 572 573 /* 574 * smb_config_get 575 * 576 * This function returns the value of the requested config 577 * iterm regardless of its type in string format. This should 578 * be used when the config item type is not known by the caller. 579 */ 580 int 581 smb_config_get(smb_cfg_id_t id, char *cbuf, int bufsz) 582 { 583 smb_cfg_param_t *cfg; 584 int64_t cint; 585 int rc; 586 587 cfg = smb_config_getent(id); 588 switch (cfg->sc_type) { 589 case SCF_TYPE_ASTRING: 590 return (smb_config_getstr(id, cbuf, bufsz)); 591 592 case SCF_TYPE_INTEGER: 593 rc = smb_config_getnum(id, &cint); 594 if (rc == SMBD_SMF_OK) 595 (void) snprintf(cbuf, bufsz, "%lld", cint); 596 return (rc); 597 598 case SCF_TYPE_BOOLEAN: 599 if (smb_config_getbool(id)) 600 (void) strlcpy(cbuf, "true", bufsz); 601 else 602 (void) strlcpy(cbuf, "false", bufsz); 603 return (SMBD_SMF_OK); 604 } 605 606 return (SMBD_SMF_INVALID_ARG); 607 } 608 609 /* 610 * smb_config_setstr 611 * 612 * Set the specified config param with the given 613 * value. 614 */ 615 int 616 smb_config_setstr(smb_cfg_id_t id, char *value) 617 { 618 smb_scfhandle_t *handle; 619 smb_cfg_param_t *cfg; 620 int rc = SMBD_SMF_OK; 621 boolean_t protected; 622 char *tmp = NULL; 623 char *pg; 624 625 cfg = smb_config_getent(id); 626 assert(cfg->sc_type == SCF_TYPE_ASTRING); 627 628 if (id == SMB_CI_ADS_SITE) 629 return (smb_config_set_idmap_site_name(value)); 630 if (id == SMB_CI_DOMAIN_SRV) 631 return (smb_config_set_idmap_preferred_dc(value)); 632 633 protected = B_FALSE; 634 635 switch (cfg->sc_flags) { 636 case SMB_CF_PROTECTED: 637 protected = B_TRUE; 638 pg = SMBD_PROTECTED_PG_NAME; 639 break; 640 case SMB_CF_EXEC: 641 pg = SMBD_EXEC_PG_NAME; 642 break; 643 default: 644 pg = SMBD_PG_NAME; 645 break; 646 } 647 648 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 649 if (handle == NULL) 650 return (SMBD_SMF_SYSTEM_ERR); 651 652 rc = smb_smf_create_service_pgroup(handle, pg); 653 if (rc == SMBD_SMF_OK) 654 rc = smb_smf_start_transaction(handle); 655 656 if (rc != SMBD_SMF_OK) { 657 smb_smf_scf_fini(handle); 658 return (rc); 659 } 660 661 if (protected && value && (*value != '\0')) { 662 if ((tmp = smb_base64_encode(value)) == NULL) { 663 (void) smb_smf_end_transaction(handle); 664 smb_smf_scf_fini(handle); 665 return (SMBD_SMF_NO_MEMORY); 666 } 667 668 value = tmp; 669 } 670 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; 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 715 free(tmp); 716 (void) smb_smf_end_transaction(handle); 717 smb_smf_scf_fini(handle); 718 return (rc); 719 } 720 721 /* 722 * smb_config_setnum 723 * 724 * Sets a numeric configuration iterm 725 */ 726 int 727 smb_config_setnum(smb_cfg_id_t id, int64_t value) 728 { 729 smb_scfhandle_t *handle; 730 smb_cfg_param_t *cfg; 731 int rc = SMBD_SMF_OK; 732 733 cfg = smb_config_getent(id); 734 assert(cfg->sc_type == SCF_TYPE_INTEGER); 735 736 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 737 if (handle == NULL) 738 return (SMBD_SMF_SYSTEM_ERR); 739 740 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 741 if (rc == SMBD_SMF_OK) 742 rc = smb_smf_start_transaction(handle); 743 744 if (rc != SMBD_SMF_OK) { 745 smb_smf_scf_fini(handle); 746 return (rc); 747 } 748 749 rc = smb_smf_set_integer_property(handle, cfg->sc_name, value); 750 751 (void) smb_smf_end_transaction(handle); 752 smb_smf_scf_fini(handle); 753 return (rc); 754 } 755 756 /* 757 * smb_config_setbool 758 * 759 * Sets a boolean configuration iterm 760 */ 761 int 762 smb_config_setbool(smb_cfg_id_t id, boolean_t value) 763 { 764 smb_scfhandle_t *handle; 765 smb_cfg_param_t *cfg; 766 int rc = SMBD_SMF_OK; 767 768 cfg = smb_config_getent(id); 769 assert(cfg->sc_type == SCF_TYPE_BOOLEAN); 770 771 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 772 if (handle == NULL) 773 return (SMBD_SMF_SYSTEM_ERR); 774 775 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 776 if (rc == SMBD_SMF_OK) 777 rc = smb_smf_start_transaction(handle); 778 779 if (rc != SMBD_SMF_OK) { 780 smb_smf_scf_fini(handle); 781 return (rc); 782 } 783 784 rc = smb_smf_set_boolean_property(handle, cfg->sc_name, value); 785 786 (void) smb_smf_end_transaction(handle); 787 smb_smf_scf_fini(handle); 788 return (rc); 789 } 790 791 /* 792 * smb_config_set 793 * 794 * This function sets the value of the specified config 795 * iterm regardless of its type in string format. This should 796 * be used when the config item type is not known by the caller. 797 */ 798 int 799 smb_config_set(smb_cfg_id_t id, char *value) 800 { 801 smb_cfg_param_t *cfg; 802 int64_t cint; 803 804 cfg = smb_config_getent(id); 805 switch (cfg->sc_type) { 806 case SCF_TYPE_ASTRING: 807 return (smb_config_setstr(id, value)); 808 809 case SCF_TYPE_INTEGER: 810 cint = atoi(value); 811 return (smb_config_setnum(id, cint)); 812 813 case SCF_TYPE_BOOLEAN: 814 return (smb_config_setbool(id, strcasecmp(value, "true") == 0)); 815 } 816 817 return (SMBD_SMF_INVALID_ARG); 818 } 819 820 int 821 smb_config_get_debug() 822 { 823 int64_t val64; 824 int val = 0; /* default */ 825 smb_scfhandle_t *handle = NULL; 826 827 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 828 if (handle == NULL) { 829 return (val); 830 } 831 832 if (smb_smf_create_service_pgroup(handle, 833 SMBD_PG_NAME) != SMBD_SMF_OK) { 834 smb_smf_scf_fini(handle); 835 return (val); 836 } 837 838 if (smb_smf_get_integer_property(handle, "debug", &val64) != 0) { 839 smb_smf_scf_fini(handle); 840 return (val); 841 } 842 val = (int)val64; 843 844 smb_smf_scf_fini(handle); 845 846 return (val); 847 } 848 849 uint8_t 850 smb_config_get_fg_flag() 851 { 852 uint8_t run_fg = 0; /* Default is to run in daemon mode */ 853 smb_scfhandle_t *handle = NULL; 854 855 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 856 if (handle == NULL) { 857 return (run_fg); 858 } 859 860 if (smb_smf_create_service_pgroup(handle, 861 SMBD_PG_NAME) != SMBD_SMF_OK) { 862 smb_smf_scf_fini(handle); 863 return (run_fg); 864 } 865 866 if (smb_smf_get_boolean_property(handle, "run_fg", &run_fg) != 0) { 867 smb_smf_scf_fini(handle); 868 return (run_fg); 869 } 870 871 smb_smf_scf_fini(handle); 872 873 return (run_fg); 874 } 875 876 /* 877 * smb_config_get_ads_enable 878 * 879 * Returns value of the "config/use_ads" parameter 880 * from the IDMAP SMF configuration repository. 881 * 882 */ 883 boolean_t 884 smb_config_get_ads_enable(void) 885 { 886 smb_scfhandle_t *handle = NULL; 887 uint8_t vbool; 888 int rc = 0; 889 890 handle = smb_smf_scf_init(IDMAP_FMRI_PREFIX); 891 if (handle == NULL) 892 return (B_FALSE); 893 894 rc = smb_smf_create_service_pgroup(handle, IDMAP_PG_NAME); 895 if (rc == SMBD_SMF_OK) 896 rc = smb_smf_get_boolean_property(handle, "use_ads", &vbool); 897 smb_smf_scf_fini(handle); 898 899 return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_TRUE); 900 } 901 902 /* 903 * smb_config_get_localsid 904 * 905 * Returns value of the "config/machine_sid" parameter 906 * from the IDMAP SMF configuration repository. 907 * Result is allocated; caller should free. 908 */ 909 char * 910 smb_config_get_localsid(void) 911 { 912 return (smb_config_getenv_generic(MACHINE_SID, IDMAP_FMRI_PREFIX, 913 IDMAP_PG_NAME)); 914 } 915 916 /* 917 * smb_config_get_localuuid 918 * 919 * Returns value of the "config/machine_uuid" parameter 920 * from the IDMAP SMF configuration repository. 921 * 922 */ 923 int 924 smb_config_get_localuuid(uuid_t uu) 925 { 926 char *s; 927 928 uuid_clear(uu); 929 s = smb_config_getenv_generic(MACHINE_UUID, IDMAP_FMRI_PREFIX, 930 IDMAP_PG_NAME); 931 if (s == NULL) 932 return (-1); 933 934 if (uuid_parse(s, uu) < 0) { 935 free(s); 936 return (-1); 937 } 938 939 return (0); 940 } 941 942 static int 943 smb_config_get_idmap_preferred_dc(char *cbuf, int bufsz) 944 { 945 char *s; 946 int len, rc = -1; 947 948 s = smb_config_getenv_generic(IDMAP_PREF_DC, 949 IDMAP_FMRI_PREFIX, IDMAP_PG_NAME); 950 if (s != NULL) { 951 len = strlcpy(cbuf, s, bufsz); 952 if (len < bufsz) 953 rc = 0; 954 free(s); 955 } 956 return (rc); 957 } 958 959 static int 960 smb_config_set_idmap_preferred_dc(char *value) 961 { 962 return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME, 963 IDMAP_PREF_DC, value)); 964 } 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 990 /* 991 * smb_config_set_idmap_domain 992 * 993 * Set the "config/domain_name" parameter from IDMAP SMF repository. 994 */ 995 int 996 smb_config_set_idmap_domain(char *value) 997 { 998 return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME, 999 IDMAP_DOMAIN, value)); 1000 } 1001 1002 /* 1003 * smb_config_refresh_idmap 1004 * 1005 * Refresh IDMAP SMF service after making changes to its configuration. 1006 */ 1007 int 1008 smb_config_refresh_idmap(void) 1009 { 1010 char instance[32]; 1011 1012 (void) snprintf(instance, sizeof (instance), "%s:default", 1013 IDMAP_FMRI_PREFIX); 1014 return (smf_refresh_instance(instance)); 1015 } 1016 1017 int 1018 smb_config_secmode_fromstr(char *secmode) 1019 { 1020 if (secmode == NULL) 1021 return (SMB_SECMODE_WORKGRP); 1022 1023 if (strcasecmp(secmode, SMB_SECMODE_DOMAIN_STR) == 0) 1024 return (SMB_SECMODE_DOMAIN); 1025 1026 return (SMB_SECMODE_WORKGRP); 1027 } 1028 1029 char * 1030 smb_config_secmode_tostr(int secmode) 1031 { 1032 if (secmode == SMB_SECMODE_DOMAIN) 1033 return (SMB_SECMODE_DOMAIN_STR); 1034 1035 return (SMB_SECMODE_WORKGRP_STR); 1036 } 1037 1038 int 1039 smb_config_get_secmode() 1040 { 1041 char p[16]; 1042 1043 (void) smb_config_getstr(SMB_CI_SECURITY, p, sizeof (p)); 1044 return (smb_config_secmode_fromstr(p)); 1045 } 1046 1047 int 1048 smb_config_set_secmode(int secmode) 1049 { 1050 char *p; 1051 1052 p = smb_config_secmode_tostr(secmode); 1053 return (smb_config_setstr(SMB_CI_SECURITY, p)); 1054 } 1055 1056 void 1057 smb_config_getdomaininfo(char *domain, char *fqdn, char *sid, char *forest, 1058 char *guid) 1059 { 1060 if (domain) 1061 (void) smb_config_getstr(SMB_CI_DOMAIN_NAME, domain, 1062 NETBIOS_NAME_SZ); 1063 1064 if (fqdn) 1065 (void) smb_config_getstr(SMB_CI_DOMAIN_FQDN, fqdn, 1066 MAXHOSTNAMELEN); 1067 1068 if (sid) 1069 (void) smb_config_getstr(SMB_CI_DOMAIN_SID, sid, 1070 SMB_SID_STRSZ); 1071 1072 if (forest) 1073 (void) smb_config_getstr(SMB_CI_DOMAIN_FOREST, forest, 1074 MAXHOSTNAMELEN); 1075 1076 if (guid) 1077 (void) smb_config_getstr(SMB_CI_DOMAIN_GUID, guid, 1078 UUID_PRINTABLE_STRING_LENGTH); 1079 } 1080 1081 void 1082 smb_config_setdomaininfo(char *domain, char *fqdn, char *sid, char *forest, 1083 char *guid) 1084 { 1085 if (domain) 1086 (void) smb_config_setstr(SMB_CI_DOMAIN_NAME, domain); 1087 if (fqdn) 1088 (void) smb_config_setstr(SMB_CI_DOMAIN_FQDN, fqdn); 1089 if (sid) 1090 (void) smb_config_setstr(SMB_CI_DOMAIN_SID, sid); 1091 if (forest) 1092 (void) smb_config_setstr(SMB_CI_DOMAIN_FOREST, forest); 1093 if (guid) 1094 (void) smb_config_setstr(SMB_CI_DOMAIN_GUID, guid); 1095 } 1096 1097 /* 1098 * The version stored in SMF in string format as N.N where 1099 * N is a number defined by Microsoft. The first number represents 1100 * the major version and the second number is the minor version. 1101 * Current defined values can be found here in 'ver_table'. 1102 * 1103 * This function reads the SMF string value and converts it to 1104 * two numbers returned in the given 'version' structure. 1105 * Current default version number is 5.0 which is for Windows 2000. 1106 */ 1107 void 1108 smb_config_get_version(smb_version_t *version) 1109 { 1110 smb_version_t tmpver; 1111 char verstr[SMB_VERSTR_LEN]; 1112 char *p; 1113 int rc, i; 1114 static smb_version_t ver_table [] = { 1115 { 0, SMB_MAJOR_NT, SMB_MINOR_NT, 1381, 0 }, 1116 { 0, SMB_MAJOR_2000, SMB_MINOR_2000, 2195, 0 }, 1117 { 0, SMB_MAJOR_XP, SMB_MINOR_XP, 2196, 0 }, 1118 { 0, SMB_MAJOR_2003, SMB_MINOR_2003, 2196, 0 }, 1119 { 0, SMB_MAJOR_VISTA, SMB_MINOR_VISTA, 6000, 0 }, 1120 { 0, SMB_MAJOR_2008, SMB_MINOR_2008, 6000, 0 }, 1121 { 0, SMB_MAJOR_2008R2, SMB_MINOR_2008R2, 7007, 0 }, 1122 { 0, SMB_MAJOR_7, SMB_MINOR_7, 7007, 0 } 1123 }; 1124 1125 *version = ver_table[1]; 1126 version->sv_size = sizeof (smb_version_t); 1127 1128 rc = smb_config_getstr(SMB_CI_VERSION, verstr, sizeof (verstr)); 1129 if (rc != SMBD_SMF_OK) 1130 return; 1131 1132 if ((p = strchr(verstr, '.')) == NULL) 1133 return; 1134 1135 *p = '\0'; 1136 tmpver.sv_major = (uint8_t)atoi(verstr); 1137 tmpver.sv_minor = (uint8_t)atoi(p + 1); 1138 1139 for (i = 0; i < sizeof (ver_table)/sizeof (ver_table[0]); ++i) { 1140 if ((tmpver.sv_major == ver_table[i].sv_major) && 1141 (tmpver.sv_minor == ver_table[i].sv_minor)) { 1142 *version = ver_table[i]; 1143 version->sv_size = sizeof (smb_version_t); 1144 break; 1145 } 1146 } 1147 } 1148 1149 /* 1150 * Reads share exec script properties 1151 */ 1152 uint32_t 1153 smb_config_get_execinfo(char *map, char *unmap, size_t bufsz) 1154 { 1155 char buf[MAXPATHLEN]; 1156 uint32_t flags = 0; 1157 1158 if (map == NULL) { 1159 map = buf; 1160 bufsz = MAXPATHLEN; 1161 } 1162 1163 *map = '\0'; 1164 (void) smb_config_getstr(SMB_CI_MAP, map, bufsz); 1165 if (*map != '\0') 1166 flags |= SMB_EXEC_MAP; 1167 1168 if (unmap == NULL) { 1169 unmap = buf; 1170 bufsz = MAXPATHLEN; 1171 } 1172 1173 *unmap = '\0'; 1174 (void) smb_config_getstr(SMB_CI_UNMAP, unmap, bufsz); 1175 if (*unmap != '\0') 1176 flags |= SMB_EXEC_UNMAP; 1177 1178 *buf = '\0'; 1179 (void) smb_config_getstr(SMB_CI_DISPOSITION, buf, sizeof (buf)); 1180 if (*buf != '\0') 1181 if (strcasecmp(buf, SMB_EXEC_DISP_TERMINATE) == 0) 1182 flags |= SMB_EXEC_TERM; 1183 1184 return (flags); 1185 } 1186 1187 static smb_cfg_param_t * 1188 smb_config_getent(smb_cfg_id_t id) 1189 { 1190 int i; 1191 1192 for (i = 0; i < SMB_CI_MAX; i++) 1193 if (smb_cfg_table[i].sc_id == id) 1194 return (&smb_cfg_table[id]); 1195 1196 assert(0); 1197 return (NULL); 1198 } 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; 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 1220 /* 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. 1226 */ 1227 uint32_t max_protocol_default = SMB_VERS_3_02; 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 1240 /* 1241 * This should eventually be SMB_VERS_2_BASE 1242 */ 1243 uint32_t min_protocol_default = SMB_VERS_1; 1244 1245 uint32_t 1246 smb_config_get_min_protocol(void) 1247 { 1248 uint32_t min; 1249 1250 min = smb_config_get_protocol(SMB_CI_MIN_PROTOCOL, "min_protocol", 1251 min_protocol_default); 1252 1253 return (min); 1254 } 1255 1256 int 1257 smb_config_check_protocol(char *value) 1258 { 1259 if (smb_convert_version_str(value) != 0) 1260 return (0); 1261 1262 return (-1); 1263 } 1264 1265 /* 1266 * If smb2_enable is present and max_protocol is empty, 1267 * set max_protocol. Delete smb2_enable. 1268 */ 1269 static void 1270 upgrade_smb2_enable() 1271 { 1272 smb_scfhandle_t *handle; 1273 char *s2e_name = "smb2_enable"; 1274 char *s2e_sval; 1275 uint8_t s2e_bval; 1276 char *maxp_name = "max_protocol"; 1277 char *maxp_sval; 1278 char verstr[SMB_VERSTR_LEN]; 1279 int rc; 1280 1281 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 1282 if (handle == NULL) 1283 return; 1284 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 1285 if (rc != SMBD_SMF_OK) 1286 goto out; 1287 1288 /* Is there an "smb2_enable" property? */ 1289 rc = smb_smf_get_boolean_property(handle, s2e_name, &s2e_bval); 1290 if (rc != SMBD_SMF_OK) { 1291 syslog(LOG_DEBUG, "upgrade: smb2_enable not found"); 1292 goto out; 1293 } 1294 1295 /* 1296 * We will try to delete the smb2_enable property, so we need 1297 * the transaction to start now, before we modify max_protocol 1298 */ 1299 if ((rc = smb_smf_start_transaction(handle)) != 0) { 1300 syslog(LOG_DEBUG, "upgrade_smb2_enable: start trans (%d)", rc); 1301 goto out; 1302 } 1303 1304 /* 1305 * Old (smb2_enable) property exists. 1306 * Does the new one? (max_protocol) 1307 */ 1308 rc = smb_smf_get_string_property(handle, maxp_name, 1309 verstr, sizeof (verstr)); 1310 if (rc == SMBD_SMF_OK && !smb_config_check_protocol(verstr)) { 1311 syslog(LOG_DEBUG, "upgrade: found %s = %s", 1312 maxp_name, verstr); 1313 /* Leave existing max_protocol as we found it. */ 1314 } else { 1315 /* 1316 * New property missing or invalid. 1317 * Upgrade from "smb2_enable". 1318 */ 1319 if (s2e_bval == 0) { 1320 s2e_sval = "false"; 1321 maxp_sval = "1"; 1322 } else { 1323 s2e_sval = "true"; 1324 maxp_sval = "2.1"; 1325 } 1326 /* 1327 * Note: Need this in the same transaction as the 1328 * delete of smb2_enable below. 1329 */ 1330 rc = smb_smf_set_string_property(handle, maxp_name, maxp_sval); 1331 if (rc != SMBD_SMF_OK) { 1332 syslog(LOG_ERR, "failed to set smbd/%d (%d)", 1333 maxp_name, rc); 1334 goto out; 1335 } 1336 syslog(LOG_INFO, "upgrade smbd/smb2_enable=%s " 1337 "converted to smbd/max_protocol=%s", 1338 s2e_sval, maxp_sval); 1339 } 1340 1341 /* 1342 * Delete the old smb2_enable property. 1343 */ 1344 if ((rc = smb_smf_delete_property(handle, s2e_name)) != 0) { 1345 syslog(LOG_DEBUG, "upgrade_smb2_enable: delete prop (%d)", rc); 1346 } else if ((rc = smb_smf_end_transaction(handle)) != 0) { 1347 syslog(LOG_DEBUG, "upgrade_smb2_enable: end trans (%d)", rc); 1348 } 1349 if (rc != 0) { 1350 syslog(LOG_ERR, "failed to delete property smbd/%d (%d)", 1351 s2e_name, rc); 1352 } 1353 1354 out: 1355 (void) smb_smf_end_transaction(handle); 1356 smb_smf_scf_fini(handle); 1357 } 1358 1359 1360 /* 1361 * Run once at startup convert old SMF settings to current. 1362 */ 1363 void 1364 smb_config_upgrade(void) 1365 { 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); 1385 } 1386