Пример #1
0
/*
 * If the domain to be discovered matches the current domain (i.e the
 * value of either domain or fqdn configuration), then get the primary
 * domain information from SMF.
 */
static uint32_t
smb_ddiscover_use_config(char *domain, smb_domainex_t *dxi)
{
	boolean_t use;
	smb_domain_t *dinfo;

	dinfo = &dxi->d_primary;
	bzero(dinfo, sizeof (smb_domain_t));

	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
		return (NT_STATUS_UNSUCCESSFUL);

	smb_config_getdomaininfo(dinfo->di_nbname, dinfo->di_fqname,
	    NULL, NULL, NULL);

	if (SMB_IS_FQDN(domain))
		use = (smb_strcasecmp(dinfo->di_fqname, domain, 0) == 0);
	else
		use = (smb_strcasecmp(dinfo->di_nbname, domain, 0) == 0);

	if (use)
		smb_config_getdomaininfo(NULL, NULL, dinfo->di_sid,
		    dinfo->di_u.di_dns.ddi_forest,
		    dinfo->di_u.di_dns.ddi_guid);

	return ((use) ? NT_STATUS_SUCCESS : NT_STATUS_UNSUCCESSFUL);
}
Пример #2
0
/*
 * smb_getfqdomainname
 *
 * In the system is in domain mode, the dns_domain property value
 * is returned. Otherwise, it returns the local domain obtained via
 * resolver.
 *
 * Returns 0 upon success.  Otherwise, returns -1.
 */
int
smb_getfqdomainname(char *buf, size_t buflen)
{
	struct __res_state res_state;
	int rc;

	if (buf == NULL || buflen == 0)
		return (-1);

	*buf = '\0';
	if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
		rc = smb_config_getstr(SMB_CI_DOMAIN_FQDN, buf, buflen);

		if ((rc != SMBD_SMF_OK) || (*buf == '\0'))
			return (-1);
	} else {
		bzero(&res_state, sizeof (struct __res_state));
		if (res_ninit(&res_state))
			return (-1);

		if (*res_state.defdname == '\0') {
			res_ndestroy(&res_state);
			return (-1);
		}

		(void) strlcpy(buf, res_state.defdname, buflen);
		res_ndestroy(&res_state);
		rc = 0;
	}

	return (rc);
}
Пример #3
0
/*
 * lsarpc_s_PrimaryDomainInfo
 *
 * Service primary domain policy queries.  In domain mode, return the
 * primary domain name and SID.   In workgroup mode, return the local
 * hostname and local domain SID.
 *
 * Note: info is zeroed on entry to ensure the SID and name do not
 * contain spurious values if an error is returned.
 */
static DWORD
lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info,
    ndr_xa_t *mxa)
{
	smb_domain_t di;
	boolean_t found;
	int rc;

	bzero(info, sizeof (struct mslsa_PrimaryDomainInfo));

	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
		found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di);
	else
		found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di);

	if (!found)
		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);

	rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
	info->sid = (struct mslsa_sid *)NDR_SIDDUP(mxa, di.di_binsid);

	if ((rc == -1) || (info->sid == NULL))
		return (NT_STATUS_NO_MEMORY);

	return (NT_STATUS_SUCCESS);
}
Пример #4
0
/*
 * lsarpc_s_QueryInfoPolicy
 *
 * This is the server side function for handling LSA information policy
 * queries. Currently, we only support primary domain and account
 * domain queries. This is just a front end to switch on the request
 * and hand it off to the appropriate function to actually deal with
 * obtaining and building the response.
 */
