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 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 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 /* 53 * config parameter flags 54 */ 55 #define SMB_CF_PROTECTED 0x01 56 #define SMB_CF_EXEC 0x02 57 58 /* idmap SMF fmri and Property Group */ 59 #define IDMAP_FMRI_PREFIX "system/idmap" 60 #define MACHINE_SID "machine_sid" 61 #define IDMAP_DOMAIN "domain_name" 62 #define IDMAP_PG_NAME "config" 63 64 #define SMB_SECMODE_WORKGRP_STR "workgroup" 65 #define SMB_SECMODE_DOMAIN_STR "domain" 66 67 #define SMB_ENC_LEN 1024 68 #define SMB_DEC_LEN 256 69 70 static char *b64_data = 71 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 72 73 static smb_cfg_param_t smb_cfg_table[] = 74 { 75 /* Oplock configuration, Kernel Only */ 76 {SMB_CI_OPLOCK_ENABLE, "oplock_enable", SCF_TYPE_BOOLEAN, 0}, 77 78 /* Autohome configuration */ 79 {SMB_CI_AUTOHOME_MAP, "autohome_map", SCF_TYPE_ASTRING, 0}, 80 81 /* Domain/PDC configuration */ 82 {SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0}, 83 {SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0}, 84 {SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0}, 85 {SMB_CI_DOMAIN_FQDN, "fqdn", SCF_TYPE_ASTRING, 0}, 86 {SMB_CI_DOMAIN_FOREST, "forest", SCF_TYPE_ASTRING, 0}, 87 {SMB_CI_DOMAIN_GUID, "domain_guid", SCF_TYPE_ASTRING, 0}, 88 {SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0}, 89 90 /* WINS configuration */ 91 {SMB_CI_WINS_SRV1, "wins_server_1", SCF_TYPE_ASTRING, 0}, 92 {SMB_CI_WINS_SRV2, "wins_server_2", SCF_TYPE_ASTRING, 0}, 93 {SMB_CI_WINS_EXCL, "wins_exclude", SCF_TYPE_ASTRING, 0}, 94 95 /* Kmod specific configuration */ 96 {SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0}, 97 {SMB_CI_MAX_CONNECTIONS, "max_connections", SCF_TYPE_INTEGER, 0}, 98 {SMB_CI_KEEPALIVE, "keep_alive", SCF_TYPE_INTEGER, 0}, 99 {SMB_CI_RESTRICT_ANON, "restrict_anonymous", SCF_TYPE_BOOLEAN, 0}, 100 101 {SMB_CI_SIGNING_ENABLE, "signing_enabled", SCF_TYPE_BOOLEAN, 0}, 102 {SMB_CI_SIGNING_REQD, "signing_required", SCF_TYPE_BOOLEAN, 0}, 103 104 /* Kmod tuning configuration */ 105 {SMB_CI_SYNC_ENABLE, "sync_enable", SCF_TYPE_BOOLEAN, 0}, 106 107 /* SMBd configuration */ 108 {SMB_CI_SECURITY, "security", SCF_TYPE_ASTRING, 0}, 109 {SMB_CI_NBSCOPE, "netbios_scope", SCF_TYPE_ASTRING, 0}, 110 {SMB_CI_SYS_CMNT, "system_comment", SCF_TYPE_ASTRING, 0}, 111 {SMB_CI_LM_LEVEL, "lmauth_level", SCF_TYPE_INTEGER, 0}, 112 113 /* ADS Configuration */ 114 {SMB_CI_ADS_SITE, "ads_site", SCF_TYPE_ASTRING, 0}, 115 116 /* Dynamic DNS */ 117 {SMB_CI_DYNDNS_ENABLE, "ddns_enable", SCF_TYPE_BOOLEAN, 0}, 118 119 {SMB_CI_MACHINE_PASSWD, "machine_passwd", SCF_TYPE_ASTRING, 120 SMB_CF_PROTECTED}, 121 {SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING, 122 0}, 123 {SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING, 124 0}, 125 {SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER, 126 0}, 127 {SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER, 128 0}, 129 {SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0}, 130 {SMB_CI_MAP, "map", SCF_TYPE_ASTRING, SMB_CF_EXEC}, 131 {SMB_CI_UNMAP, "unmap", SCF_TYPE_ASTRING, SMB_CF_EXEC}, 132 {SMB_CI_DISPOSITION, "disposition", SCF_TYPE_ASTRING, SMB_CF_EXEC} 133 134 /* SMB_CI_MAX */ 135 }; 136 137 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t); 138 139 static boolean_t smb_is_base64(unsigned char c); 140 static char *smb_base64_encode(char *str_to_encode); 141 static char *smb_base64_decode(char *encoded_str); 142 143 char * 144 smb_config_getname(smb_cfg_id_t id) 145 { 146 smb_cfg_param_t *cfg; 147 cfg = smb_config_getent(id); 148 return (cfg->sc_name); 149 } 150 151 static boolean_t 152 smb_is_base64(unsigned char c) 153 { 154 return (isalnum(c) || (c == '+') || (c == '/')); 155 } 156 157 /* 158 * smb_base64_encode 159 * 160 * Encode a string using base64 algorithm. 161 * Caller should free the returned buffer when done. 162 */ 163 static char * 164 smb_base64_encode(char *str_to_encode) 165 { 166 int ret_cnt = 0; 167 int i = 0, j = 0; 168 char arr_3[3], arr_4[4]; 169 int len = strlen(str_to_encode); 170 char *ret = malloc(SMB_ENC_LEN); 171 172 if (ret == NULL) { 173 return (NULL); 174 } 175 176 while (len--) { 177 arr_3[i++] = *(str_to_encode++); 178 if (i == 3) { 179 arr_4[0] = (arr_3[0] & 0xfc) >> 2; 180 arr_4[1] = ((arr_3[0] & 0x03) << 4) + 181 ((arr_3[1] & 0xf0) >> 4); 182 arr_4[2] = ((arr_3[1] & 0x0f) << 2) + 183 ((arr_3[2] & 0xc0) >> 6); 184 arr_4[3] = arr_3[2] & 0x3f; 185 186 for (i = 0; i < 4; i++) 187 ret[ret_cnt++] = b64_data[arr_4[i]]; 188 i = 0; 189 } 190 } 191 192 if (i) { 193 for (j = i; j < 3; j++) 194 arr_3[j] = '\0'; 195 196 arr_4[0] = (arr_3[0] & 0xfc) >> 2; 197 arr_4[1] = ((arr_3[0] & 0x03) << 4) + 198 ((arr_3[1] & 0xf0) >> 4); 199 arr_4[2] = ((arr_3[1] & 0x0f) << 2) + 200 ((arr_3[2] & 0xc0) >> 6); 201 arr_4[3] = arr_3[2] & 0x3f; 202 203 for (j = 0; j < (i + 1); j++) 204 ret[ret_cnt++] = b64_data[arr_4[j]]; 205 206 while (i++ < 3) 207 ret[ret_cnt++] = '='; 208 } 209 210 ret[ret_cnt++] = '\0'; 211 return (ret); 212 } 213 214 /* 215 * smb_base64_decode 216 * 217 * Decode using base64 algorithm. 218 * Caller should free the returned buffer when done. 219 */ 220 static char * 221 smb_base64_decode(char *encoded_str) 222 { 223 int len = strlen(encoded_str); 224 int i = 0, j = 0; 225 int en_ind = 0; 226 char arr_4[4], arr_3[3]; 227 int ret_cnt = 0; 228 char *ret = malloc(SMB_DEC_LEN); 229 char *p; 230 231 if (ret == NULL) { 232 return (NULL); 233 } 234 235 while (len-- && (encoded_str[en_ind] != '=') && 236 smb_is_base64(encoded_str[en_ind])) { 237 arr_4[i++] = encoded_str[en_ind]; 238 en_ind++; 239 if (i == 4) { 240 for (i = 0; i < 4; i++) { 241 if ((p = strchr(b64_data, arr_4[i])) == NULL) 242 return (NULL); 243 244 arr_4[i] = (int)(p - b64_data); 245 } 246 247 arr_3[0] = (arr_4[0] << 2) + 248 ((arr_4[1] & 0x30) >> 4); 249 arr_3[1] = ((arr_4[1] & 0xf) << 4) + 250 ((arr_4[2] & 0x3c) >> 2); 251 arr_3[2] = ((arr_4[2] & 0x3) << 6) + 252 arr_4[3]; 253 254 for (i = 0; i < 3; i++) 255 ret[ret_cnt++] = arr_3[i]; 256 257 i = 0; 258 } 259 } 260 261 if (i) { 262 for (j = i; j < 4; j++) 263 arr_4[j] = 0; 264 265 for (j = 0; j < 4; j++) { 266 if ((p = strchr(b64_data, arr_4[j])) == NULL) 267 return (NULL); 268 269 arr_4[j] = (int)(p - b64_data); 270 } 271 arr_3[0] = (arr_4[0] << 2) + 272 ((arr_4[1] & 0x30) >> 4); 273 arr_3[1] = ((arr_4[1] & 0xf) << 4) + 274 ((arr_4[2] & 0x3c) >> 2); 275 arr_3[2] = ((arr_4[2] & 0x3) << 6) + 276 arr_4[3]; 277 for (j = 0; j < (i - 1); j++) 278 ret[ret_cnt++] = arr_3[j]; 279 } 280 281 ret[ret_cnt++] = '\0'; 282 return (ret); 283 } 284 285 static char * 286 smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp) 287 { 288 smb_scfhandle_t *handle; 289 char *value; 290 291 if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL) 292 return (NULL); 293 294 handle = smb_smf_scf_init(svc_fmri_prefix); 295 if (handle == NULL) { 296 free(value); 297 return (NULL); 298 } 299 300 (void) smb_smf_create_service_pgroup(handle, svc_propgrp); 301 302 if (smb_smf_get_string_property(handle, name, value, 303 sizeof (char) * MAX_VALUE_BUFLEN) != 0) { 304 smb_smf_scf_fini(handle); 305 free(value); 306 return (NULL); 307 } 308 309 smb_smf_scf_fini(handle); 310 return (value); 311 312 } 313 314 static int 315 smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp, 316 char *name, char *value) 317 { 318 smb_scfhandle_t *handle = NULL; 319 int rc = 0; 320 321 322 handle = smb_smf_scf_init(svc_fmri_prefix); 323 if (handle == NULL) { 324 return (1); 325 } 326 327 (void) smb_smf_create_service_pgroup(handle, svc_propgrp); 328 329 if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) { 330 smb_smf_scf_fini(handle); 331 return (1); 332 } 333 334 if (smb_smf_set_string_property(handle, name, value) != SMBD_SMF_OK) 335 rc = 1; 336 337 if (smb_smf_end_transaction(handle) != SMBD_SMF_OK) 338 rc = 1; 339 340 smb_smf_scf_fini(handle); 341 return (rc); 342 } 343 344 /* 345 * smb_config_getstr 346 * 347 * Fetch the specified string configuration item from SMF 348 */ 349 int 350 smb_config_getstr(smb_cfg_id_t id, char *cbuf, int bufsz) 351 { 352 smb_scfhandle_t *handle; 353 smb_cfg_param_t *cfg; 354 int rc = SMBD_SMF_OK; 355 char *pg; 356 char protbuf[SMB_ENC_LEN]; 357 char *tmp; 358 359 *cbuf = '\0'; 360 cfg = smb_config_getent(id); 361 assert(cfg->sc_type == SCF_TYPE_ASTRING); 362 363 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 364 if (handle == NULL) 365 return (SMBD_SMF_SYSTEM_ERR); 366 367 if (cfg->sc_flags & SMB_CF_PROTECTED) { 368 if ((rc = smb_smf_create_service_pgroup(handle, 369 SMBD_PROTECTED_PG_NAME)) != SMBD_SMF_OK) 370 goto error; 371 372 if ((rc = smb_smf_get_string_property(handle, cfg->sc_name, 373 protbuf, sizeof (protbuf))) != SMBD_SMF_OK) 374 goto error; 375 376 if (*protbuf != '\0') { 377 tmp = smb_base64_decode(protbuf); 378 (void) strlcpy(cbuf, tmp, bufsz); 379 free(tmp); 380 } 381 } else { 382 pg = (cfg->sc_flags & SMB_CF_EXEC) ? SMBD_EXEC_PG_NAME : 383 SMBD_PG_NAME; 384 rc = smb_smf_create_service_pgroup(handle, pg); 385 if (rc == SMBD_SMF_OK) 386 rc = smb_smf_get_string_property(handle, cfg->sc_name, 387 cbuf, bufsz); 388 } 389 390 error: 391 smb_smf_scf_fini(handle); 392 return (rc); 393 } 394 395 /* 396 * Translate the value of an astring SMF property into a binary 397 * IP address. If the value is neither a valid IPv4 nor IPv6 398 * address, attempt to look it up as a hostname using the 399 * configured address type. 400 */ 401 int 402 smb_config_getip(smb_cfg_id_t sc_id, smb_inaddr_t *ipaddr) 403 { 404 int rc, error; 405 int a_family; 406 char ipstr[MAXHOSTNAMELEN]; 407 struct hostent *h; 408 smb_cfg_param_t *cfg; 409 410 if (ipaddr == NULL) 411 return (SMBD_SMF_INVALID_ARG); 412 413 bzero(ipaddr, sizeof (smb_inaddr_t)); 414 rc = smb_config_getstr(sc_id, ipstr, sizeof (ipstr)); 415 if (rc == SMBD_SMF_OK) { 416 if (*ipstr == '\0') 417 return (SMBD_SMF_INVALID_ARG); 418 419 if (inet_pton(AF_INET, ipstr, &ipaddr->a_ipv4) == 1) { 420 ipaddr->a_family = AF_INET; 421 return (SMBD_SMF_OK); 422 } 423 424 if (inet_pton(AF_INET6, ipstr, &ipaddr->a_ipv6) == 1) { 425 ipaddr->a_family = AF_INET6; 426 return (SMBD_SMF_OK); 427 } 428 429 /* 430 * The value is neither an IPv4 nor IPv6 address; 431 * so check if it's a hostname. 432 */ 433 a_family = smb_config_getbool(SMB_CI_IPV6_ENABLE) ? 434 AF_INET6 : AF_INET; 435 h = getipnodebyname(ipstr, a_family, AI_DEFAULT, 436 &error); 437 if (h != NULL) { 438 bcopy(*(h->h_addr_list), &ipaddr->a_ip, 439 h->h_length); 440 ipaddr->a_family = a_family; 441 freehostent(h); 442 rc = SMBD_SMF_OK; 443 } else { 444 cfg = smb_config_getent(sc_id); 445 syslog(LOG_ERR, "smbd/%s: %s unable to get %s " 446 "address: %d", cfg->sc_name, ipstr, 447 a_family == AF_INET ? "IPv4" : "IPv6", error); 448 rc = SMBD_SMF_INVALID_ARG; 449 } 450 } 451 452 return (rc); 453 } 454 455 /* 456 * smb_config_getnum 457 * 458 * Returns the value of a numeric config param. 459 */ 460 int 461 smb_config_getnum(smb_cfg_id_t id, int64_t *cint) 462 { 463 smb_scfhandle_t *handle; 464 smb_cfg_param_t *cfg; 465 int rc = SMBD_SMF_OK; 466 467 *cint = 0; 468 cfg = smb_config_getent(id); 469 assert(cfg->sc_type == SCF_TYPE_INTEGER); 470 471 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 472 if (handle == NULL) 473 return (SMBD_SMF_SYSTEM_ERR); 474 475 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 476 if (rc == SMBD_SMF_OK) 477 rc = smb_smf_get_integer_property(handle, cfg->sc_name, cint); 478 smb_smf_scf_fini(handle); 479 480 return (rc); 481 } 482 483 /* 484 * smb_config_getbool 485 * 486 * Returns the value of a boolean config param. 487 */ 488 boolean_t 489 smb_config_getbool(smb_cfg_id_t id) 490 { 491 smb_scfhandle_t *handle; 492 smb_cfg_param_t *cfg; 493 int rc = SMBD_SMF_OK; 494 uint8_t vbool; 495 496 cfg = smb_config_getent(id); 497 assert(cfg->sc_type == SCF_TYPE_BOOLEAN); 498 499 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 500 if (handle == NULL) 501 return (B_FALSE); 502 503 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 504 if (rc == SMBD_SMF_OK) 505 rc = smb_smf_get_boolean_property(handle, cfg->sc_name, &vbool); 506 smb_smf_scf_fini(handle); 507 508 return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE); 509 } 510 511 /* 512 * smb_config_get 513 * 514 * This function returns the value of the requested config 515 * iterm regardless of its type in string format. This should 516 * be used when the config item type is not known by the caller. 517 */ 518 int 519 smb_config_get(smb_cfg_id_t id, char *cbuf, int bufsz) 520 { 521 smb_cfg_param_t *cfg; 522 int64_t cint; 523 int rc; 524 525 cfg = smb_config_getent(id); 526 switch (cfg->sc_type) { 527 case SCF_TYPE_ASTRING: 528 return (smb_config_getstr(id, cbuf, bufsz)); 529 530 case SCF_TYPE_INTEGER: 531 rc = smb_config_getnum(id, &cint); 532 if (rc == SMBD_SMF_OK) 533 (void) snprintf(cbuf, bufsz, "%lld", cint); 534 return (rc); 535 536 case SCF_TYPE_BOOLEAN: 537 if (smb_config_getbool(id)) 538 (void) strlcpy(cbuf, "true", bufsz); 539 else 540 (void) strlcpy(cbuf, "false", bufsz); 541 return (SMBD_SMF_OK); 542 } 543 544 return (SMBD_SMF_INVALID_ARG); 545 } 546 547 /* 548 * smb_config_setstr 549 * 550 * Set the specified config param with the given 551 * value. 552 */ 553 int 554 smb_config_setstr(smb_cfg_id_t id, char *value) 555 { 556 smb_scfhandle_t *handle; 557 smb_cfg_param_t *cfg; 558 int rc = SMBD_SMF_OK; 559 boolean_t protected; 560 char *tmp = NULL; 561 char *pg; 562 563 cfg = smb_config_getent(id); 564 assert(cfg->sc_type == SCF_TYPE_ASTRING); 565 566 protected = B_FALSE; 567 568 switch (cfg->sc_flags) { 569 case SMB_CF_PROTECTED: 570 protected = B_TRUE; 571 pg = SMBD_PROTECTED_PG_NAME; 572 break; 573 case SMB_CF_EXEC: 574 pg = SMBD_EXEC_PG_NAME; 575 break; 576 default: 577 pg = SMBD_PG_NAME; 578 break; 579 } 580 581 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 582 if (handle == NULL) 583 return (SMBD_SMF_SYSTEM_ERR); 584 585 rc = smb_smf_create_service_pgroup(handle, pg); 586 if (rc == SMBD_SMF_OK) 587 rc = smb_smf_start_transaction(handle); 588 589 if (rc != SMBD_SMF_OK) { 590 smb_smf_scf_fini(handle); 591 return (rc); 592 } 593 594 if (protected && value && (*value != '\0')) { 595 if ((tmp = smb_base64_encode(value)) == NULL) { 596 (void) smb_smf_end_transaction(handle); 597 smb_smf_scf_fini(handle); 598 return (SMBD_SMF_NO_MEMORY); 599 } 600 601 value = tmp; 602 } 603 604 rc = smb_smf_set_string_property(handle, cfg->sc_name, value); 605 606 free(tmp); 607 (void) smb_smf_end_transaction(handle); 608 smb_smf_scf_fini(handle); 609 return (rc); 610 } 611 612 /* 613 * smb_config_setnum 614 * 615 * Sets a numeric configuration iterm 616 */ 617 int 618 smb_config_setnum(smb_cfg_id_t id, int64_t value) 619 { 620 smb_scfhandle_t *handle; 621 smb_cfg_param_t *cfg; 622 int rc = SMBD_SMF_OK; 623 624 cfg = smb_config_getent(id); 625 assert(cfg->sc_type == SCF_TYPE_INTEGER); 626 627 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 628 if (handle == NULL) 629 return (SMBD_SMF_SYSTEM_ERR); 630 631 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 632 if (rc == SMBD_SMF_OK) 633 rc = smb_smf_start_transaction(handle); 634 635 if (rc != SMBD_SMF_OK) { 636 smb_smf_scf_fini(handle); 637 return (rc); 638 } 639 640 rc = smb_smf_set_integer_property(handle, cfg->sc_name, value); 641 642 (void) smb_smf_end_transaction(handle); 643 smb_smf_scf_fini(handle); 644 return (rc); 645 } 646 647 /* 648 * smb_config_setbool 649 * 650 * Sets a boolean configuration iterm 651 */ 652 int 653 smb_config_setbool(smb_cfg_id_t id, boolean_t value) 654 { 655 smb_scfhandle_t *handle; 656 smb_cfg_param_t *cfg; 657 int rc = SMBD_SMF_OK; 658 659 cfg = smb_config_getent(id); 660 assert(cfg->sc_type == SCF_TYPE_BOOLEAN); 661 662 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 663 if (handle == NULL) 664 return (SMBD_SMF_SYSTEM_ERR); 665 666 rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME); 667 if (rc == SMBD_SMF_OK) 668 rc = smb_smf_start_transaction(handle); 669 670 if (rc != SMBD_SMF_OK) { 671 smb_smf_scf_fini(handle); 672 return (rc); 673 } 674 675 rc = smb_smf_set_boolean_property(handle, cfg->sc_name, value); 676 677 (void) smb_smf_end_transaction(handle); 678 smb_smf_scf_fini(handle); 679 return (rc); 680 } 681 682 /* 683 * smb_config_set 684 * 685 * This function sets the value of the specified config 686 * iterm regardless of its type in string format. This should 687 * be used when the config item type is not known by the caller. 688 */ 689 int 690 smb_config_set(smb_cfg_id_t id, char *value) 691 { 692 smb_cfg_param_t *cfg; 693 int64_t cint; 694 695 cfg = smb_config_getent(id); 696 switch (cfg->sc_type) { 697 case SCF_TYPE_ASTRING: 698 return (smb_config_setstr(id, value)); 699 700 case SCF_TYPE_INTEGER: 701 cint = atoi(value); 702 return (smb_config_setnum(id, cint)); 703 704 case SCF_TYPE_BOOLEAN: 705 return (smb_config_setbool(id, strcasecmp(value, "true") == 0)); 706 } 707 708 return (SMBD_SMF_INVALID_ARG); 709 } 710 uint8_t 711 smb_config_get_fg_flag() 712 { 713 uint8_t run_fg = 0; /* Default is to run in daemon mode */ 714 smb_scfhandle_t *handle = NULL; 715 716 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX); 717 if (handle == NULL) { 718 return (run_fg); 719 } 720 721 if (smb_smf_create_service_pgroup(handle, 722 SMBD_PG_NAME) != SMBD_SMF_OK) { 723 smb_smf_scf_fini(handle); 724 return (run_fg); 725 } 726 727 if (smb_smf_get_boolean_property(handle, "run_fg", &run_fg) != 0) { 728 smb_smf_scf_fini(handle); 729 return (run_fg); 730 } 731 732 smb_smf_scf_fini(handle); 733 734 return (run_fg); 735 } 736 737 /* 738 * smb_config_get_localsid 739 * 740 * Returns value of the "config/machine_sid" parameter 741 * from the IDMAP SMF configuration repository. 742 * 743 */ 744 char * 745 smb_config_get_localsid(void) 746 { 747 return (smb_config_getenv_generic(MACHINE_SID, IDMAP_FMRI_PREFIX, 748 IDMAP_PG_NAME)); 749 } 750 751 /* 752 * smb_config_set_idmap_domain 753 * 754 * Set the "config/domain_name" parameter from IDMAP SMF repository. 755 */ 756 int 757 smb_config_set_idmap_domain(char *value) 758 { 759 return (smb_config_setenv_generic(IDMAP_FMRI_PREFIX, IDMAP_PG_NAME, 760 IDMAP_DOMAIN, value)); 761 } 762 763 /* 764 * smb_config_refresh_idmap 765 * 766 * Refresh IDMAP SMF service after making changes to its configuration. 767 */ 768 int 769 smb_config_refresh_idmap(void) 770 { 771 char instance[32]; 772 773 (void) snprintf(instance, sizeof (instance), "%s:default", 774 IDMAP_FMRI_PREFIX); 775 return (smf_refresh_instance(instance)); 776 } 777 778 int 779 smb_config_secmode_fromstr(char *secmode) 780 { 781 if (secmode == NULL) 782 return (SMB_SECMODE_WORKGRP); 783 784 if (strcasecmp(secmode, SMB_SECMODE_DOMAIN_STR) == 0) 785 return (SMB_SECMODE_DOMAIN); 786 787 return (SMB_SECMODE_WORKGRP); 788 } 789 790 char * 791 smb_config_secmode_tostr(int secmode) 792 { 793 if (secmode == SMB_SECMODE_DOMAIN) 794 return (SMB_SECMODE_DOMAIN_STR); 795 796 return (SMB_SECMODE_WORKGRP_STR); 797 } 798 799 int 800 smb_config_get_secmode() 801 { 802 char p[16]; 803 804 (void) smb_config_getstr(SMB_CI_SECURITY, p, sizeof (p)); 805 return (smb_config_secmode_fromstr(p)); 806 } 807 808 int 809 smb_config_set_secmode(int secmode) 810 { 811 char *p; 812 813 p = smb_config_secmode_tostr(secmode); 814 return (smb_config_setstr(SMB_CI_SECURITY, p)); 815 } 816 817 static smb_cfg_param_t * 818 smb_config_getent(smb_cfg_id_t id) 819 { 820 int i; 821 822 for (i = 0; i < SMB_CI_MAX; i++) 823 if (smb_cfg_table[i].sc_id == id) 824 return (&smb_cfg_table[id]); 825 826 assert(0); 827 return (NULL); 828 } 829 830 void 831 smb_config_getdomaininfo(char *domain, char *fqdn, char *sid, char *forest, 832 char *guid) 833 { 834 if (domain) 835 (void) smb_config_getstr(SMB_CI_DOMAIN_NAME, domain, 836 NETBIOS_NAME_SZ); 837 838 if (fqdn) 839 (void) smb_config_getstr(SMB_CI_DOMAIN_FQDN, fqdn, 840 MAXHOSTNAMELEN); 841 842 if (sid) 843 (void) smb_config_getstr(SMB_CI_DOMAIN_SID, sid, 844 SMB_SID_STRSZ); 845 846 if (forest) 847 (void) smb_config_getstr(SMB_CI_DOMAIN_FOREST, forest, 848 MAXHOSTNAMELEN); 849 850 if (guid) 851 (void) smb_config_getstr(SMB_CI_DOMAIN_GUID, guid, 852 UUID_PRINTABLE_STRING_LENGTH); 853 } 854 855 void 856 smb_config_setdomaininfo(char *domain, char *fqdn, char *sid, char *forest, 857 char *guid) 858 { 859 if (domain) 860 (void) smb_config_setstr(SMB_CI_DOMAIN_NAME, domain); 861 if (fqdn) 862 (void) smb_config_setstr(SMB_CI_DOMAIN_FQDN, fqdn); 863 if (sid) 864 (void) smb_config_setstr(SMB_CI_DOMAIN_SID, sid); 865 if (forest) 866 (void) smb_config_setstr(SMB_CI_DOMAIN_FOREST, forest); 867 if (guid) 868 (void) smb_config_setstr(SMB_CI_DOMAIN_GUID, guid); 869 } 870