mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
auth: Provide a way to use the auth stack for winbindd authentication
This adds in flags that allow winbindd to request authentication without directly calling into the auth_sam module. That in turn will allow winbindd to call auth_samba4 and so permit winbindd operation in the AD DC. Andrew Bartlett Change-Id: I27d11075eb8e1a54f034ee2fdcb05360b4203567 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
parent
2e961bf598
commit
597d2a7a29
@ -25,7 +25,9 @@
|
||||
#define USER_INFO_CASE_INSENSITIVE_USERNAME 0x01 /* username may be in any case */
|
||||
#define USER_INFO_CASE_INSENSITIVE_PASSWORD 0x02 /* password may be in any case */
|
||||
#define USER_INFO_DONT_CHECK_UNIX_ACCOUNT 0x04 /* don't check unix account status */
|
||||
#define USER_INFO_INTERACTIVE_LOGON 0x08 /* don't check unix account status */
|
||||
#define USER_INFO_INTERACTIVE_LOGON 0x08 /* Interactive logon */
|
||||
#define USER_INFO_LOCAL_SAM_ONLY 0x10 /* Only authenticate against the local SAM */
|
||||
#define USER_INFO_INFO3_AND_NO_AUTHZ 0x20 /* Only fill in server_info->info3 and do not do any authorization steps */
|
||||
|
||||
enum auth_password_state {
|
||||
AUTH_PASSWORD_PLAIN = 1,
|
||||
@ -77,6 +79,8 @@ struct loadparm_context;
|
||||
struct ldb_context;
|
||||
struct smb_krb5_context;
|
||||
|
||||
#define AUTH_METHOD_LOCAL_SAM 0x01
|
||||
|
||||
struct auth4_context {
|
||||
struct {
|
||||
/* Who set this up in the first place? */
|
||||
|
@ -210,6 +210,11 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
NTSTATUS result;
|
||||
|
||||
if (user_info->flags & USER_INFO_LOCAL_SAM_ONLY
|
||||
&& !(auth_method->flags & AUTH_METHOD_LOCAL_SAM)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp_ctx = talloc_named(mem_ctx,
|
||||
0,
|
||||
"%s authentication for user %s\\%s",
|
||||
@ -253,7 +258,10 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
|
||||
|
||||
if (NT_STATUS_IS_OK(nt_status)) {
|
||||
unix_username = (*pserver_info)->unix_name;
|
||||
if (!(*pserver_info)->guest) {
|
||||
|
||||
/* We skip doing this step if the caller asked us not to */
|
||||
if (!(user_info->flags & USER_INFO_INFO3_AND_NO_AUTHZ)
|
||||
&& !(*pserver_info)->guest) {
|
||||
const char *rhost;
|
||||
|
||||
if (tsocket_address_is_inet(user_info->remote_host, "ip")) {
|
||||
|
@ -121,7 +121,7 @@ static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *par
|
||||
}
|
||||
result->auth = auth_samstrict_auth;
|
||||
result->name = "sam";
|
||||
|
||||
result->flags = AUTH_METHOD_LOCAL_SAM;
|
||||
*auth_method = result;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -145,14 +145,23 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
nt_status = make_server_info_info3(mem_ctx, user_info->client.account_name,
|
||||
user_info->mapped.domain_name, server_info,
|
||||
info3);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(10, ("make_server_info_info3 failed: %s\n",
|
||||
nt_errstr(nt_status)));
|
||||
TALLOC_FREE(frame);
|
||||
return nt_status;
|
||||
if (user_info->flags & USER_INFO_INFO3_AND_NO_AUTHZ) {
|
||||
*server_info = make_server_info(mem_ctx);
|
||||
if (*server_info == NULL) {
|
||||
nt_status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
(*server_info)->info3 = talloc_steal(*server_info, info3);
|
||||
|
||||
} else {
|
||||
nt_status = make_server_info_info3(mem_ctx, user_info->client.account_name,
|
||||
user_info->mapped.domain_name, server_info,
|
||||
info3);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(10, ("make_server_info_info3 failed: %s\n",
|
||||
nt_errstr(nt_status)));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
nt_status = NT_STATUS_OK;
|
||||
@ -356,6 +365,7 @@ static NTSTATUS auth_init_samba4(struct auth_context *auth_context,
|
||||
result->auth = check_samba4_security;
|
||||
result->prepare_gensec = prepare_gensec;
|
||||
result->make_auth4_context = make_auth4_context_s4;
|
||||
result->flags = AUTH_METHOD_LOCAL_SAM;
|
||||
|
||||
if (param && *param) {
|
||||
auth_context->forced_samba4_methods = talloc_strdup(result, param);
|
||||
|
@ -107,6 +107,8 @@ typedef struct auth_methods
|
||||
/* Used to keep tabs on things like the cli for SMB server authentication */
|
||||
void *private_data;
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
} auth_methods;
|
||||
|
||||
typedef NTSTATUS (*auth_init_function)(struct auth_context *, const char *, struct auth_methods **);
|
||||
@ -130,7 +132,8 @@ enum session_key_use_intent {
|
||||
|
||||
/* Changed from 1 -> 2 to add the logon_parameters field. */
|
||||
/* Changed from 2 -> 3 when we reworked many auth structures to use IDL or be in common with Samba4 */
|
||||
#define AUTH_INTERFACE_VERSION 3
|
||||
/* Changed from 3 -> 4 when we reworked added the flags */
|
||||
#define AUTH_INTERFACE_VERSION 4
|
||||
|
||||
#include "auth/proto.h"
|
||||
|
||||
|
@ -1212,13 +1212,16 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
|
||||
const DATA_BLOB *nt_resp,
|
||||
struct netr_SamInfo3 **pinfo3)
|
||||
{
|
||||
struct auth_context *auth_context;
|
||||
struct auth_serversupplied_info *server_info;
|
||||
struct auth_usersupplied_info *user_info = NULL;
|
||||
struct tsocket_address *local;
|
||||
struct netr_SamInfo3 *info3;
|
||||
NTSTATUS status;
|
||||
int rc;
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
rc = tsocket_address_inet_from_strings(mem_ctx,
|
||||
rc = tsocket_address_inet_from_strings(frame,
|
||||
"ip",
|
||||
"127.0.0.1",
|
||||
0,
|
||||
@ -1235,13 +1238,49 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
user_info->logon_parameters = logon_parameters;
|
||||
|
||||
/* We don't want any more mapping of the username */
|
||||
user_info->mapped_state = True;
|
||||
|
||||
status = check_sam_security_info3(challenge, mem_ctx, user_info,
|
||||
pinfo3);
|
||||
/* We don't want to come back to winbindd or to do PAM account checks */
|
||||
user_info->flags |= USER_INFO_LOCAL_SAM_ONLY | USER_INFO_INFO3_AND_NO_AUTHZ;
|
||||
|
||||
status = make_auth_context_fixed(frame, &auth_context, challenge->data);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status)));
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = auth_check_ntlm_password(mem_ctx,
|
||||
auth_context,
|
||||
user_info,
|
||||
&server_info);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
|
||||
if (info3 == NULL) {
|
||||
TALLOC_FREE(frame);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
status = serverinfo_to_SamInfo3(server_info, info3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(frame);
|
||||
TALLOC_FREE(info3);
|
||||
DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
return status;
|
||||
}
|
||||
|
||||
*pinfo3 = info3;
|
||||
DEBUG(10, ("Authenticaticating user %s\\%s returned %s\n", domain,
|
||||
user, nt_errstr(status)));
|
||||
TALLOC_FREE(frame);
|
||||
|
@ -72,6 +72,7 @@ struct auth_operations {
|
||||
const char *principal,
|
||||
struct ldb_dn *user_dn,
|
||||
struct auth_user_info_dc **interim_info);
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct auth_method_context {
|
||||
|
@ -342,6 +342,11 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
|
||||
|
||||
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;
|
||||
|
@ -677,14 +677,16 @@ static const struct auth_operations sam_ignoredomain_ops = {
|
||||
.name = "sam_ignoredomain",
|
||||
.want_check = authsam_ignoredomain_want_check,
|
||||
.check_password = authsam_check_password_internals,
|
||||
.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
|
||||
.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
|
||||
.flags = AUTH_METHOD_LOCAL_SAM
|
||||
};
|
||||
|
||||
static const struct auth_operations sam_ops = {
|
||||
.name = "sam",
|
||||
.want_check = authsam_want_check,
|
||||
.check_password = authsam_check_password_internals,
|
||||
.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
|
||||
.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
|
||||
.flags = AUTH_METHOD_LOCAL_SAM
|
||||
};
|
||||
|
||||
_PUBLIC_ NTSTATUS auth4_sam_init(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user