Exemplo n.º 1
0
/****************************************************************************
 Do a specific test for an smb password being correct, given a smb_password and
 the lanman and NT responses.
****************************************************************************/
static NTSTATUS authsam_password_ok(struct auth4_context *auth_context,
				    TALLOC_CTX *mem_ctx,
				    uint16_t acct_flags,
				    const struct samr_Password *lm_pwd, 
				    const struct samr_Password *nt_pwd,
				    const struct auth_usersupplied_info *user_info, 
				    DATA_BLOB *user_sess_key, 
				    DATA_BLOB *lm_sess_key)
{
	NTSTATUS status;

	switch (user_info->password_state) {
	case AUTH_PASSWORD_PLAIN: 
	{
		const struct auth_usersupplied_info *user_info_temp;	
		status = encrypt_user_info(mem_ctx, auth_context, 
					   AUTH_PASSWORD_HASH, 
					   user_info, &user_info_temp);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("Failed to convert plaintext password to password HASH: %s\n", nt_errstr(status)));
			return status;
		}
		user_info = user_info_temp;

		FALL_THROUGH;
	}
	case AUTH_PASSWORD_HASH:
		*lm_sess_key = data_blob(NULL, 0);
		*user_sess_key = data_blob(NULL, 0);
		status = hash_password_check(mem_ctx, 
					     lpcfg_lanman_auth(auth_context->lp_ctx),
					     user_info->password.hash.lanman,
					     user_info->password.hash.nt,
					     user_info->mapped.account_name,
					     lm_pwd, nt_pwd);
		NT_STATUS_NOT_OK_RETURN(status);
		break;
		
	case AUTH_PASSWORD_RESPONSE:
		status = ntlm_password_check(mem_ctx, 
					     lpcfg_lanman_auth(auth_context->lp_ctx),
						 lpcfg_ntlm_auth(auth_context->lp_ctx),
					     user_info->logon_parameters, 
					     &auth_context->challenge.data, 
					     &user_info->password.response.lanman, 
					     &user_info->password.response.nt,
					     user_info->mapped.account_name,
					     user_info->client.account_name, 
					     user_info->client.domain_name, 
					     lm_pwd, nt_pwd,
					     user_sess_key, lm_sess_key);
		NT_STATUS_NOT_OK_RETURN(status);
		break;
	}

	return NT_STATUS_OK;
}
Exemplo n.º 2
0
/**
 * Start NTLMSSP on the server side
 *
 */
NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
{
	NTSTATUS nt_status;
	struct ntlmssp_state *ntlmssp_state;
	struct gensec_ntlmssp_context *gensec_ntlmssp;
	const char *netbios_name;
	const char *netbios_domain;
	const char *dns_name;
	const char *dns_domain;
	enum server_role role;

	role = lpcfg_server_role(gensec_security->settings->lp_ctx);

	nt_status = gensec_ntlmssp_start(gensec_security);
	NT_STATUS_NOT_OK_RETURN(nt_status);

	gensec_ntlmssp =
		talloc_get_type_abort(gensec_security->private_data,
				      struct gensec_ntlmssp_context);

	ntlmssp_state = talloc_zero(gensec_ntlmssp,
				    struct ntlmssp_state);
	if (!ntlmssp_state) {
		return NT_STATUS_NO_MEMORY;
	}
	gensec_ntlmssp->ntlmssp_state = ntlmssp_state;

	ntlmssp_state->role = NTLMSSP_SERVER;

	ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;

	ntlmssp_state->allow_lm_response =
		lpcfg_lanman_auth(gensec_security->settings->lp_ctx);

	if (ntlmssp_state->allow_lm_response &&
	    gensec_setting_bool(gensec_security->settings,
				"ntlmssp_server", "allow_lm_key", false))
	{
		ntlmssp_state->allow_lm_key = true;
	}

	ntlmssp_state->force_old_spnego = false;

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "force_old_spnego", false)) {
		/*
		 * For testing Windows 2000 mode
		 */
		ntlmssp_state->force_old_spnego = true;
	}

	ntlmssp_state->neg_flags =
		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
	}

	if (ntlmssp_state->allow_lm_key) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
	}

	/*
	 * We always allow NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL.
	 *
	 * These will be removed if the client doesn't want them.
	 */
	ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;

	if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;

		if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
			/*
			 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
			 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
			 * is requested.
			 */
			ntlmssp_state->force_wrap_seal = true;
		}
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
	}

	if (role == ROLE_STANDALONE) {
		ntlmssp_state->server.is_standalone = true;
	} else {
		ntlmssp_state->server.is_standalone = false;
	}

	if (gensec_security->settings->server_netbios_name) {
		netbios_name = gensec_security->settings->server_netbios_name;
	} else {
		netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);
	}

	if (gensec_security->settings->server_netbios_domain) {
		netbios_domain = gensec_security->settings->server_netbios_domain;
	} else {
		netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
	}

	if (gensec_security->settings->server_dns_name) {
		dns_name = gensec_security->settings->server_dns_name;
	} else {
		const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
		char *lower_netbiosname;

		lower_netbiosname = strlower_talloc(ntlmssp_state, netbios_name);
		NT_STATUS_HAVE_NO_MEMORY(lower_netbiosname);

		/* Find out the DNS host name */
		if (dnsdomain && dnsdomain[0] != '\0') {
			dns_name = talloc_asprintf(ntlmssp_state, "%s.%s",
						   lower_netbiosname,
						   dnsdomain);
			talloc_free(lower_netbiosname);
			NT_STATUS_HAVE_NO_MEMORY(dns_name);
		} else {
			dns_name = lower_netbiosname;
		}
	}

	if (gensec_security->settings->server_dns_domain) {
		dns_domain = gensec_security->settings->server_dns_domain;
	} else {
		dns_domain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
	}

	ntlmssp_state->server.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.netbios_name);

	ntlmssp_state->server.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.netbios_domain);

	ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, dns_name);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);

	ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);

	ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
	ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;

	return NT_STATUS_OK;
}
Exemplo n.º 3
0
static NTSTATUS local_pw_check_specified(struct loadparm_context *lp_ctx,
					 const char *username, 
					 const char *domain, 
					 const char *workstation,
					 const DATA_BLOB *challenge, 
					 const DATA_BLOB *lm_response, 
					 const DATA_BLOB *nt_response, 
					 uint32_t flags, 
					 DATA_BLOB *lm_session_key, 
					 DATA_BLOB *user_session_key, 
					 char **error_string, 
					 char **unix_name) 
{
	NTSTATUS nt_status;
	struct samr_Password lm_pw, nt_pw;
	struct samr_Password *lm_pwd, *nt_pwd;
	TALLOC_CTX *mem_ctx = talloc_init("local_pw_check_specified");
	if (!mem_ctx) {
		nt_status = NT_STATUS_NO_MEMORY;
	} else {
		
		E_md4hash(opt_password, nt_pw.hash);
		if (E_deshash(opt_password, lm_pw.hash)) {
			lm_pwd = &lm_pw;
		} else {
			lm_pwd = NULL;
		}
		nt_pwd = &nt_pw;
		
		
		nt_status = ntlm_password_check(mem_ctx, 
						lpcfg_lanman_auth(lp_ctx),
						lpcfg_ntlm_auth(lp_ctx),
						MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
						MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,
						challenge,
						lm_response,
						nt_response,
						username,
						username,
						domain,
						lm_pwd, nt_pwd, user_session_key, lm_session_key);
		
		if (NT_STATUS_IS_OK(nt_status)) {
			if (unix_name) {
				if (asprintf(unix_name, "%s%c%s", domain,
					     *lpcfg_winbind_separator(lp_ctx),
					     username) < 0) {
					nt_status = NT_STATUS_NO_MEMORY;
				}
			}
		} else {
			DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 
				  domain, username, workstation, 
				  nt_errstr(nt_status)));
		}
		talloc_free(mem_ctx);
	}
	if (error_string) {
		*error_string = strdup(nt_errstr(nt_status));
	}
	return nt_status;
	
	
}
Exemplo n.º 4
0
/*
  samr_OemChangePasswordUser2
*/
NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
					    TALLOC_CTX *mem_ctx,
					    struct samr_OemChangePasswordUser2 *r)
{
	NTSTATUS status;
	DATA_BLOB new_password, new_unicode_password;
	char *new_pass;
	struct samr_CryptPassword *pwbuf = r->in.password;
	struct ldb_context *sam_ctx;
	struct ldb_dn *user_dn;
	int ret;
	struct ldb_message **res;
	const char * const attrs[] = { "objectSid", "dBCSPwd", NULL };
	struct samr_Password *lm_pwd;
	DATA_BLOB lm_pwd_blob;
	uint8_t new_lm_hash[16];
	struct samr_Password lm_verifier;
	size_t unicode_pw_len;

	if (pwbuf == NULL) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (r->in.hash == NULL) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	/* this call can only work with lanman auth */
	if (!lpcfg_lanman_auth(dce_call->conn->dce_ctx->lp_ctx)) {
		return NT_STATUS_WRONG_PASSWORD;
	}

	/* Connect to a SAMDB with system privileges for fetching the old pw
	 * hashes. */
	sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
				dce_call->conn->dce_ctx->lp_ctx,
				system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
	if (sam_ctx == NULL) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	/* we need the users dn and the domain dn (derived from the
	   user SID). We also need the current lm password hash in
	   order to decrypt the incoming password */
	ret = gendb_search(sam_ctx,
			   mem_ctx, NULL, &res, attrs,
			   "(&(sAMAccountName=%s)(objectclass=user))",
			   r->in.account->string);
	if (ret != 1) {
		/* Don't give the game away:  (don't allow anonymous users to prove the existance of usernames) */
		return NT_STATUS_WRONG_PASSWORD;
	}