static int
lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_QueryInfoPolicy *param = arg;
	union mslsa_PolicyInfoResUnion *ru = &param->ru;
	int security_mode;
	DWORD status;

	param->switch_value = param->info_class;

	switch (param->info_class) {
	case MSLSA_POLICY_AUDIT_EVENTS_INFO:
		ru->audit_events.enabled = 0;
		ru->audit_events.count = 1;
		ru->audit_events.settings
		    = NDR_MALLOC(mxa, sizeof (DWORD));
		bzero(ru->audit_events.settings, sizeof (DWORD));
		status = NT_STATUS_SUCCESS;
		break;

	case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
		status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa);
		break;

	case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
		status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa);
		break;

	case MSLSA_POLICY_SERVER_ROLE_INFO:
		security_mode = smb_config_get_secmode();

		if (security_mode == SMB_SECMODE_DOMAIN)
			ru->server_role.role = LSA_ROLE_MEMBER_SERVER;
		else
			ru->server_role.role = LSA_ROLE_STANDALONE_SERVER;

		ru->server_role.pad = 0;
		status = NT_STATUS_SUCCESS;
		break;

	default:
		bzero(param, sizeof (struct mslsa_QueryInfoPolicy));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS);
		return (NDR_DRC_OK);
	}

	if (status != NT_STATUS_SUCCESS)
		param->status = NT_SC_ERROR(status);
	else
		param->status = NT_STATUS_SUCCESS;
	param->address = (DWORD)(uintptr_t)ru;

	return (NDR_DRC_OK);
}
Пример #5
0
/*
 * Build the SPNEGO "hint" token based on the
 * configured authentication mechanisms.
 * (NTLMSSP, and maybe Kerberos)
 */
void
smbd_get_authconf(smb_kmod_cfg_t *kcfg)
{
	SPNEGO_MECH_OID *mechList = MechTypeList;
	int mechCnt = MechTypeCnt;
	SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
	uchar_t *pBuf = kcfg->skc_negtok;
	uint32_t *pBufLen = &kcfg->skc_negtok_len;
	ulong_t tLen = sizeof (kcfg->skc_negtok);
	int rc;

	/*
	 * In workgroup mode, skip Kerberos.
	 */
	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) {
		mechList += MECH_OID_IDX_NTLMSSP;
		mechCnt  -= MECH_OID_IDX_NTLMSSP;
	}

	rc = spnegoCreateNegTokenHint(mechList, mechCnt,
	    (uchar_t *)IgnoreSPN, &hSpnegoToken);
	if (rc != SPNEGO_E_SUCCESS) {
		syslog(LOG_DEBUG, "smb_config_get_negtok: "
		    "spnegoCreateNegTokenHint, rc=%d", rc);
		*pBufLen = 0;
		return;
	}
	rc = spnegoTokenGetBinary(hSpnegoToken, pBuf, &tLen);
	if (rc != SPNEGO_E_SUCCESS) {
		syslog(LOG_DEBUG, "smb_config_get_negtok: "
		    "spnegoTokenGetBinary, rc=%d", rc);
		*pBufLen = 0;
	} else {
		*pBufLen = (uint32_t)tLen;
	}
	spnegoFreeData(hSpnegoToken);
}
Пример #6
0
/*
 * GetPrinterData is used t obtain values from the registry for a
 * printer or a print server.  See [MS-RPRN] for value descriptions.
 * The registry returns ERROR_FILE_NOT_FOUND for unknown keys.
 */
