NTSTATUS nt_status;
struct auth_user_info_dc *user_info_dc;
struct auth4_context *auth4_context;
+ uint8_t authoritative = 0;
nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
- nt_status = auth_check_password(auth4_context, auth4_context, user_info, &user_info_dc);
+ nt_status = auth_check_password(auth4_context, auth4_context, user_info,
+ &user_info_dc, &authoritative);
if (!NT_STATUS_IS_OK(nt_status)) {
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
+ authoritative == 0)
+ {
+ nt_status = NT_STATUS_NOT_IMPLEMENTED;
+ }
TALLOC_FREE(auth4_context);
TALLOC_FREE(frame);
return nt_status;
}
-
+
nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
user_info_dc,
&info3);
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);
NTSTATUS auth4_init(void);
NTSTATUS auth_register(const struct auth_operations *ops);
NTSTATUS server_service_auth_init(void);
const struct auth_usersupplied_info *user_info);
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);
bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx);
NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by);
_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;
{
struct auth_user_info_dc *user_info_dc;
NTSTATUS status;
+ uint8_t authoritative = 0;
status = auth_check_password(auth_ctx, mem_ctx, user_info,
- &user_info_dc);
+ &user_info_dc, &authoritative);
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,
return NULL;
}
+ /*
+ * We are authoritative by default.
+ */
+ state->authoritative = 1;
state->auth_ctx = auth_ctx;
state->user_info = user_info;
}
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;
+ *pauthoritative = state->authoritative;
+
if (tevent_req_is_nterror(req, &status)) {
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));
tevent_req_received(req);
return status;
}
struct auth_usersupplied_info *user_info;
struct auth_user_info_dc *user_info_dc;
NTSTATUS nt_status;
+ uint8_t authoritative = 0;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
- nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc);
+ nt_status = auth_check_password(auth_context, tmp_ctx, user_info,
+ &user_info_dc, &authoritative);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(tmp_ctx);
return nt_status;
return NT_STATUS_INVALID_PARAMETER;
}
- nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc);
- /* TODO: set *r->out.authoritative = 0 on specific errors */
+ nt_status = auth_check_password(auth_context, mem_ctx, user_info,
+ &user_info_dc, r->out.authoritative);
NT_STATUS_NOT_OK_RETURN(nt_status);
switch (r->in.validation_level) {
struct auth_session_info *session_info;
struct smbsrv_session *smb_sess;
NTSTATUS status;
+ uint8_t authoritative = 0;
uint32_t flags;
- status = auth_check_password_recv(subreq, req, &user_info_dc);
+ status = auth_check_password_recv(subreq, req, &user_info_dc,
+ &authoritative);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) goto failed;
struct auth_user_info_dc *user_info_dc = NULL;
struct auth_session_info *session_info;
struct smbsrv_session *smb_sess;
-
+ uint8_t authoritative = 0;
uint32_t flags;
NTSTATUS status;
- status = auth_check_password_recv(subreq, req, &user_info_dc);
+ status = auth_check_password_recv(subreq, req, &user_info_dc,
+ &authoritative);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) goto failed;