	user_dn = res[0]->dn;

	status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
					res[0], &lm_pwd, NULL);
	if (!NT_STATUS_IS_OK(status) || !lm_pwd) {
		return NT_STATUS_WRONG_PASSWORD;
	}

	/* decrypt the password we have been given */
	lm_pwd_blob = data_blob(lm_pwd->hash, sizeof(lm_pwd->hash));
	arcfour_crypt_blob(pwbuf->data, 516, &lm_pwd_blob);
	data_blob_free(&lm_pwd_blob);

	if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) {
		DEBUG(3,("samr: failed to decode password buffer\n"));
		return NT_STATUS_WRONG_PASSWORD;
	}

	if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
				  CH_DOS, CH_UNIX,
				  (const char *)new_password.data,
				  new_password.length,
				  (void **)&new_pass, NULL, false)) {
		DEBUG(3,("samr: failed to convert incoming password buffer to unix charset\n"));
		return NT_STATUS_WRONG_PASSWORD;
	}

	if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
					       CH_DOS, CH_UTF16,
					       (const char *)new_password.data,
					       new_password.length,
					       (void **)&new_unicode_password.data, &unicode_pw_len, false)) {
		DEBUG(3,("samr: failed to convert incoming password buffer to UTF16 charset\n"));
		return NT_STATUS_WRONG_PASSWORD;
	}
	new_unicode_password.length = unicode_pw_len;

	E_deshash(new_pass, new_lm_hash);
	E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash);
	if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) {
		return NT_STATUS_WRONG_PASSWORD;
	}

	/* Connect to a SAMDB with user privileges for the password change */
	sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
				dce_call->conn->dce_ctx->lp_ctx,
				dce_call->conn->auth_state.session_info, 0);
	if (sam_ctx == NULL) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	/* Start transaction */
	ret = ldb_transaction_start(sam_ctx);
	if (ret != LDB_SUCCESS) {
		DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(sam_ctx)));
		return NT_STATUS_TRANSACTION_ABORTED;
	}

	/* Performs the password modification. We pass the old hashes read out
	 * from the database since they were already checked against the user-
	 * provided ones. */
	status = samdb_set_password(sam_ctx, mem_ctx,
				    user_dn, NULL,
				    &new_unicode_password,
				    NULL, NULL,
				    lm_pwd, NULL, /* this is a user password change */
				    NULL,
				    NULL);
	if (!NT_STATUS_IS_OK(status)) {
		ldb_transaction_cancel(sam_ctx);
		return status;
	}

	/* And this confirms it in a transaction commit */
	ret = ldb_transaction_commit(sam_ctx);
	if (ret != LDB_SUCCESS) {
		DEBUG(1,("Failed to commit transaction to change password on %s: %s\n",
			 ldb_dn_get_linearized(user_dn),
			 ldb_errstring(sam_ctx)));
		return NT_STATUS_TRANSACTION_ABORTED;
	}

	return NT_STATUS_OK;
}
Exemplo n.º 5
0
/**
 * Start NTLMSSP on the server side 
 *
 */
NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
{
	NTSTATUS nt_status;
	struct ntlmssp_state *ntlmssp_state;
	struct gensec_ntlmssp_context *gensec_ntlmssp;

	nt_status = gensec_ntlmssp_start(gensec_security);
	NT_STATUS_NOT_OK_RETURN(nt_status);

	gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
					       struct gensec_ntlmssp_context);
	ntlmssp_state = gensec_ntlmssp->ntlmssp_state;

	ntlmssp_state->role = NTLMSSP_SERVER;

	ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;

	ntlmssp_state->allow_lm_key = (lpcfg_lanman_auth(gensec_security->settings->lp_ctx)
					  && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));

	ntlmssp_state->neg_flags =
		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;

	ntlmssp_state->lm_resp = data_blob(NULL, 0);
	ntlmssp_state->nt_resp = data_blob(NULL, 0);

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
	}

	if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
	}

	ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
	ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
	ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
	ntlmssp_state->check_password = auth_ntlmssp_check_password;
	if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) {
		ntlmssp_state->server.is_standalone = true;
	} else {
		ntlmssp_state->server.is_standalone = false;
	}

	ntlmssp_state->server.netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);

	ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);

	{
		const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
		char *dnsname, *lower_netbiosname;
		lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name);

		/* Find out the DNS host name */
		if (dnsdomain && dnsdomain[0] != '\0') {
			dnsname = talloc_asprintf(ntlmssp_state, "%s.%s",
						  lower_netbiosname,
						  dnsdomain);
			talloc_free(lower_netbiosname);
			ntlmssp_state->server.dns_name = dnsname;
		} else {
			ntlmssp_state->server.dns_name = lower_netbiosname;
		}

		NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);

		ntlmssp_state->server.dns_domain
			= talloc_strdup(ntlmssp_state,
					lpcfg_dnsdomain(gensec_security->settings->lp_ctx));
		NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
	}

	return NT_STATUS_OK;
}