static int
spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
{
	static spoolss_winreg_t	reg[] = {
		{ "ChangeId",			0x0050acf2 },
		{ "W3SvcInstalled",		0x00000000 },
		{ "BeepEnabled",		0x00000000 },
		{ "EventLog",			0x0000001f },
		{ "NetPopup",			0x00000000 },
		{ "NetPopupToComputer",		0x00000000 },
		{ "MajorVersion",		0x00000003 },
		{ "MinorVersion",		0x00000000 },
		{ "DsPresent",			0x00000000 }
	};

	struct spoolss_GetPrinterData *param = arg;
	char			*name = (char *)param->pValueName;
	char			buf[MAXPATHLEN];
	static uint8_t		reserved_buf[4];
	spoolss_winreg_t	*rp;
	smb_share_t		si;
	smb_version_t		*osversion;
	struct utsname		sysname;
	smb_wchar_t		*wcs;
	uint32_t		value;
	uint32_t		status;
	int			wcslen;
	int			i;

	if (name == NULL || *name == '\0') {
		status = ERROR_FILE_NOT_FOUND;
		goto report_error;
	}

	for (i = 0; i < sizeof (reg) / sizeof (reg[0]); ++i) {
		param->pType = WINREG_DWORD;
		param->Needed = sizeof (uint32_t);
		rp = &reg[i];

		if (strcasecmp(name, rp->name) != 0)
			continue;

		if (param->Size < sizeof (uint32_t)) {
			param->Size = 0;
			goto need_more_data;
		}

		if ((param->Buf = NDR_NEW(mxa, uint32_t)) == NULL) {
			status = ERROR_NOT_ENOUGH_MEMORY;
			goto report_error;
		}

		value = rp->value;

		if ((strcasecmp(name, "DsPresent") == 0) &&
		    (smb_config_get_secmode() == SMB_SECMODE_DOMAIN))
			value = 0x00000001;

		bcopy(&value, param->Buf, sizeof (uint32_t));
		param->Size = sizeof (uint32_t);
		param->status = ERROR_SUCCESS;
		return (NDR_DRC_OK);
	}

	if (strcasecmp(name, "OSVersion") == 0) {
		param->pType = WINREG_BINARY;
		param->Needed = sizeof (smb_version_t);

		if (param->Size < sizeof (smb_version_t)) {
			param->Size = sizeof (smb_version_t);
			goto need_more_data;
		}

		if ((osversion = NDR_NEW(mxa, smb_version_t)) == NULL) {
			status = ERROR_NOT_ENOUGH_MEMORY;
			goto report_error;
		}

		smb_config_get_version(osversion);
		param->Buf = (uint8_t *)osversion;
		param->status = ERROR_SUCCESS;
		return (NDR_DRC_OK);
	}

	if (strcasecmp(name, "DNSMachineName") == 0) {
		param->pType = WINREG_SZ;
		buf[0] = '\0';
		(void) smb_getfqhostname(buf, MAXHOSTNAMELEN);
		goto encode_string;
	}

	if (strcasecmp(name, "DefaultSpoolDirectory") == 0) {
		param->pType = WINREG_SZ;
		buf[0] = '\0';

		if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
			status = ERROR_FILE_NOT_FOUND;
			goto report_error;
		}

		(void) snprintf(buf, MAXPATHLEN, "C:/%s", si.shr_path);
		(void) strcanon(buf, "/\\");
		(void) strsubst(buf, '/', '\\');
		goto encode_string;
	}

	if (strcasecmp(name, "Architecture") == 0) {
		param->pType = WINREG_SZ;

		if (uname(&sysname) < 0)
			(void) strlcpy(buf, "Solaris", MAXPATHLEN);
		else
			(void) snprintf(buf, MAXPATHLEN, "%s %s",
			    sysname.sysname, sysname.machine);

		goto encode_string;
	}

	status = ERROR_FILE_NOT_FOUND;

report_error:
	bzero(param, sizeof (struct spoolss_GetPrinterData));
	param->Buf = reserved_buf;
	param->status = status;
	return (NDR_DRC_OK);

encode_string:
	wcslen = smb_wcequiv_strlen(buf) + sizeof (smb_wchar_t);
	if (param->Size < wcslen) {
		param->Needed = wcslen;
		goto need_more_data;
	}

	if ((wcs = NDR_MALLOC(mxa, wcslen)) == NULL) {
		status = ERROR_NOT_ENOUGH_MEMORY;
		goto report_error;
	}

	(void) ndr_mbstowcs(NULL, wcs, buf, wcslen);
	param->Buf = (uint8_t *)wcs;
	param->Needed = wcslen;
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);

