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 */ 24 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <sys/ioccom.h> 28 #include <sys/corectl.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include <stdarg.h> 35 #include <fcntl.h> 36 #include <wait.h> 37 #include <signal.h> 38 #include <atomic.h> 39 #include <libscf.h> 40 #include <limits.h> 41 #include <priv_utils.h> 42 #include <door.h> 43 #include <errno.h> 44 #include <pthread.h> 45 #include <time.h> 46 #include <libscf.h> 47 #include <zone.h> 48 #include <libgen.h> 49 #include <pwd.h> 50 #include <grp.h> 51 #include <cups/cups.h> 52 53 #include <smbsrv/smb_door.h> 54 #include <smbsrv/smb_ioctl.h> 55 #include <smbsrv/string.h> 56 #include <smbsrv/libsmb.h> 57 #include <smbsrv/libsmbns.h> 58 #include <smbsrv/libmlsvc.h> 59 #include "smbd.h" 60 61 #define SMB_CUPS_DOCNAME "generic_doc" 62 #define DRV_DEVICE_PATH "/devices/pseudo/smbsrv@0:smbsrv" 63 #define SMB_DBDIR "/var/smb" 64 #define SMB_SPOOL_WAIT 2 65 66 static void *smbd_nbt_listener(void *); 67 static void *smbd_tcp_listener(void *); 68 static void *smbd_nbt_receiver(void *); 69 static void *smbd_tcp_receiver(void *); 70 71 static int smbd_daemonize_init(void); 72 static void smbd_daemonize_fini(int, int); 73 static int smb_init_daemon_priv(int, uid_t, gid_t); 74 75 static int smbd_kernel_bind(void); 76 static void smbd_kernel_unbind(void); 77 static int smbd_already_running(void); 78 79 static int smbd_service_init(void); 80 static void smbd_service_fini(void); 81 82 static int smbd_setup_options(int argc, char *argv[]); 83 static void smbd_usage(FILE *fp); 84 static void smbd_report(const char *fmt, ...); 85 86 static void smbd_sig_handler(int sig); 87 88 static int32_t smbd_gmtoff(void); 89 static int smbd_localtime_init(void); 90 static void *smbd_localtime_monitor(void *arg); 91 92 static pthread_t localtime_thr; 93 94 static int smbd_spool_init(void); 95 static void *smbd_spool_monitor(void *arg); 96 static pthread_t smbd_spool_thr; 97 98 static int smbd_refresh_init(void); 99 static void smbd_refresh_fini(void); 100 static void *smbd_refresh_monitor(void *); 101 static void smbd_refresh_dc(void); 102 103 static void *smbd_nbt_receiver(void *); 104 static void *smbd_nbt_listener(void *); 105 106 static void *smbd_tcp_receiver(void *); 107 static void *smbd_tcp_listener(void *); 108 109 static int smbd_start_listeners(void); 110 static void smbd_stop_listeners(void); 111 static int smbd_kernel_start(void); 112 113 static void smbd_fatal_error(const char *); 114 115 static pthread_t refresh_thr; 116 static pthread_cond_t refresh_cond; 117 static pthread_mutex_t refresh_mutex; 118 119 static cond_t listener_cv; 120 static mutex_t listener_mutex; 121 122 /* 123 * Mutex to ensure that smbd_service_fini() and smbd_service_init() 124 * are atomic w.r.t. one another. Otherwise, if a shutdown begins 125 * before initialization is complete, resources can get deallocated 126 * while initialization threads are still using them. 127 */ 128 static mutex_t smbd_service_mutex; 129 static cond_t smbd_service_cv; 130 131 smbd_t smbd; 132 133 /* 134 * Use SMF error codes only on return or exit. 135 */ 136 int 137 main(int argc, char *argv[]) 138 { 139 struct sigaction act; 140 sigset_t set; 141 uid_t uid; 142 int pfd = -1; 143 uint_t sigval; 144 struct rlimit rl; 145 int orig_limit; 146 147 smbd.s_pname = basename(argv[0]); 148 openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 149 150 if (smbd_setup_options(argc, argv) != 0) 151 return (SMF_EXIT_ERR_FATAL); 152 153 if ((uid = getuid()) != smbd.s_uid) { 154 smbd_report("user %d: %s", uid, strerror(EPERM)); 155 return (SMF_EXIT_ERR_FATAL); 156 } 157 158 if (getzoneid() != GLOBAL_ZONEID) { 159 smbd_report("non-global zones are not supported"); 160 return (SMF_EXIT_ERR_FATAL); 161 } 162 163 if (is_system_labeled()) { 164 smbd_report("Trusted Extensions not supported"); 165 return (SMF_EXIT_ERR_FATAL); 166 } 167 168 if (smbd_already_running()) 169 return (SMF_EXIT_OK); 170 171 /* 172 * Raise the file descriptor limit to accommodate simultaneous user 173 * authentications/file access. 174 */ 175 if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) && 176 (rl.rlim_cur < rl.rlim_max)) { 177 orig_limit = rl.rlim_cur; 178 rl.rlim_cur = rl.rlim_max; 179 if (setrlimit(RLIMIT_NOFILE, &rl) != 0) 180 smbd_report("Failed to raise file descriptor limit" 181 " from %d to %d", orig_limit, rl.rlim_cur); 182 } 183 184 (void) sigfillset(&set); 185 (void) sigdelset(&set, SIGABRT); 186 187 (void) sigfillset(&act.sa_mask); 188 act.sa_handler = smbd_sig_handler; 189 act.sa_flags = 0; 190 191 (void) sigaction(SIGABRT, &act, NULL); 192 (void) sigaction(SIGTERM, &act, NULL); 193 (void) sigaction(SIGHUP, &act, NULL); 194 (void) sigaction(SIGINT, &act, NULL); 195 (void) sigaction(SIGPIPE, &act, NULL); 196 (void) sigaction(SIGUSR1, &act, NULL); 197 198 (void) sigdelset(&set, SIGTERM); 199 (void) sigdelset(&set, SIGHUP); 200 (void) sigdelset(&set, SIGINT); 201 (void) sigdelset(&set, SIGPIPE); 202 (void) sigdelset(&set, SIGUSR1); 203 204 if (smbd.s_fg) { 205 (void) sigdelset(&set, SIGTSTP); 206 (void) sigdelset(&set, SIGTTIN); 207 (void) sigdelset(&set, SIGTTOU); 208 209 if (smbd_service_init() != 0) { 210 smbd_report("service initialization failed"); 211 exit(SMF_EXIT_ERR_FATAL); 212 } 213 } else { 214 /* 215 * "pfd" is a pipe descriptor -- any fatal errors 216 * during subsequent initialization of the child 217 * process should be written to this pipe and the 218 * parent will report this error as the exit status. 219 */ 220 pfd = smbd_daemonize_init(); 221 222 if (smbd_service_init() != 0) { 223 smbd_report("daemon initialization failed"); 224 exit(SMF_EXIT_ERR_FATAL); 225 } 226 227 smbd_daemonize_fini(pfd, SMF_EXIT_OK); 228 } 229 230 (void) atexit(smb_kmod_stop); 231 232 while (!smbd.s_shutting_down) { 233 if (smbd.s_sigval == 0 && smbd.s_refreshes == 0) 234 (void) sigsuspend(&set); 235 236 sigval = atomic_swap_uint(&smbd.s_sigval, 0); 237 238 switch (sigval) { 239 case 0: 240 case SIGPIPE: 241 case SIGABRT: 242 break; 243 244 case SIGHUP: 245 syslog(LOG_DEBUG, "refresh requested"); 246 (void) pthread_cond_signal(&refresh_cond); 247 break; 248 249 case SIGUSR1: 250 smb_log_dumpall(); 251 break; 252 253 default: 254 /* 255 * Typically SIGINT or SIGTERM. 256 */ 257 smbd.s_shutting_down = B_TRUE; 258 break; 259 } 260 } 261 262 smbd_service_fini(); 263 closelog(); 264 return ((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK); 265 } 266 267 /* 268 * This function will fork off a child process, 269 * from which only the child will return. 270 * 271 * Use SMF error codes only on exit. 272 */ 273 static int 274 smbd_daemonize_init(void) 275 { 276 int status, pfds[2]; 277 sigset_t set, oset; 278 pid_t pid; 279 int rc; 280 281 /* 282 * Reset privileges to the minimum set required. We continue 283 * to run as root to create and access files in /var. 284 */ 285 rc = smb_init_daemon_priv(PU_RESETGROUPS, smbd.s_uid, smbd.s_gid); 286 287 if (rc != 0) { 288 smbd_report("insufficient privileges"); 289 exit(SMF_EXIT_ERR_FATAL); 290 } 291 292 /* 293 * Block all signals prior to the fork and leave them blocked in the 294 * parent so we don't get in a situation where the parent gets SIGINT 295 * and returns non-zero exit status and the child is actually running. 296 * In the child, restore the signal mask once we've done our setsid(). 297 */ 298 (void) sigfillset(&set); 299 (void) sigdelset(&set, SIGABRT); 300 (void) sigprocmask(SIG_BLOCK, &set, &oset); 301 302 if (pipe(pfds) == -1) { 303 smbd_report("unable to create pipe"); 304 exit(SMF_EXIT_ERR_FATAL); 305 } 306 307 closelog(); 308 309 if ((pid = fork()) == -1) { 310 openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 311 smbd_report("unable to fork"); 312 closelog(); 313 exit(SMF_EXIT_ERR_FATAL); 314 } 315 316 /* 317 * If we're the parent process, wait for either the child to send us 318 * the appropriate exit status over the pipe or for the read to fail 319 * (presumably with 0 for EOF if our child terminated abnormally). 320 * If the read fails, exit with either the child's exit status if it 321 * exited or with SMF_EXIT_ERR_FATAL if it died from a fatal signal. 322 */ 323 if (pid != 0) { 324 (void) close(pfds[1]); 325 326 if (read(pfds[0], &status, sizeof (status)) == sizeof (status)) 327 _exit(status); 328 329 if (waitpid(pid, &status, 0) == pid && WIFEXITED(status)) 330 _exit(WEXITSTATUS(status)); 331 332 _exit(SMF_EXIT_ERR_FATAL); 333 } 334 335 openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 336 (void) setsid(); 337 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 338 (void) chdir("/"); 339 (void) umask(022); 340 (void) close(pfds[0]); 341 342 return (pfds[1]); 343 } 344 345 /* 346 * This function is based on __init_daemon_priv() and replaces 347 * __init_daemon_priv() since we want smbd to have all privileges so that it 348 * can execute map/unmap commands with all privileges during share 349 * connection/disconnection. Unused privileges are disabled until command 350 * execution. The permitted and the limit set contains all privileges. The 351 * inheritable set contains no privileges. 352 */ 353 354 static const char root_cp[] = "/core.%f.%t"; 355 static const char daemon_cp[] = "/var/tmp/core.%f.%t"; 356 357 static int 358 smb_init_daemon_priv(int flags, uid_t uid, gid_t gid) 359 { 360 priv_set_t *perm = NULL; 361 int ret = -1; 362 char buf[1024]; 363 364 /* 365 * This is not a significant failure: it allows us to start programs 366 * with sufficient privileges and with the proper uid. We don't 367 * care enough about the extra groups in that case. 368 */ 369 if (flags & PU_RESETGROUPS) 370 (void) setgroups(0, NULL); 371 372 if (gid != (gid_t)-1 && setgid(gid) != 0) 373 goto end; 374 375 perm = priv_allocset(); 376 if (perm == NULL) 377 goto end; 378 379 /* E = P */ 380 (void) getppriv(PRIV_PERMITTED, perm); 381 (void) setppriv(PRIV_SET, PRIV_EFFECTIVE, perm); 382 383 /* Now reset suid and euid */ 384 if (uid != (uid_t)-1 && setreuid(uid, uid) != 0) 385 goto end; 386 387 /* I = 0 */ 388 priv_emptyset(perm); 389 ret = setppriv(PRIV_SET, PRIV_INHERITABLE, perm); 390 end: 391 priv_freeset(perm); 392 393 if (core_get_process_path(buf, sizeof (buf), getpid()) == 0 && 394 strcmp(buf, "core") == 0) { 395 396 if ((uid == (uid_t)-1 ? geteuid() : uid) == 0) { 397 (void) core_set_process_path(root_cp, sizeof (root_cp), 398 getpid()); 399 } else { 400 (void) core_set_process_path(daemon_cp, 401 sizeof (daemon_cp), getpid()); 402 } 403 } 404 (void) setpflags(__PROC_PROTECT, 0); 405 406 return (ret); 407 } 408 409 /* 410 * Most privileges, except the ones that are required for smbd, are turn off 411 * in the effective set. They will be turn on when needed for command 412 * execution during share connection/disconnection. 413 */ 414 static void 415 smbd_daemonize_fini(int fd, int exit_status) 416 { 417 priv_set_t *pset; 418 419 /* 420 * Now that we're running, if a pipe fd was specified, write an exit 421 * status to it to indicate that our parent process can safely detach. 422 * Then proceed to loading the remaining non-built-in modules. 423 */ 424 if (fd >= 0) 425 (void) write(fd, &exit_status, sizeof (exit_status)); 426 427 (void) close(fd); 428 429 pset = priv_allocset(); 430 if (pset == NULL) 431 return; 432 433 priv_basicset(pset); 434 435 /* list of privileges for smbd */ 436 (void) priv_addset(pset, PRIV_NET_MAC_AWARE); 437 (void) priv_addset(pset, PRIV_NET_PRIVADDR); 438 (void) priv_addset(pset, PRIV_PROC_AUDIT); 439 (void) priv_addset(pset, PRIV_SYS_DEVICES); 440 (void) priv_addset(pset, PRIV_SYS_SMB); 441 (void) priv_addset(pset, PRIV_SYS_MOUNT); 442 443 priv_inverse(pset); 444 445 /* turn off unneeded privileges */ 446 (void) setppriv(PRIV_OFF, PRIV_EFFECTIVE, pset); 447 448 priv_freeset(pset); 449 450 /* reenable core dumps */ 451 __fini_daemon_priv(NULL); 452 } 453 454 /* 455 * smbd_service_init 456 */ 457 static int 458 smbd_service_init(void) 459 { 460 static struct dir { 461 char *name; 462 int perm; 463 } dir[] = { 464 { SMB_DBDIR, 0700 }, 465 { SMB_CVOL, 0755 }, 466 { SMB_SYSROOT, 0755 }, 467 { SMB_SYSTEM32, 0755 }, 468 { SMB_VSS, 0755 } 469 }; 470 int rc, i; 471 472 (void) mutex_lock(&smbd_service_mutex); 473 474 smbd.s_pid = getpid(); 475 for (i = 0; i < sizeof (dir)/sizeof (dir[0]); ++i) { 476 if ((mkdir(dir[i].name, dir[i].perm) < 0) && 477 (errno != EEXIST)) { 478 smbd_report("mkdir %s: %s", dir[i].name, 479 strerror(errno)); 480 (void) mutex_unlock(&smbd_service_mutex); 481 return (-1); 482 } 483 } 484 485 if ((rc = smb_ccache_init(SMB_VARRUN_DIR, SMB_CCACHE_FILE)) != 0) { 486 if (rc == -1) 487 smbd_report("mkdir %s: %s", SMB_VARRUN_DIR, 488 strerror(errno)); 489 else 490 smbd_report("unable to set KRB5CCNAME"); 491 (void) mutex_unlock(&smbd_service_mutex); 492 return (-1); 493 } 494 495 smbd.s_loghd = smb_log_create(SMBD_LOGSIZE, SMBD_LOGNAME); 496 smb_codepage_init(); 497 498 if (smbd_nicmon_start(SMBD_DEFAULT_INSTANCE_FMRI) != 0) 499 smbd_report("NIC monitor failed to start"); 500 501 (void) dyndns_start(); 502 smb_ipc_init(); 503 504 if (smb_netbios_start() != 0) 505 smbd_report("NetBIOS services failed to start"); 506 else 507 smbd_report("NetBIOS services started"); 508 509 smbd.s_secmode = smb_config_get_secmode(); 510 if ((rc = smb_domain_init(smbd.s_secmode)) != 0) { 511 if (rc == SMB_DOMAIN_NOMACHINE_SID) { 512 smbd_report( 513 "no machine SID: check idmap configuration"); 514 (void) mutex_unlock(&smbd_service_mutex); 515 return (-1); 516 } 517 } 518 519 smb_ads_init(); 520 if (mlsvc_init() != 0) { 521 smbd_report("msrpc initialization failed"); 522 (void) mutex_unlock(&smbd_service_mutex); 523 return (-1); 524 } 525 526 if (smbd.s_secmode == SMB_SECMODE_DOMAIN) 527 if (smbd_locate_dc_start() != 0) 528 smbd_report("dc discovery failed %s", strerror(errno)); 529 530 smbd.s_door_srv = smbd_door_start(); 531 smbd.s_door_opipe = smbd_opipe_start(); 532 if (smbd.s_door_srv < 0 || smbd.s_door_opipe < 0) { 533 smbd_report("door initialization failed %s", strerror(errno)); 534 (void) mutex_unlock(&smbd_service_mutex); 535 return (-1); 536 } 537 538 if (smbd_refresh_init() != 0) { 539 (void) mutex_unlock(&smbd_service_mutex); 540 return (-1); 541 } 542 543 dyndns_update_zones(); 544 (void) smbd_localtime_init(); 545 (void) smb_lgrp_start(); 546 smb_pwd_init(B_TRUE); 547 548 if (smb_shr_start() != 0) { 549 smbd_report("share initialization failed: %s", strerror(errno)); 550 (void) mutex_unlock(&smbd_service_mutex); 551 return (-1); 552 } 553 554 smbd.s_door_lmshr = smbd_share_start(); 555 if (smbd.s_door_lmshr < 0) 556 smbd_report("share initialization failed"); 557 558 if (smbd_kernel_bind() != 0) { 559 (void) mutex_unlock(&smbd_service_mutex); 560 return (-1); 561 } 562 563 if (smb_shr_load() != 0) { 564 smbd_report("failed to start loading shares: %s", 565 strerror(errno)); 566 (void) mutex_unlock(&smbd_service_mutex); 567 return (-1); 568 } 569 570 if (smbd_spool_init() != 0) { 571 smbd_report("failed to start print monitor: %s", 572 strerror(errno)); 573 (void) mutex_unlock(&smbd_service_mutex); 574 return (-1); 575 } 576 577 smbd.s_initialized = B_TRUE; 578 smbd_report("service initialized"); 579 (void) cond_signal(&smbd_service_cv); 580 (void) mutex_unlock(&smbd_service_mutex); 581 return (0); 582 } 583 584 /* 585 * Shutdown smbd and smbsrv kernel services. 586 * 587 * Shutdown will not begin until initialization has completed. 588 * Only one thread is allowed to perform the shutdown. Other 589 * threads will be blocked on fini_in_progress until the process 590 * has exited. 591 */ 592 static void 593 smbd_service_fini(void) 594 { 595 static uint_t fini_in_progress; 596 597 (void) mutex_lock(&smbd_service_mutex); 598 599 while (!smbd.s_initialized) 600 (void) cond_wait(&smbd_service_cv, &smbd_service_mutex); 601 602 if (atomic_swap_uint(&fini_in_progress, 1) != 0) { 603 while (fini_in_progress) 604 (void) cond_wait(&smbd_service_cv, &smbd_service_mutex); 605 /*NOTREACHED*/ 606 } 607 608 smbd.s_shutting_down = B_TRUE; 609 smbd_report("service shutting down"); 610 611 smb_kmod_stop(); 612 smb_logon_abort(); 613 smb_lgrp_stop(); 614 smbd_opipe_stop(); 615 smbd_door_stop(); 616 smbd_refresh_fini(); 617 smbd_kernel_unbind(); 618 smbd_share_stop(); 619 smb_shr_stop(); 620 dyndns_stop(); 621 smbd_nicmon_stop(); 622 smb_ccache_remove(SMB_CCACHE_PATH); 623 smb_pwd_fini(); 624 smb_domain_fini(); 625 mlsvc_fini(); 626 smb_ads_fini(); 627 smb_netbios_stop(); 628 629 smbd.s_initialized = B_FALSE; 630 smbd_report("service terminated"); 631 (void) mutex_unlock(&smbd_service_mutex); 632 exit((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK); 633 } 634 635 /* 636 * smbd_refresh_init() 637 * 638 * SMB service refresh thread initialization. This thread waits for a 639 * refresh event and updates the daemon's view of the configuration 640 * before going back to sleep. 641 */ 642 static int 643 smbd_refresh_init() 644 { 645 pthread_attr_t tattr; 646 pthread_condattr_t cattr; 647 int rc; 648 649 (void) pthread_condattr_init(&cattr); 650 (void) pthread_cond_init(&refresh_cond, &cattr); 651 (void) pthread_condattr_destroy(&cattr); 652 653 (void) pthread_mutex_init(&refresh_mutex, NULL); 654 655 (void) pthread_attr_init(&tattr); 656 (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 657 rc = pthread_create(&refresh_thr, &tattr, smbd_refresh_monitor, 0); 658 (void) pthread_attr_destroy(&tattr); 659 660 return (rc); 661 } 662 663 /* 664 * smbd_refresh_fini() 665 * 666 * Stop the refresh thread. 667 */ 668 static void 669 smbd_refresh_fini() 670 { 671 if (pthread_self() != refresh_thr) { 672 (void) pthread_cancel(refresh_thr); 673 (void) pthread_cond_destroy(&refresh_cond); 674 (void) pthread_mutex_destroy(&refresh_mutex); 675 } 676 } 677 678 /* 679 * smbd_refresh_monitor() 680 * 681 * Wait for a refresh event. When this thread wakes up, update the 682 * smbd configuration from the SMF config information then go back to 683 * wait for the next refresh. 684 */ 685 /*ARGSUSED*/ 686 static void * 687 smbd_refresh_monitor(void *arg) 688 { 689 smb_kmod_cfg_t cfg; 690 int error; 691 692 while (!smbd.s_shutting_down) { 693 (void) pthread_mutex_lock(&refresh_mutex); 694 while ((atomic_swap_uint(&smbd.s_refreshes, 0) == 0) && 695 (!smbd.s_shutting_down)) 696 (void) pthread_cond_wait(&refresh_cond, &refresh_mutex); 697 (void) pthread_mutex_unlock(&refresh_mutex); 698 699 if (smbd.s_shutting_down) { 700 smbd_service_fini(); 701 /*NOTREACHED*/ 702 } 703 704 (void) mutex_lock(&smbd_service_mutex); 705 706 /* 707 * We've been woken up by a refresh event so go do 708 * what is necessary. 709 */ 710 smb_ads_refresh(); 711 smb_ccache_remove(SMB_CCACHE_PATH); 712 713 /* 714 * Start the dyndns thread, if required. 715 * Clear the DNS zones for the existing interfaces 716 * before updating the NIC interface list. 717 */ 718 (void) dyndns_start(); 719 dyndns_clear_zones(); 720 721 if (smbd_nicmon_refresh() != 0) 722 smbd_report("NIC monitor refresh failed"); 723 smb_netbios_name_reconfig(); 724 smb_browser_reconfig(); 725 smbd_refresh_dc(); 726 dyndns_update_zones(); 727 728 (void) mutex_unlock(&smbd_service_mutex); 729 730 if (smbd_set_netlogon_cred()) { 731 /* 732 * Restart required because the domain changed 733 * or the credential chain setup failed. 734 */ 735 if (smb_smf_restart_service() != 0) { 736 syslog(LOG_ERR, 737 "unable to restart smb/server. " 738 "Run 'svcs -xv smb/server' for more " 739 "information."); 740 smbd_service_fini(); 741 /*NOTREACHED*/ 742 } 743 744 break; 745 } 746 747 if (!smbd.s_kbound) { 748 if ((error = smbd_kernel_bind()) == 0) 749 (void) smb_shr_load(); 750 751 continue; 752 } 753 754 (void) smb_shr_load(); 755 756 smb_load_kconfig(&cfg); 757 error = smb_kmod_setcfg(&cfg); 758 if (error < 0) 759 smbd_report("configuration update failed: %s", 760 strerror(error)); 761 } 762 763 return (NULL); 764 } 765 766 /* 767 * Update DC information on a refresh. 768 */ 769 static void 770 smbd_refresh_dc(void) 771 { 772 char fqdomain[MAXHOSTNAMELEN]; 773 if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 774 return; 775 776 if (smb_getfqdomainname(fqdomain, MAXHOSTNAMELEN)) 777 return; 778 779 if (!smb_locate_dc(fqdomain, "", NULL)) 780 smbd_report("DC refresh failed"); 781 } 782 783 void 784 smbd_set_secmode(int secmode) 785 { 786 switch (secmode) { 787 case SMB_SECMODE_WORKGRP: 788 case SMB_SECMODE_DOMAIN: 789 (void) smb_config_set_secmode(secmode); 790 smbd.s_secmode = secmode; 791 break; 792 793 default: 794 syslog(LOG_ERR, "invalid security mode: %d", secmode); 795 syslog(LOG_ERR, "entering maintenance mode"); 796 (void) smb_smf_maintenance_mode(); 797 } 798 } 799 800 /* 801 * The service is online if initialization is complete and shutdown 802 * has not begun. 803 */ 804 boolean_t 805 smbd_online(void) 806 { 807 return (smbd.s_initialized && !smbd.s_shutting_down); 808 } 809 810 /* 811 * If the door has already been opened by another process (non-zero pid 812 * in target), we assume that another smbd is already running. If there 813 * is a race here, it will be caught later when smbsrv is opened because 814 * only one process is allowed to open the device at a time. 815 */ 816 static int 817 smbd_already_running(void) 818 { 819 door_info_t info; 820 int door; 821 822 if ((door = open(SMBD_DOOR_NAME, O_RDONLY)) < 0) 823 return (0); 824 825 if (door_info(door, &info) < 0) 826 return (0); 827 828 if (info.di_target > 0) { 829 smbd_report("already running: pid %ld\n", info.di_target); 830 (void) close(door); 831 return (1); 832 } 833 834 (void) close(door); 835 return (0); 836 } 837 838 /* 839 * smbd_kernel_bind 840 * 841 * This function open the smbsrv device and start the kernel service. 842 */ 843 static int 844 smbd_kernel_bind(void) 845 { 846 int rc; 847 848 smbd_kernel_unbind(); 849 850 if ((rc = smb_kmod_bind()) == 0) { 851 rc = smbd_kernel_start(); 852 if (rc != 0) 853 smb_kmod_unbind(); 854 else 855 smbd.s_kbound = B_TRUE; 856 } 857 858 if (rc != 0) 859 smbd_report("kernel bind error: %s", strerror(errno)); 860 return (rc); 861 } 862 863 static int 864 smbd_kernel_start(void) 865 { 866 smb_kmod_cfg_t cfg; 867 int rc; 868 869 smb_load_kconfig(&cfg); 870 rc = smb_kmod_setcfg(&cfg); 871 if (rc != 0) 872 return (rc); 873 874 rc = smb_kmod_setgmtoff(smbd_gmtoff()); 875 if (rc != 0) 876 return (rc); 877 878 rc = smb_kmod_start(smbd.s_door_opipe, smbd.s_door_lmshr, 879 smbd.s_door_srv); 880 if (rc != 0) 881 return (rc); 882 883 rc = smbd_start_listeners(); 884 if (rc != 0) 885 return (rc); 886 887 return (0); 888 } 889 890 /* 891 * smbd_kernel_unbind 892 */ 893 static void 894 smbd_kernel_unbind(void) 895 { 896 smbd_stop_listeners(); 897 smb_kmod_unbind(); 898 smbd.s_kbound = B_FALSE; 899 } 900 901 /* 902 * Initialization of the spool thread. 903 * Returns 0 on success, an error number if thread creation fails. 904 */ 905 906 static int 907 smbd_spool_init(void) 908 { 909 pthread_attr_t tattr; 910 int rc; 911 912 (void) pthread_attr_init(&tattr); 913 (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 914 rc = pthread_create(&smbd_spool_thr, &tattr, smbd_spool_monitor, 0); 915 (void) pthread_attr_destroy(&tattr); 916 917 return (rc); 918 } 919 920 /* 921 * This user thread blocks waiting for close print file 922 * in the kernel. It then uses the data returned from the ioctl 923 * to copy the spool file into the cups spooler. 924 * This function is really only used by Vista and Win7 clients, 925 * other versions of windows create only a zero size file and this 926 * be removed by spoolss_copy_spool_file function. 927 */ 928 929 /*ARGSUSED*/ 930 static void * 931 smbd_spool_monitor(void *arg) 932 { 933 uint32_t spool_num; 934 char username[MAXNAMELEN]; 935 char path[MAXPATHLEN]; 936 smb_inaddr_t ipaddr; 937 int error_retry_cnt = 5; 938 939 while (!smbd.s_shutting_down && (error_retry_cnt > 0)) { 940 errno = 0; 941 942 if (smb_kmod_get_spool_doc(&spool_num, username, 943 path, &ipaddr) == 0) { 944 spoolss_copy_spool_file(&ipaddr, 945 username, path, SMB_CUPS_DOCNAME); 946 error_retry_cnt = 5; 947 } else { 948 if (errno == ECANCELED) 949 break; 950 951 (void) sleep(SMB_SPOOL_WAIT); 952 error_retry_cnt--; 953 } 954 } 955 return (NULL); 956 } 957 958 /* 959 * Initialization of the localtime thread. 960 * Returns 0 on success, an error number if thread creation fails. 961 */ 962 963 int 964 smbd_localtime_init(void) 965 { 966 pthread_attr_t tattr; 967 int rc; 968 969 (void) pthread_attr_init(&tattr); 970 (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 971 rc = pthread_create(&localtime_thr, &tattr, smbd_localtime_monitor, 0); 972 (void) pthread_attr_destroy(&tattr); 973 return (rc); 974 } 975 976 /* 977 * Local time thread to kernel land. 978 * Send local gmtoff to kernel module one time at startup 979 * and each time it changes (up to twice a year). 980 * Local gmtoff is checked once every 15 minutes and 981 * since some timezones are aligned on half and qtr hour boundaries, 982 * once an hour would likely suffice. 983 */ 984 985 /*ARGSUSED*/ 986 static void * 987 smbd_localtime_monitor(void *arg) 988 { 989 struct tm local_tm; 990 time_t secs; 991 int32_t gmtoff, last_gmtoff = -1; 992 int timeout; 993 int error; 994 995 for (;;) { 996 gmtoff = smbd_gmtoff(); 997 998 if ((last_gmtoff != gmtoff) && smbd.s_kbound) { 999 error = smb_kmod_setgmtoff(gmtoff); 1000 if (error != 0) 1001 smbd_report("localtime set failed: %s", 1002 strerror(error)); 1003 } 1004 1005 /* 1006 * Align the next iteration on a fifteen minute boundary. 1007 */ 1008 secs = time(0); 1009 (void) localtime_r(&secs, &local_tm); 1010 timeout = ((15 - (local_tm.tm_min % 15)) * SECSPERMIN); 1011 (void) sleep(timeout); 1012 1013 last_gmtoff = gmtoff; 1014 } 1015 1016 /*NOTREACHED*/ 1017 return (NULL); 1018 } 1019 1020 /* 1021 * smbd_gmtoff 1022 * 1023 * Determine offset from GMT. If daylight saving time use altzone, 1024 * otherwise use timezone. 1025 */ 1026 static int32_t 1027 smbd_gmtoff(void) 1028 { 1029 time_t clock_val; 1030 struct tm *atm; 1031 int32_t gmtoff; 1032 1033 (void) time(&clock_val); 1034 atm = localtime(&clock_val); 1035 1036 gmtoff = (atm->tm_isdst) ? altzone : timezone; 1037 1038 return (gmtoff); 1039 } 1040 1041 static void 1042 smbd_sig_handler(int sigval) 1043 { 1044 if (smbd.s_sigval == 0) 1045 (void) atomic_swap_uint(&smbd.s_sigval, sigval); 1046 1047 if (sigval == SIGHUP) { 1048 atomic_inc_uint(&smbd.s_refreshes); 1049 (void) pthread_cond_signal(&refresh_cond); 1050 } 1051 1052 if (sigval == SIGINT || sigval == SIGTERM) { 1053 smbd.s_shutting_down = B_TRUE; 1054 (void) pthread_cond_signal(&refresh_cond); 1055 } 1056 } 1057 1058 /* 1059 * Set up configuration options and parse the command line. 1060 * This function will determine if we will run as a daemon 1061 * or in the foreground. 1062 * 1063 * Failure to find a uid or gid results in using the default (0). 1064 */ 1065 static int 1066 smbd_setup_options(int argc, char *argv[]) 1067 { 1068 struct passwd *pwd; 1069 struct group *grp; 1070 int c; 1071 1072 if ((pwd = getpwnam("root")) != NULL) 1073 smbd.s_uid = pwd->pw_uid; 1074 1075 if ((grp = getgrnam("sys")) != NULL) 1076 smbd.s_gid = grp->gr_gid; 1077 1078 smbd.s_fg = smb_config_get_fg_flag(); 1079 1080 while ((c = getopt(argc, argv, ":f")) != -1) { 1081 switch (c) { 1082 case 'f': 1083 smbd.s_fg = 1; 1084 break; 1085 1086 case ':': 1087 case '?': 1088 default: 1089 smbd_usage(stderr); 1090 return (-1); 1091 } 1092 } 1093 1094 return (0); 1095 } 1096 1097 static void 1098 smbd_usage(FILE *fp) 1099 { 1100 static char *help[] = { 1101 "-f run program in foreground" 1102 }; 1103 1104 int i; 1105 1106 (void) fprintf(fp, "Usage: %s [-f]\n", smbd.s_pname); 1107 1108 for (i = 0; i < sizeof (help)/sizeof (help[0]); ++i) 1109 (void) fprintf(fp, " %s\n", help[i]); 1110 } 1111 1112 static void 1113 smbd_report(const char *fmt, ...) 1114 { 1115 char buf[128]; 1116 va_list ap; 1117 1118 if (fmt == NULL) 1119 return; 1120 1121 va_start(ap, fmt); 1122 (void) vsnprintf(buf, 128, fmt, ap); 1123 va_end(ap); 1124 1125 (void) fprintf(stderr, "smbd: %s\n", buf); 1126 } 1127 1128 static int 1129 smbd_start_listeners(void) 1130 { 1131 int rc1; 1132 int rc2; 1133 pthread_attr_t tattr; 1134 1135 (void) pthread_attr_init(&tattr); 1136 1137 if (!smbd.s_nbt_listener_running) { 1138 rc1 = pthread_create(&smbd.s_nbt_listener_id, &tattr, 1139 smbd_nbt_listener, NULL); 1140 if (rc1 != 0) 1141 smbd_report("unable to start NBT service"); 1142 else 1143 smbd.s_nbt_listener_running = B_TRUE; 1144 } 1145 1146 if (!smbd.s_tcp_listener_running) { 1147 rc2 = pthread_create(&smbd.s_tcp_listener_id, &tattr, 1148 smbd_tcp_listener, NULL); 1149 if (rc2 != 0) 1150 smbd_report("unable to start TCP service"); 1151 else 1152 smbd.s_tcp_listener_running = B_TRUE; 1153 } 1154 1155 (void) pthread_attr_destroy(&tattr); 1156 1157 if (rc1 != 0) 1158 return (rc1); 1159 return (rc2); 1160 } 1161 1162 /* 1163 * Stop the listener threads. In an attempt to ensure that the listener 1164 * threads get the signal, we use the timed wait loop to harass the 1165 * threads into terminating. Then, if they are still running, we make 1166 * one final attempt to deliver the signal before calling thread join 1167 * to wait for them. Note: if these threads don't terminate, smbd will 1168 * hang here and SMF will probably end up killing the contract. 1169 */ 1170 static void 1171 smbd_stop_listeners(void) 1172 { 1173 void *status; 1174 timestruc_t delay; 1175 int rc = 0; 1176 1177 (void) mutex_lock(&listener_mutex); 1178 1179 while ((smbd.s_nbt_listener_running || smbd.s_tcp_listener_running) && 1180 (rc != ETIME)) { 1181 if (smbd.s_nbt_listener_running) 1182 (void) pthread_kill(smbd.s_nbt_listener_id, SIGTERM); 1183 1184 if (smbd.s_tcp_listener_running) 1185 (void) pthread_kill(smbd.s_tcp_listener_id, SIGTERM); 1186 1187 delay.tv_sec = 3; 1188 delay.tv_nsec = 0; 1189 rc = cond_reltimedwait(&listener_cv, &listener_mutex, &delay); 1190 } 1191 1192 (void) mutex_unlock(&listener_mutex); 1193 1194 if (smbd.s_nbt_listener_running) { 1195 syslog(LOG_WARNING, "NBT listener still running"); 1196 (void) pthread_kill(smbd.s_nbt_listener_id, SIGTERM); 1197 (void) pthread_join(smbd.s_nbt_listener_id, &status); 1198 smbd.s_nbt_listener_running = B_FALSE; 1199 } 1200 1201 if (smbd.s_tcp_listener_running) { 1202 syslog(LOG_WARNING, "TCP listener still running"); 1203 (void) pthread_kill(smbd.s_tcp_listener_id, SIGTERM); 1204 (void) pthread_join(smbd.s_tcp_listener_id, &status); 1205 smbd.s_tcp_listener_running = B_FALSE; 1206 } 1207 } 1208 1209 /* 1210 * Perform fatal error exit. 1211 */ 1212 static void 1213 smbd_fatal_error(const char *msg) 1214 { 1215 if (msg == NULL) 1216 msg = "Fatal error"; 1217 1218 smbd_report("%s", msg); 1219 smbd.s_fatal_error = B_TRUE; 1220 (void) kill(smbd.s_pid, SIGTERM); 1221 } 1222 1223 /*ARGSUSED*/ 1224 static void * 1225 smbd_nbt_receiver(void *arg) 1226 { 1227 (void) smb_kmod_nbtreceive(); 1228 return (NULL); 1229 } 1230 1231 /*ARGSUSED*/ 1232 static void * 1233 smbd_nbt_listener(void *arg) 1234 { 1235 pthread_attr_t tattr; 1236 sigset_t set; 1237 sigset_t oset; 1238 pthread_t tid; 1239 int error = 0; 1240 1241 (void) sigfillset(&set); 1242 (void) sigdelset(&set, SIGTERM); 1243 (void) sigdelset(&set, SIGINT); 1244 (void) pthread_sigmask(SIG_SETMASK, &set, &oset); 1245 (void) pthread_attr_init(&tattr); 1246 (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 1247 1248 while (smb_kmod_nbtlisten(error) == 0) 1249 error = pthread_create(&tid, &tattr, smbd_nbt_receiver, NULL); 1250 1251 (void) pthread_attr_destroy(&tattr); 1252 1253 if (!smbd.s_shutting_down) 1254 smbd_fatal_error("NBT listener thread terminated unexpectedly"); 1255 1256 (void) mutex_lock(&listener_mutex); 1257 smbd.s_nbt_listener_running = B_FALSE; 1258 (void) cond_broadcast(&listener_cv); 1259 (void) mutex_unlock(&listener_mutex); 1260 return (NULL); 1261 } 1262 1263 /*ARGSUSED*/ 1264 static void * 1265 smbd_tcp_receiver(void *arg) 1266 { 1267 (void) smb_kmod_tcpreceive(); 1268 return (NULL); 1269 } 1270 1271 /*ARGSUSED*/ 1272 static void * 1273 smbd_tcp_listener(void *arg) 1274 { 1275 pthread_attr_t tattr; 1276 sigset_t set; 1277 sigset_t oset; 1278 pthread_t tid; 1279 int error = 0; 1280 1281 (void) sigfillset(&set); 1282 (void) sigdelset(&set, SIGTERM); 1283 (void) sigdelset(&set, SIGINT); 1284 (void) pthread_sigmask(SIG_SETMASK, &set, &oset); 1285 (void) pthread_attr_init(&tattr); 1286 (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 1287 1288 while (smb_kmod_tcplisten(error) == 0) 1289 error = pthread_create(&tid, &tattr, smbd_tcp_receiver, NULL); 1290 1291 (void) pthread_attr_destroy(&tattr); 1292 1293 if (!smbd.s_shutting_down) 1294 smbd_fatal_error("TCP listener thread terminated unexpectedly"); 1295 1296 (void) mutex_lock(&listener_mutex); 1297 smbd.s_tcp_listener_running = B_FALSE; 1298 (void) cond_broadcast(&listener_cv); 1299 (void) mutex_unlock(&listener_mutex); 1300 return (NULL); 1301 } 1302 1303 /* 1304 * Enable libumem debugging by default on DEBUG builds. 1305 */ 1306 #ifdef DEBUG 1307 const char * 1308 _umem_debug_init(void) 1309 { 1310 return ("default,verbose"); /* $UMEM_DEBUG setting */ 1311 } 1312 1313 const char * 1314 _umem_logging_init(void) 1315 { 1316 return ("fail,contents"); /* $UMEM_LOGGING setting */ 1317 } 1318 #endif 1319