/* * Hook to allow handling of NTLM authentication for AD operation * without directly linking the s4 auth stack * * This ensures we use the source4 authentication stack, as well as * the authorization stack to create the user's token. This ensures * consistency between NTLM logins and NTLMSSP logins, as NTLMSSP is * handled by the hook above. */ static NTSTATUS make_auth4_context_s4(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context) { NTSTATUS status; struct loadparm_context *lp_ctx; struct tevent_context *event_ctx; TALLOC_CTX *frame = talloc_stackframe(); struct imessaging_context *msg_ctx; struct server_id *server_id; lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); if (lp_ctx == NULL) { DEBUG(1, ("loadparm_init_s3 failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } event_ctx = s4_event_context_init(frame); if (event_ctx == NULL) { DEBUG(1, ("s4_event_context_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } server_id = new_server_id_task(frame); if (server_id == NULL) { DEBUG(1, ("new_server_id_task failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } msg_ctx = imessaging_init(frame, lp_ctx, *server_id, event_ctx, true); if (msg_ctx == NULL) { DEBUG(1, ("imessaging_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } talloc_reparent(frame, msg_ctx, server_id); status = auth_context_create(mem_ctx, event_ctx, msg_ctx, lp_ctx, auth4_context); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(status))); TALLOC_FREE(frame); return status; } talloc_reparent(frame, *auth4_context, msg_ctx); talloc_reparent(frame, *auth4_context, event_ctx); talloc_reparent(frame, *auth4_context, lp_ctx); TALLOC_FREE(frame); return status; }
/* * Hook to allow handling of NTLM authentication for AD operation * without directly linking the s4 auth stack * * This ensures we use the source4 authentication stack, as well as * the authorization stack to create the user's token. This ensures * consistency between NTLM logins and NTLMSSP logins, as NTLMSSP is * handled by the hook above. */ static NTSTATUS make_auth4_context_s4(const struct auth_context *auth_context, TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context) { NTSTATUS status; struct loadparm_context *lp_ctx; struct tevent_context *event_ctx; TALLOC_CTX *frame = talloc_stackframe(); struct imessaging_context *msg_ctx; struct server_id *server_id; lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); if (lp_ctx == NULL) { DEBUG(1, ("loadparm_init_s3 failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } event_ctx = s4_event_context_init(frame); if (event_ctx == NULL) { DEBUG(1, ("s4_event_context_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } server_id = new_server_id_task(frame); if (server_id == NULL) { DEBUG(1, ("new_server_id_task failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } msg_ctx = imessaging_init(frame, lp_ctx, *server_id, event_ctx, true); if (msg_ctx == NULL) { DEBUG(1, ("imessaging_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } talloc_reparent(frame, msg_ctx, server_id); /* Allow forcing a specific auth4 module */ if (!auth_context->forced_samba4_methods) { status = auth_context_create(mem_ctx, event_ctx, msg_ctx, lp_ctx, auth4_context); } else { const char * const *forced_auth_methods = (const char * const *)str_list_make(mem_ctx, auth_context->forced_samba4_methods, NULL); status = auth_context_create_methods(mem_ctx, forced_auth_methods, event_ctx, msg_ctx, lp_ctx, NULL, auth4_context); } if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(status))); TALLOC_FREE(frame); return status; } talloc_reparent(frame, *auth4_context, msg_ctx); talloc_reparent(frame, *auth4_context, event_ctx); talloc_reparent(frame, *auth4_context, lp_ctx); TALLOC_FREE(frame); return status; }
/* * Hook to allow the source4 set of GENSEC modules to handle * blob-based authentication mechanisms, without directly linking the * mechanism code. * * This may eventually go away, when the GSSAPI acceptors are merged, * when we will just rely on the make_auth4_context_s4 hook instead. * * Even for NTLMSSP, which has a common module, significant parts of * the behaviour are overridden here, because it uses the source4 NTLM * stack and the source4 mapping between the PAC/SamLogon response and * the local token. * * It is important to override all this to ensure that the exact same * token is generated and used in the SMB and LDAP servers, for NTLM * and for Kerberos. */ static NTSTATUS prepare_gensec(const struct auth_context *auth_context, TALLOC_CTX *mem_ctx, struct gensec_security **gensec_context) { NTSTATUS status; struct loadparm_context *lp_ctx; struct tevent_context *event_ctx; TALLOC_CTX *frame = talloc_stackframe(); struct gensec_security *gensec_ctx; struct imessaging_context *msg_ctx; struct cli_credentials *server_credentials; struct server_id *server_id; lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); if (lp_ctx == NULL) { DEBUG(1, ("loadparm_init_s3 failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } event_ctx = s4_event_context_init(frame); if (event_ctx == NULL) { DEBUG(1, ("s4_event_context_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } server_id = new_server_id_task(frame); if (server_id == NULL) { DEBUG(1, ("new_server_id_task failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } msg_ctx = imessaging_init(frame, lp_ctx, *server_id, event_ctx, true); if (msg_ctx == NULL) { DEBUG(1, ("imessaging_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } talloc_reparent(frame, msg_ctx, server_id); server_credentials = cli_credentials_init(frame); if (!server_credentials) { DEBUG(1, ("Failed to init server credentials")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } cli_credentials_set_conf(server_credentials, lp_ctx); status = cli_credentials_set_machine_account(server_credentials, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); TALLOC_FREE(frame); return status; } status = samba_server_gensec_start(mem_ctx, event_ctx, msg_ctx, lp_ctx, server_credentials, "cifs", &gensec_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status))); TALLOC_FREE(frame); return status; } talloc_reparent(frame, gensec_ctx, msg_ctx); talloc_reparent(frame, gensec_ctx, event_ctx); talloc_reparent(frame, gensec_ctx, lp_ctx); talloc_reparent(frame, gensec_ctx, server_credentials); gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY); gensec_want_feature(gensec_ctx, GENSEC_FEATURE_UNIX_TOKEN); *gensec_context = gensec_ctx; TALLOC_FREE(frame); return status; }