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