/*ARGSUSED*/ static void * smbd_share_printers(void *arg) { cups_dest_t *dests; cups_dest_t *dest; smb_cups_ops_t *cups; smb_share_t si; uint32_t nerr; int num_dests; int i; if (!smb_config_getbool(SMB_CI_PRINT_ENABLE)) return (NULL); if ((cups = smbd_cups_ops()) == NULL) return (NULL); if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) { syslog(LOG_DEBUG, "smbd_share_printers unable to load %s", SMB_SHARE_PRINT); return (NULL); } num_dests = cups->cupsGetDests(&dests); for (i = num_dests, dest = dests; i > 0; i--, dest++) { if (dest->instance != NULL) continue; (void) strlcpy(si.shr_name, dest->name, MAXPATHLEN); smbd_print_share_comment(&si, dest); si.shr_type = STYPE_PRINTQ; nerr = smb_shr_add(&si); if (nerr == NERR_Success || nerr == NERR_DuplicateShare) syslog(LOG_DEBUG, "shared printer: %s", si.shr_name); else syslog(LOG_DEBUG, "smbd_share_printers: unable to add share %s: %u", si.shr_name, nerr); } cups->cupsFreeDests(num_dests, dests); return (NULL); }
/* * Start the spool thread. * Returns 0 on success, an error number if thread creation fails. */ void smbd_spool_start(void) { pthread_attr_t attr; int rc; if (!smb_config_getbool(SMB_CI_PRINT_ENABLE)) return; (void) pthread_attr_init(&attr); (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); rc = pthread_create(&smbd.s_spool_tid, &attr, smbd_spool_monitor, NULL); (void) pthread_attr_destroy(&attr); if (rc != 0) syslog(LOG_NOTICE, "failed to start print monitor: %s", strerror(errno)); }
void smbd_load_printers(void) { pthread_t tid; pthread_attr_t attr; int rc; if (!smb_config_getbool(SMB_CI_PRINT_ENABLE)) return; (void) pthread_attr_init(&attr); (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); rc = pthread_create(&tid, &attr, smbd_share_printers, &tid); (void) pthread_attr_destroy(&attr); if (rc != 0) syslog(LOG_NOTICE, "unable to load printer shares: %s", strerror(errno)); }
/* * smbd_service_init */ static int smbd_service_init(void) { static struct dir { char *name; int perm; } dir[] = { { SMB_DBDIR, 0700 }, { SMB_CVOL, 0755 }, { SMB_SYSROOT, 0755 }, { SMB_SYSTEM32, 0755 }, { SMB_VSS, 0755 } }; int rc, i; (void) mutex_lock(&smbd_service_mutex); smbd.s_pid = getpid(); for (i = 0; i < sizeof (dir)/sizeof (dir[0]); ++i) { if ((mkdir(dir[i].name, dir[i].perm) < 0) && (errno != EEXIST)) { smbd_report("mkdir %s: %s", dir[i].name, strerror(errno)); (void) mutex_unlock(&smbd_service_mutex); return (-1); } } if ((rc = smb_ccache_init(SMB_VARRUN_DIR, SMB_CCACHE_FILE)) != 0) { if (rc == -1) smbd_report("mkdir %s: %s", SMB_VARRUN_DIR, strerror(errno)); else smbd_report("unable to set KRB5CCNAME"); (void) mutex_unlock(&smbd_service_mutex); return (-1); } smbd.s_loghd = smb_log_create(SMBD_LOGSIZE, SMBD_LOGNAME); smb_codepage_init(); rc = smbd_cups_init(); if (smb_config_getbool(SMB_CI_PRINT_ENABLE)) smbd_report("print service %savailable", (rc == 0) ? "" : "un"); if (smbd_nicmon_start(SMBD_DEFAULT_INSTANCE_FMRI) != 0) smbd_report("NIC monitor failed to start"); smbd_dyndns_init(); smb_ipc_init(); if (smb_netbios_start() != 0) smbd_report("NetBIOS services failed to start"); else smbd_report("NetBIOS services started"); smbd.s_secmode = smb_config_get_secmode(); if ((rc = smb_domain_init(smbd.s_secmode)) != 0) { if (rc == SMB_DOMAIN_NOMACHINE_SID) { smbd_report( "no machine SID: check idmap configuration"); (void) mutex_unlock(&smbd_service_mutex); return (-1); } } if (smbd_dc_monitor_init() != 0) smbd_report("DC monitor initialization failed %s", strerror(errno)); if (mlsvc_init() != 0) { smbd_report("msrpc initialization failed"); (void) mutex_unlock(&smbd_service_mutex); return (-1); } smbd.s_door_srv = smbd_door_start(); smbd.s_door_opipe = smbd_opipe_start(); if (smbd.s_door_srv < 0 || smbd.s_door_opipe < 0) { smbd_report("door initialization failed %s", strerror(errno)); (void) mutex_unlock(&smbd_service_mutex); return (-1); } if (smbd_refresh_init() != 0) { (void) mutex_unlock(&smbd_service_mutex); return (-1); } dyndns_update_zones(); smbd_localtime_init(); (void) smb_lgrp_start(); smb_pwd_init(B_TRUE); if (smb_shr_start() != 0) { smbd_report("share initialization failed: %s", strerror(errno)); (void) mutex_unlock(&smbd_service_mutex); return (-1); } smbd.s_door_lmshr = smbd_share_start(); if (smbd.s_door_lmshr < 0) smbd_report("share initialization failed"); if (smbd_kernel_bind() != 0) { (void) mutex_unlock(&smbd_service_mutex); return (-1); } smbd_load_shares(); smbd_load_printers(); smbd.s_initialized = B_TRUE; smbd_report("service initialized"); (void) cond_signal(&smbd_service_cv); (void) mutex_unlock(&smbd_service_mutex); return (0); }
/* * Some older clients (Windows 98) only handle the low byte * of the max workers value. If the low byte is less than * SMB_PI_MAX_WORKERS_MIN set it to SMB_PI_MAX_WORKERS_MIN. */ void smb_load_kconfig(smb_kmod_cfg_t *kcfg) { struct utsname uts; int64_t citem; int rc; bzero(kcfg, sizeof (smb_kmod_cfg_t)); (void) smb_config_getnum(SMB_CI_MAX_WORKERS, &citem); kcfg->skc_maxworkers = (uint32_t)citem; if ((kcfg->skc_maxworkers & 0xFF) < SMB_PI_MAX_WORKERS_MIN) { kcfg->skc_maxworkers &= ~0xFF; kcfg->skc_maxworkers += SMB_PI_MAX_WORKERS_MIN; } (void) smb_config_getnum(SMB_CI_KEEPALIVE, &citem); kcfg->skc_keepalive = (uint32_t)citem; if ((kcfg->skc_keepalive != 0) && (kcfg->skc_keepalive < SMB_PI_KEEP_ALIVE_MIN)) kcfg->skc_keepalive = SMB_PI_KEEP_ALIVE_MIN; (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &citem); kcfg->skc_maxconnections = (uint32_t)citem; kcfg->skc_restrict_anon = smb_config_getbool(SMB_CI_RESTRICT_ANON); kcfg->skc_signing_enable = smb_config_getbool(SMB_CI_SIGNING_ENABLE); kcfg->skc_signing_required = smb_config_getbool(SMB_CI_SIGNING_REQD); kcfg->skc_netbios_enable = smb_config_getbool(SMB_CI_NETBIOS_ENABLE); kcfg->skc_ipv6_enable = smb_config_getbool(SMB_CI_IPV6_ENABLE); kcfg->skc_print_enable = smb_config_getbool(SMB_CI_PRINT_ENABLE); kcfg->skc_oplock_enable = smb_config_getbool(SMB_CI_OPLOCK_ENABLE); kcfg->skc_sync_enable = smb_config_getbool(SMB_CI_SYNC_ENABLE); kcfg->skc_traverse_mounts = smb_config_getbool(SMB_CI_TRAVERSE_MOUNTS); kcfg->skc_max_protocol = smb_config_get_max_protocol(); kcfg->skc_secmode = smb_config_get_secmode(); rc = smb_config_getnum(SMB_CI_MAXIMUM_CREDITS, &citem); if (rc != SMBD_SMF_OK) citem = SMB_PI_MAX_CREDITS; if (citem < SMB_PI_MIN_CREDITS) citem = SMB_PI_MIN_CREDITS; if (citem > SMB_PI_MAX_CREDITS) citem = SMB_PI_MAX_CREDITS; kcfg->skc_maximum_credits = (uint16_t)citem; rc = smb_config_getnum(SMB_CI_INITIAL_CREDITS, &citem); if (rc != SMBD_SMF_OK) citem = SMB_PI_MIN_CREDITS; if (citem < SMB_PI_MIN_CREDITS) citem = SMB_PI_MIN_CREDITS; if (citem > kcfg->skc_maximum_credits) citem = kcfg->skc_maximum_credits; kcfg->skc_initial_credits = (uint16_t)citem; (void) smb_getdomainname(kcfg->skc_nbdomain, sizeof (kcfg->skc_nbdomain)); (void) smb_getfqdomainname(kcfg->skc_fqdn, sizeof (kcfg->skc_fqdn)); (void) smb_getnetbiosname(kcfg->skc_hostname, sizeof (kcfg->skc_hostname)); (void) smb_config_getstr(SMB_CI_SYS_CMNT, kcfg->skc_system_comment, sizeof (kcfg->skc_system_comment)); smb_config_get_version(&kcfg->skc_version); kcfg->skc_execflags = smb_config_get_execinfo(NULL, NULL, 0); if (smb_config_get_localuuid(kcfg->skc_machine_uuid) < 0) { syslog(LOG_ERR, "smb_load_kconfig: no machine_uuid"); uuid_generate_time(kcfg->skc_machine_uuid); } /* skc_negtok, skc_negtok_len: see smbd_authsvc.c */ (void) uname(&uts); (void) snprintf(kcfg->skc_native_os, sizeof (kcfg->skc_native_os), "%s %s %s", uts.sysname, uts.release, uts.version); (void) strlcpy(kcfg->skc_native_lm, "Native SMB service", sizeof (kcfg->skc_native_lm)); }
/* * smbd_service_init */ static int smbd_service_init(void) { static struct dir { char *name; int perm; } dir[] = { { SMB_DBDIR, 0700 }, { SMB_CVOL, 0755 }, { SMB_SYSROOT, 0755 }, { SMB_SYSTEM32, 0755 }, { SMB_VSS, 0755 }, { SMB_PIPE_DIR, 0755 }, }; int rc, i; smbd.s_pid = getpid(); /* * Stop for a debugger attach here, which is after the * fork() etc. in smb_daemonize_init() */ if (smbd.s_dbg_stop) { smbd_report("pid %d stop for debugger attach", smbd.s_pid); (void) kill(smbd.s_pid, SIGSTOP); } smbd_report("smbd starting, pid %d", smbd.s_pid); for (i = 0; i < sizeof (dir)/sizeof (dir[0]); ++i) { if ((mkdir(dir[i].name, dir[i].perm) < 0) && (errno != EEXIST)) { smbd_report("mkdir %s: %s", dir[i].name, strerror(errno)); return (-1); } } if ((rc = smb_ccache_init(SMB_VARRUN_DIR, SMB_CCACHE_FILE)) != 0) { if (rc == -1) smbd_report("mkdir %s: %s", SMB_VARRUN_DIR, strerror(errno)); else smbd_report("unable to set KRB5CCNAME"); return (-1); } smb_codepage_init(); rc = smbd_cups_init(); if (smb_config_getbool(SMB_CI_PRINT_ENABLE)) smbd_report("print service %savailable", (rc == 0) ? "" : "un"); if (smbd_nicmon_start(SMBD_DEFAULT_INSTANCE_FMRI) != 0) smbd_report("NIC monitor failed to start"); smbd_dyndns_init(); smb_ipc_init(); if (smb_config_getbool(SMB_CI_NETBIOS_ENABLE) == 0) smbd_report("NetBIOS services disabled"); else if (smb_netbios_start() != 0) smbd_report("NetBIOS services failed to start"); else smbd_report("NetBIOS services started"); smbd.s_secmode = smb_config_get_secmode(); if ((rc = smb_domain_init(smbd.s_secmode)) != 0) { if (rc == SMB_DOMAIN_NOMACHINE_SID) { smbd_report( "no machine SID: check idmap configuration"); return (-1); } } if (smbd_dc_monitor_init() != 0) smbd_report("DC monitor initialization failed %s", strerror(errno)); if (smbd_pipesvc_start() != 0) { smbd_report("pipesvc initialization failed"); return (-1); } smbd.s_door_srv = smbd_door_start(); if (smbd.s_door_srv < 0) { smbd_report("door initialization failed %s", strerror(errno)); return (-1); } dyndns_update_zones(); smbd_localtime_init(); (void) smb_lgrp_start(); smb_pwd_init(B_TRUE); if (smb_shr_start() != 0) { smbd_report("share initialization failed: %s", strerror(errno)); return (-1); } smbd.s_door_lmshr = smbd_share_start(); if (smbd.s_door_lmshr < 0) smbd_report("share initialization failed"); /* Open the driver, load the kernel config. */ if (smbd_kernel_bind() != 0) { return (-1); } smbd_load_shares(); smbd_load_printers(); smbd_spool_start(); smbd.s_initialized = B_TRUE; smbd_report("service initialized"); return (0); }