*/
#include "includes.h"
+#include "auth.h"
#include "../libcli/auth/ntlmssp.h"
#include "ntlmssp_wrap.h"
#include "../librpc/gen_ndr/netlogon.h"
+#include "../lib/tsocket/tsocket.h"
+#include "auth/gensec/gensec.h"
+#include "librpc/rpc/dcerpc.h"
-NTSTATUS auth_ntlmssp_steal_server_info(TALLOC_CTX *mem_ctx,
- struct auth_ntlmssp_state *auth_ntlmssp_state,
- struct auth_serversupplied_info **server_info)
+NTSTATUS auth_ntlmssp_session_info(TALLOC_CTX *mem_ctx,
+ struct auth_ntlmssp_state *auth_ntlmssp_state,
+ struct auth_session_info **session_info)
{
- /* Free the current server_info user_session_key and reset it from the
- * current ntlmssp_state session_key */
- data_blob_free(&auth_ntlmssp_state->server_info->user_session_key);
- /* Set up the final session key for the connection */
- auth_ntlmssp_state->server_info->user_session_key =
- data_blob_talloc(
- auth_ntlmssp_state->server_info,
- auth_ntlmssp_state->ntlmssp_state->session_key.data,
- auth_ntlmssp_state->ntlmssp_state->session_key.length);
- if (auth_ntlmssp_state->ntlmssp_state->session_key.length &&
- !auth_ntlmssp_state->server_info->user_session_key.data) {
- *server_info = NULL;
- return NT_STATUS_NO_MEMORY;
+ NTSTATUS nt_status;
+ if (auth_ntlmssp_state->gensec_security) {
+
+ nt_status = gensec_session_info(auth_ntlmssp_state->gensec_security,
+ mem_ctx,
+ session_info);
+ return nt_status;
}
- /* Steal server_info away from auth_ntlmssp_state */
- *server_info = talloc_move(mem_ctx, &auth_ntlmssp_state->server_info);
- return NT_STATUS_OK;
+
+ nt_status = create_local_token(mem_ctx,
+ auth_ntlmssp_state->server_info,
+ &auth_ntlmssp_state->ntlmssp_state->session_key,
+ auth_ntlmssp_state->ntlmssp_state->user,
+ session_info);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(10, ("create_local_token failed: %s\n",
+ nt_errstr(nt_status)));
+ }
+ return nt_status;
}
/**
*/
static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
- DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
+ DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
{
struct auth_ntlmssp_state *auth_ntlmssp_state =
(struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
/* sub_set_smb_name checks for weird internally */
sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
- reload_services(smbd_messaging_context(), -1, True);
+ lp_load(get_dyn_CONFIGFILE(), false, false, true, true);
- nt_status = make_user_info_map(&user_info,
+ nt_status = make_user_info_map(&user_info,
auth_ntlmssp_state->ntlmssp_state->user,
auth_ntlmssp_state->ntlmssp_state->domain,
auth_ntlmssp_state->ntlmssp_state->client.netbios_name,
+ auth_ntlmssp_state->remote_address,
auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL,
auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL,
NULL, NULL, NULL,
AUTH_PASSWORD_RESPONSE);
- user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
-
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
+ user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
+
nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context,
user_info, &auth_ntlmssp_state->server_info);
free_user_info(&user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
+ nt_status = do_map_to_guest_server_info(nt_status,
+ &auth_ntlmssp_state->server_info,
+ auth_ntlmssp_state->ntlmssp_state->user,
+ auth_ntlmssp_state->ntlmssp_state->domain);
}
- auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
-
- nt_status = create_local_token(auth_ntlmssp_state->server_info);
-
if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(10, ("create_local_token failed: %s\n",
- nt_errstr(nt_status)));
return nt_status;
}
+ talloc_steal(auth_ntlmssp_state, auth_ntlmssp_state->server_info);
+
+ auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
+
/* Clear out the session keys, and pass them to the caller.
* They will not be used in this form again - instead the
* NTLMSSP code will decide on the final correct session key,
- * and put it back here at the end of
- * auth_ntlmssp_steal_server_info */
- if (auth_ntlmssp_state->server_info->user_session_key.length) {
+ * and supply it to create_local_token() */
+ if (auth_ntlmssp_state->server_info->session_key.length) {
DEBUG(10, ("Got NT session key of length %u\n",
- (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
- *user_session_key = auth_ntlmssp_state->server_info->user_session_key;
- talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->user_session_key.data);
- auth_ntlmssp_state->server_info->user_session_key = data_blob_null;
+ (unsigned int)auth_ntlmssp_state->server_info->session_key.length));
+ *session_key = auth_ntlmssp_state->server_info->session_key;
+ talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->session_key.data);
+ auth_ntlmssp_state->server_info->session_key = data_blob_null;
}
if (auth_ntlmssp_state->server_info->lm_session_key.length) {
DEBUG(10, ("Got LM session key of length %u\n",
return nt_status;
}
-static int auth_ntlmssp_state_destructor(void *ptr);
-
-NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state)
+NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
+ struct auth_ntlmssp_state **auth_ntlmssp_state)
{
NTSTATUS nt_status;
bool is_standalone;
struct auth_ntlmssp_state *ans;
struct auth_context *auth_context;
- if ((enum server_types)lp_server_role() == ROLE_STANDALONE) {
+ ans = talloc_zero(NULL, struct auth_ntlmssp_state);
+ if (!ans) {
+ DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ TALLOC_FREE(ans);
+ return nt_status;
+ }
+
+ ans->auth_context = talloc_steal(ans, auth_context);
+
+ if (auth_context->prepare_gensec) {
+ nt_status = auth_context->prepare_gensec(ans, &ans->gensec_security);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ TALLOC_FREE(ans);
+ return nt_status;
+ }
+ *auth_ntlmssp_state = ans;
+ return NT_STATUS_OK;
+ }
+
+ if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
is_standalone = true;
} else {
is_standalone = false;
}
- netbios_name = global_myname();
+ netbios_name = lp_netbios_name();
netbios_domain = lp_workgroup();
/* This should be a 'netbios domain -> DNS domain' mapping */
dns_domain = get_mydnsdomname(talloc_tos());
}
dns_name = get_mydnsfullname();
- ans = talloc_zero(NULL, struct auth_ntlmssp_state);
- if (!ans) {
+ ans->remote_address = tsocket_address_copy(remote_address, ans);
+ if (ans->remote_address == NULL) {
DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
return NT_STATUS_NO_MEMORY;
}
return nt_status;
}
- nt_status = make_auth_context_subsystem(&auth_context);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
- ans->auth_context = talloc_steal(ans, auth_context);
-
ans->ntlmssp_state->callback_private = ans;
ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
ans->ntlmssp_state->check_password = auth_ntlmssp_check_password;
- talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor);
-
*auth_ntlmssp_state = ans;
return NT_STATUS_OK;
}
-static int auth_ntlmssp_state_destructor(void *ptr)
+NTSTATUS auth_generic_start(struct auth_ntlmssp_state *auth_ntlmssp_state, const char *oid)
{
- struct auth_ntlmssp_state *ans;
+ if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid) {
+ return auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid(auth_ntlmssp_state->gensec_security, oid);
+ }
- ans = talloc_get_type(ptr, struct auth_ntlmssp_state);
+ if (strcmp(oid, GENSEC_OID_NTLMSSP) != 0) {
+ /* The caller will then free the auth_ntlmssp_state,
+ * undoing what was done in auth_ntlmssp_prepare().
+ *
+ * We can't do that logic here, as
+ * auth_ntlmssp_want_feature() may have been called in
+ * between.
+ */
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS auth_generic_authtype_start(struct auth_ntlmssp_state *auth_ntlmssp_state,
+ uint8_t auth_type, uint8_t auth_level)
+{
+ if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_authtype) {
+ return auth_ntlmssp_state->auth_context->gensec_start_mech_by_authtype(auth_ntlmssp_state->gensec_security,
+ auth_type, auth_level);
+ }
+
+ if (auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
+ /* The caller will then free the auth_ntlmssp_state,
+ * undoing what was done in auth_ntlmssp_prepare().
+ *
+ * We can't do that logic here, as
+ * auth_ntlmssp_want_feature() may have been called in
+ * between.
+ */
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+ auth_ntlmssp_want_feature(auth_ntlmssp_state, NTLMSSP_FEATURE_SIGN);
+ } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+ /* Always implies both sign and seal for ntlmssp */
+ auth_ntlmssp_want_feature(auth_ntlmssp_state, NTLMSSP_FEATURE_SEAL);
+ } else if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
+ /* Default features */
+ } else {
+ DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n",
+ auth_level));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- TALLOC_FREE(ans->server_info);
- TALLOC_FREE(ans->ntlmssp_state);
- return 0;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state *auth_ntlmssp_state)
+{
+ return auth_generic_start(auth_ntlmssp_state, GENSEC_OID_NTLMSSP);
}