コード例 #1
0
static uint32_t
netlogon_logon(smb_logon_t *user_info, smb_token_t *token)
{
	char resource_domain[SMB_PI_MAX_DOMAIN];
	char server[NETBIOS_NAME_SZ * 2];
	mlsvc_handle_t netr_handle;
	smb_domainex_t di;
	uint32_t status;
	int retries = 0;

	(void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);

	/* Avoid interfering with DC discovery. */
	if (smb_ddiscover_wait() != 0 ||
	    !smb_domain_getinfo(&di)) {
		netr_invalidate_chain();
		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
	}

	do {
		if (netr_open(di.d_dc, di.d_primary.di_nbname, &netr_handle)
		    != 0)
			return (NT_STATUS_OPEN_FAILED);

		if (di.d_dc && (*netr_global_info.server != '\0')) {
			(void) snprintf(server, sizeof (server),
			    "\\\\%s", di.d_dc);
			if (strncasecmp(netr_global_info.server,
			    server, strlen(server)) != 0)
				netr_invalidate_chain();
		}

		if ((netr_global_info.flags & NETR_FLG_VALID) == 0 ||
		    !smb_match_netlogon_seqnum()) {
			status = netlogon_auth(di.d_dc, &netr_handle,
			    NETR_FLG_NULL);

			if (status != 0) {
				(void) netr_close(&netr_handle);
				return (NT_STATUS_LOGON_FAILURE);
			}

			netr_global_info.flags |= NETR_FLG_VALID;
		}

		status = netr_server_samlogon(&netr_handle,
		    &netr_global_info, di.d_dc, user_info, token);

		(void) netr_close(&netr_handle);
	} while (status == NT_STATUS_INSUFFICIENT_LOGON_INFO && retries++ < 3);

	if (retries >= 3)
		status = NT_STATUS_LOGON_FAILURE;

	return (status);
}
コード例 #2
0
ファイル: smbadm.c プロジェクト: metricinc/illumos-gate
/*ARGSUSED*/
static int
smbadm_list(int argc, char **argv)
{
	char domain[MAXHOSTNAMELEN];
	char fqdn[MAXHOSTNAMELEN];
	char srvname[MAXHOSTNAMELEN];
	char modename[16];
	int rc;
	smb_inaddr_t srvipaddr;
	char ipstr[INET6_ADDRSTRLEN];

	rc = smb_config_getstr(SMB_CI_SECURITY, modename, sizeof (modename));
	if (rc != SMBD_SMF_OK) {
		(void) fprintf(stderr,
		    gettext("cannot determine the operational mode\n"));
		return (1);
	}

	if (smb_getdomainname(domain, sizeof (domain)) != 0) {
		(void) fprintf(stderr, gettext("failed to get the %s name\n"),
		    modename);
		return (1);
	}

	if (strcmp(modename, "workgroup") == 0) {
		(void) printf(gettext("[*] [%s]\n"), domain);
		return (0);
	}

	(void) printf(gettext("[*] [%s]\n"), domain);
	if ((smb_getfqdomainname(fqdn, sizeof (fqdn)) == 0) && (*fqdn != '\0'))
		(void) printf(gettext("[*] [%s]\n"), fqdn);

	if ((smb_get_dcinfo(srvname, MAXHOSTNAMELEN, &srvipaddr)
	    == NT_STATUS_SUCCESS) && (*srvname != '\0') &&
	    (!smb_inet_iszero(&srvipaddr))) {
		(void) smb_inet_ntop(&srvipaddr, ipstr,
		    SMB_IPSTRLEN(srvipaddr.a_family));
		(void) printf(gettext("\t[+%s.%s] [%s]\n"),
		    srvname, fqdn, ipstr);
	}

	smb_domain_show();
	return (0);
}
コード例 #3
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));
}
コード例 #4
0
static uint32_t
netr_setup_token(struct netr_validation_info3 *info3, smb_logon_t *user_info,
    netr_info_t *netr_info, smb_token_t *token)
{
	char *username, *domain;
	unsigned char rc4key[SMBAUTH_SESSION_KEY_SZ];
	smb_sid_t *domsid;
	uint32_t status;
	char nbdomain[NETBIOS_NAME_SZ];

	domsid = (smb_sid_t *)info3->LogonDomainId;

	token->tkn_user.i_sid = smb_sid_splice(domsid, info3->UserId);
	if (token->tkn_user.i_sid == NULL)
		return (NT_STATUS_NO_MEMORY);

	token->tkn_primary_grp.i_sid = smb_sid_splice(domsid,
	    info3->PrimaryGroupId);
	if (token->tkn_primary_grp.i_sid == NULL)
		return (NT_STATUS_NO_MEMORY);

	username = (info3->EffectiveName.str)
	    ? (char *)info3->EffectiveName.str : user_info->lg_e_username;

	if (info3->LogonDomainName.str) {
		domain = (char *)info3->LogonDomainName.str;
	} else if (*user_info->lg_e_domain != '\0') {
		domain = user_info->lg_e_domain;
	} else {
		(void) smb_getdomainname(nbdomain, sizeof (nbdomain));
		domain = nbdomain;
	}

	if (username)
		token->tkn_account_name = strdup(username);
	if (domain)
		token->tkn_domain_name = strdup(domain);

	if (token->tkn_account_name == NULL || token->tkn_domain_name == NULL)
		return (NT_STATUS_NO_MEMORY);

	status = netr_setup_token_wingrps(info3, token);
	if (status != NT_STATUS_SUCCESS)
		return (status);

	/*
	 * The UserSessionKey in NetrSamLogon RPC is obfuscated using the
	 * session key obtained in the NETLOGON credential chain.
	 * An 8 byte session key is zero extended to 16 bytes. This 16 byte
	 * key is the key to the RC4 algorithm. The RC4 byte stream is
	 * exclusively ored with the 16 byte UserSessionKey to recover
	 * the the clear form.
	 */
	if ((token->tkn_session_key = malloc(SMBAUTH_SESSION_KEY_SZ)) == NULL)
		return (NT_STATUS_NO_MEMORY);
	bzero(rc4key, SMBAUTH_SESSION_KEY_SZ);
	bcopy(netr_info->session_key.key, rc4key, netr_info->session_key.len);
	bcopy(info3->UserSessionKey.data, token->tkn_session_key,
	    SMBAUTH_SESSION_KEY_SZ);
	rand_hash((unsigned char *)token->tkn_session_key,
	    SMBAUTH_SESSION_KEY_SZ, rc4key, SMBAUTH_SESSION_KEY_SZ);

	return (NT_STATUS_SUCCESS);
}