need_more_data:
	param->Size = 0;
	param->Buf = reserved_buf;
	param->status = ERROR_MORE_DATA;
	return (NDR_DRC_OK);
}
Пример #7
0
/*
 * 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);
}
Пример #8
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));
}
Пример #9
0
/*
 * Handle a security blob we've received from the client.
 * Incoming type: LSA_MTYPE_ESFIRST
 * Outgoing types: LSA_MTYPE_ES_CONT, LSA_MTYPE_ES_DONE,
 *   LSA_MTYPE_ERROR
 */
static int
smbd_authsvc_esfirst(authsvc_context_t *ctx)
{
	const spnego_mech_handler_t *mh;
	int idx, pref, rc;
	int best_pref = 1000;
	int best_mhidx = -1;

	/*
	 * NTLMSSP header is 8+, SPNEGO is 10+
	 */
	if (ctx->ctx_irawlen < 8) {
		smbd_report("authsvc: short blob");
		return (NT_STATUS_INVALID_PARAMETER);
	}

	/*
	 * We could have "Raw NTLMSSP" here intead of SPNEGO.
	 */
	if (bcmp(ctx->ctx_irawbuf, "NTLMSSP", 8) == 0) {
		rc = smbd_raw_ntlmssp_esfirst(ctx);
		return (rc);
	}

	/*
	 * Parse the SPNEGO token, check its type.
	 */
	rc = spnegoInitFromBinary(ctx->ctx_irawbuf,
	    ctx->ctx_irawlen, &ctx->ctx_itoken);
	if (rc != 0) {
		smbd_report("authsvc: spnego parse failed");
		return (NT_STATUS_INVALID_PARAMETER);
	}

	rc = spnegoGetTokenType(ctx->ctx_itoken, &ctx->ctx_itoktype);
	if (rc != 0) {
		smbd_report("authsvc: spnego get token type failed");
		return (NT_STATUS_INVALID_PARAMETER);
	}

	if (ctx->ctx_itoktype != SPNEGO_TOKEN_INIT) {
		smbd_report("authsvc: spnego wrong token type %d",
		    ctx->ctx_itoktype);
		return (NT_STATUS_INVALID_PARAMETER);
	}

	/*
	 * Figure out which mech type to use.  We want to use the
	 * first of the client's supported mechanisms that we also
	 * support.  Unfortunately, the spnego code does not have an
	 * interface to walk the token's mech list, so we have to
	 * ask about each mech type we know and keep track of which
	 * was earliest in the token's mech list.
	 *
	 * Also, skip the Kerberos mechanisms in workgroup mode.
	 */
	idx = 0;
	mh = mech_table;
	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) {
		idx = MECH_TBL_IDX_NTLMSSP;
		mh = &mech_table[idx];
	}
	for (; mh->mh_init != NULL; idx++, mh++) {

		if (spnegoIsMechTypeAvailable(ctx->ctx_itoken,
		    mh->mh_oid, &pref) != 0)
			continue;

		if (pref < best_pref) {
			best_pref = pref;
			best_mhidx = idx;
		}
	}
	if (best_mhidx == -1) {
		smbd_report("authsvc: no supported spnego mechanism");
		return (NT_STATUS_INVALID_PARAMETER);
	}

	/* Found a mutually agreeable mech. */
	mh = &mech_table[best_mhidx];
	ctx->ctx_mech_oid = mh->mh_oid;
	ctx->ctx_mh_work = mh->mh_work;
	ctx->ctx_mh_fini = mh->mh_fini;
	rc = mh->mh_init(ctx);
	if (rc != 0) {
		smbd_report("authsvc: mech init failed");
		return (rc);
	}

	/*
	 * Common to LSA_MTYPE_ESFIRST, LSA_MTYPE_ESNEXT
	 */
	rc = smbd_authsvc_escmn(ctx);
	return (rc);
}
Пример #10
0
/*
 * 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);
}