_PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
TALLOC_CTX *mem_ctx,
const struct auth_usersupplied_info *user_info,
- struct auth_user_info_dc **user_info_dc)
+ struct auth_user_info_dc **user_info_dc,
+ uint8_t *pauthoritative)
{
struct tevent_req *subreq;
struct tevent_context *ev;
return NT_STATUS_INTERNAL_ERROR;
}
- status = auth_check_password_recv(subreq, mem_ctx, user_info_dc);
+ status = auth_check_password_recv(subreq, mem_ctx,
+ user_info_dc, pauthoritative);
TALLOC_FREE(subreq);
return status;
}
-_PUBLIC_ NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
- TALLOC_CTX *mem_ctx,
- const struct auth_usersupplied_info *user_info,
- void **server_returned_info,
- DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
+static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
+ TALLOC_CTX *mem_ctx,
+ const struct auth_usersupplied_info *user_info,
+ uint8_t *pauthoritative,
+ void **server_returned_info,
+ DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
{
struct auth_user_info_dc *user_info_dc;
NTSTATUS status;
status = auth_check_password(auth_ctx, mem_ctx, user_info,
- &user_info_dc);
+ &user_info_dc, pauthoritative);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
const struct auth_usersupplied_info *user_info;
struct auth_user_info_dc *user_info_dc;
struct auth_method_context *method;
+ uint8_t authoritative;
};
static void auth_check_password_async_trigger(struct tevent_context *ev,
/* if all the modules say 'not for me' this is reasonable */
NTSTATUS nt_status;
uint8_t chal[8];
- struct auth_usersupplied_info *user_info_tmp;
struct tevent_immediate *im;
DEBUG(3,("auth_check_password_send: "
return NULL;
}
+ /*
+ * We are authoritative by default.
+ */
+ state->authoritative = 1;
state->auth_ctx = auth_ctx;
state->user_info = user_info;
if (!user_info->mapped_state) {
int server_role = lpcfg_server_role(auth_ctx->lp_ctx);
+ struct auth_usersupplied_info *user_info_tmp;
nt_status = map_user_info(
auth_ctx->sam_ctx, req,
for (method=state->auth_ctx->methods; method; method = method->next) {
- if (state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY
- && !(method->ops->flags & AUTH_METHOD_LOCAL_SAM)) {
- continue;
- }
-
/* we fill in state->method here so debug messages in
the callers know which method failed */
state->method = method;
status = method->ops->want_check(method, req, state->user_info);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
DEBUG(11,("auth_check_password_send: "
- "%s had nothing to say\n",
+ "%s doesn't want to check\n",
method->ops->name));
continue;
}
state,
state->user_info,
&state->user_info_dc);
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
- /* the backend has handled the request */
- break;
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
+ DEBUG(11,("auth_check_password_send: "
+ "%s passes to the next method\n",
+ method->ops->name));
+ continue;
}
+
+ /* the backend has handled the request */
+ break;
}
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
- if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) {
- /* don't expose the NT_STATUS_NOT_IMPLEMENTED
- * internals, except when the caller is only probing
- * one method, as they may do the fallback
- */
- status = NT_STATUS_NO_SUCH_USER;
- }
+ state->authoritative = 0;
+ status = NT_STATUS_NO_SUCH_USER;
}
if (tevent_req_nterror(req, status)) {
_PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
- struct auth_user_info_dc **user_info_dc)
+ struct auth_user_info_dc **user_info_dc,
+ uint8_t *pauthoritative)
{
struct auth_check_password_state *state =
tevent_req_data(req, struct auth_check_password_state);
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
+
+ *pauthoritative = state->authoritative;
if (tevent_req_is_nterror(req, &status)) {
+ /*
+ * Please try not to change this string, it is probably in use
+ * in audit logging tools
+ */
DEBUG(2,("auth_check_password_recv: "
"%s authentication for user [%s\\%s] "
- "FAILED with error %s\n",
+ "FAILED with error %s, authoritative=%u\n",
(state->method ? state->method->ops->name : "NO_METHOD"),
state->user_info->mapped.domain_name,
state->user_info->mapped.account_name,
- nt_errstr(status)));
+ nt_errstr(status), state->authoritative));
+
+ log_authentication_event(state->auth_ctx->msg_ctx,
+ state->auth_ctx->lp_ctx,
+ state->user_info, status,
+ NULL, NULL, NULL, NULL);
tevent_req_received(req);
return status;
}
state->user_info_dc->info->domain_name,
state->user_info_dc->info->account_name));
+ log_authentication_event(state->auth_ctx->msg_ctx,
+ state->auth_ctx->lp_ctx,
+ state->user_info, status,
+ state->user_info_dc->info->domain_name,
+ state->user_info_dc->info->account_name,
+ NULL,
+ &state->user_info_dc->sids[0]);
+
*user_info_dc = talloc_move(mem_ctx, &state->user_info_dc);
tevent_req_received(req);
const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
{
char **auth_methods = NULL;
+ const char **const_auth_methods = NULL;
+
+ /*
+ * As 'auth methods' is deprecated it will be removed
+ * in future releases again, but for now give
+ * admins the flexibility to configure, the behavior
+ * from Samba 4.6: "auth methods = anonymous sam_ignoredomain",
+ * for a while.
+ */
+ const_auth_methods = lpcfg_auth_methods(lp_ctx);
+ if (const_auth_methods != NULL) {
+ DBG_NOTICE("using deprecated 'auth methods' values.\n");
+ return const_auth_methods;
+ }
switch (lpcfg_server_role(lp_ctx)) {
case ROLE_STANDALONE:
auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL);
break;
case ROLE_DOMAIN_MEMBER:
- auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL);
+ auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
break;
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
case ROLE_ACTIVE_DIRECTORY_DC:
- auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL);
+ /*
+ * TODO: we should replace "winbind_rodc sam_failtrusts" with "winbind"
+ * if everything (gensec/auth4) is fully async without nested
+ * event loops!
+ *
+ * But for now we'll fail authentications for trusted
+ * domain consistently with NT_STATUS_NO_TRUST_LSA_SECRET,
+ * instead of silently mapping to local users.
+ */
+ auth_methods = str_list_make(mem_ctx,
+ "anonymous sam "
+ "winbind_rodc sam_failtrusts "
+ "sam_ignoredomain",
+ NULL);
break;
}
return discard_const_p(const char *, auth_methods);
return status;
}
+_PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct imessaging_context *msg,
+ struct loadparm_context *lp_ctx,
+ struct auth4_context **auth_ctx)
+{
+ return auth_context_create(mem_ctx, ev, msg, lp_ctx, auth_ctx);
+}
+
/* the list of currently registered AUTH backends */
static struct auth_backend {
const struct auth_operations *ops;