diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
commit | 6da26870e0ae5acd6ff49a30ec2f6886b44d095e (patch) | |
tree | 850c71039563c16a5d563c47e7ba2ab645baf198 /source4/auth | |
parent | 6925a799d04c6fa59dd2ddef1f5510f9bb7d17d1 (diff) | |
parent | 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 (diff) | |
download | samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.gz samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.bz2 samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.zip |
Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16
Diffstat (limited to 'source4/auth')
30 files changed, 660 insertions, 291 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 9eb3e7db6f..04731af019 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -43,7 +43,7 @@ struct loadparm_context; /* version 3 - subsequent samba4 version - abartlet */ /* version 4 - subsequent samba4 version - metze */ /* version 0 - till samba4 is stable - metze */ -#define AUTH_INTERFACE_VERSION 0 +#define AUTH4_INTERFACE_VERSION 0 #define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */ #define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */ @@ -51,7 +51,7 @@ struct loadparm_context; struct auth_method_context; struct auth_check_password_request; -struct auth_context; +struct auth4_context; struct auth_session_info; struct ldb_dn; @@ -78,7 +78,7 @@ struct auth_operations { /* Lookup a 'session info interim' return based only on the principal or DN */ NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **interim_info); @@ -86,13 +86,13 @@ struct auth_operations { struct auth_method_context { struct auth_method_context *prev, *next; - struct auth_context *auth_ctx; + struct auth4_context *auth_ctx; const struct auth_operations *ops; int depth; void *private_data; }; -struct auth_context { +struct auth4_context { struct { /* Who set this up in the first place? */ const char *set_by; @@ -109,7 +109,7 @@ struct auth_context { struct tevent_context *event_ctx; /* the messaging context which can be used by backends */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* loadparm context */ struct loadparm_context *lp_ctx; @@ -117,25 +117,25 @@ struct auth_context { /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */ struct ldb_context *sam_ctx; - NTSTATUS (*check_password)(struct auth_context *auth_ctx, + NTSTATUS (*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); - NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]); + NTSTATUS (*get_challenge)(struct auth4_context *auth_ctx, uint8_t chal[8]); - bool (*challenge_may_be_modified)(struct auth_context *auth_ctx); + bool (*challenge_may_be_modified)(struct auth4_context *auth_ctx); - NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); + NTSTATUS (*set_challenge)(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc); NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct auth_user_info_dc *user_info_dc, uint32_t session_info_flags, struct auth_session_info **session_info); @@ -151,7 +151,7 @@ struct auth_critical_sizes { int sizeof_auth_user_info_dc; }; - NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, + NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted); @@ -165,7 +165,7 @@ struct ldb_context; struct gensec_security; struct cli_credentials; -NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]); +NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]); NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, uint32_t logon_parameters, @@ -175,10 +175,7 @@ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, const char *name_for_logs, bool allow_domain_trust, bool password_change); -NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx, - struct ldb_val *dn_val, const bool only_childs, const char *filter, - TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids, - unsigned int *num_res_sids); + struct auth_session_info *system_session(struct loadparm_context *lp_ctx); NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, const char *netbios_name, @@ -193,20 +190,20 @@ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, - struct auth_context **auth_ctx); + struct auth4_context **auth_ctx); const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, - struct auth_context **auth_ctx); -NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx); + struct auth4_context **auth_ctx); +NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth4_context **auth_ctx); -NTSTATUS auth_check_password(struct auth_context *auth_ctx, +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); @@ -215,7 +212,7 @@ NTSTATUS auth_register(const struct auth_operations *ops); NTSTATUS server_service_auth_init(void); NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, const char *nt4_domain, const char *nt4_username, @@ -225,24 +222,24 @@ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, 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); -bool auth_challenge_may_be_modified(struct auth_context *auth_ctx); -NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); +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); NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc); NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *server_credentials, const char *target_service, diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 015c549693..83e90344bf 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -64,6 +64,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->principal = NULL; cred->salt_principal = NULL; cred->impersonate_principal = NULL; + cred->self_service = NULL; cred->target_service = NULL; cred->bind_dn = NULL; diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h index 0b0de59752..f8fa2f864b 100644 --- a/source4/auth/credentials/credentials.h +++ b/source4/auth/credentials/credentials.h @@ -84,6 +84,7 @@ struct cli_credentials { const char *principal; char *salt_principal; char *impersonate_principal; + char *self_service; char *target_service; const char *bind_dn; @@ -277,10 +278,13 @@ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, void cli_credentials_invalidate_ccache(struct cli_credentials *cred, enum credentials_obtained obtained); void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal); -void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal); +void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service); void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal); const char *cli_credentials_get_salt_principal(struct cli_credentials *cred); const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred); +const char *cli_credentials_get_self_service(struct cli_credentials *cred); const char *cli_credentials_get_target_service(struct cli_credentials *cred); enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds); enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds); diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index d3925a01f6..1643197004 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -235,9 +235,15 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, if (!ccache_name) { must_free_cc_name = true; - ccache_name = talloc_asprintf(ccc, "MEMORY:%p", - ccc); - + + if (lpcfg_parm_bool(lp_ctx, NULL, "credentials", "krb5_cc_file", false)) { + ccache_name = talloc_asprintf(ccc, "FILE:/tmp/krb5_cc_samba_%u_%p", + (unsigned int)getpid(), ccc); + } else { + ccache_name = talloc_asprintf(ccc, "MEMORY:%p", + ccc); + } + if (!ccache_name) { talloc_free(ccc); (*error_string) = strerror(ENOMEM); @@ -288,8 +294,38 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, if (cred->ccache_obtained >= cred->ccache_threshold && cred->ccache_obtained > CRED_UNINITIALISED) { - *ccc = cred->ccache; - return 0; + time_t lifetime; + bool expired = false; + ret = krb5_cc_get_lifetime(cred->ccache->smb_krb5_context->krb5_context, + cred->ccache->ccache, &lifetime); + if (ret == KRB5_CC_END) { + /* If we have a particular ccache set, without + * an initial ticket, then assume there is a + * good reason */ + } else if (ret == 0) { + if (lifetime == 0) { + DEBUG(3, ("Ticket in credentials cache for %s expired, will refresh\n", + cli_credentials_get_principal(cred, cred))); + expired = true; + } else if (lifetime < 300) { + DEBUG(3, ("Ticket in credentials cache for %s will shortly expire (%u secs), will refresh\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + expired = true; + } + } else { + (*error_string) = talloc_asprintf(cred, "failed to get ccache lifetime: %s\n", + smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context, + ret, cred)); + return ret; + } + + DEBUG(5, ("Ticket in credentials cache for %s will expire in %u secs\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + + if (!expired) { + *ccc = cred->ccache; + return 0; + } } if (cli_credentials_is_anonymous(cred)) { (*error_string) = "Cannot get anonymous kerberos credentials"; @@ -351,7 +387,7 @@ void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, } /* Now that we know that the data is 'this specified', then * don't allow something less 'known' to be returned as a - * ccache. Ie, if the username is on the commmand line, we + * ccache. Ie, if the username is on the command line, we * don't want to later guess to use a file-based ccache */ if (obtained > cred->client_gss_creds_threshold) { cred->client_gss_creds_threshold = obtained; @@ -384,7 +420,7 @@ _PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred, } /* Now that we know that the data is 'this specified', then * don't allow something less 'known' to be returned as a - * ccache. Ie, if the username is on the commmand line, we + * ccache. i.e, if the username is on the command line, we * don't want to later guess to use a file-based ccache */ if (obtained > cred->ccache_threshold) { cred->ccache_threshold = obtained; @@ -416,14 +452,41 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && cred->client_gss_creds_obtained > CRED_UNINITIALISED) { - *_gcc = cred->client_gss_creds; - return 0; + bool expired = false; + OM_uint32 lifetime = 0; + gss_cred_usage_t usage = 0; + maj_stat = gss_inquire_cred(&min_stat, cred->client_gss_creds->creds, + NULL, &lifetime, &usage, NULL); + if (maj_stat == GSS_S_CREDENTIALS_EXPIRED) { + DEBUG(3, ("Credentials for %s expired, must refresh credentials cache\n", cli_credentials_get_principal(cred, cred))); + expired = true; + } else if (maj_stat == GSS_S_COMPLETE && lifetime < 300) { + DEBUG(3, ("Credentials for %s will expire shortly (%u sec), must refresh credentials cache\n", cli_credentials_get_principal(cred, cred), lifetime)); + expired = true; + } else if (maj_stat != GSS_S_COMPLETE) { + *error_string = talloc_asprintf(cred, "inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", + gssapi_error_string(cred, maj_stat, min_stat, NULL)); + return EINVAL; + } + if (expired) { + cli_credentials_unconditionally_invalidate_client_gss_creds(cred); + } else { + DEBUG(5, ("GSSAPI credentials for %s will expire in %u secs\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + + *_gcc = cred->client_gss_creds; + return 0; + } } ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache, error_string); if (ret) { - DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); + if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) { + DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", error_message(ret))); + } else { + DEBUG(4, ("Failed to get kerberos credentials: %s\n", error_message(ret))); + } return ret; } @@ -781,26 +844,43 @@ _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, c cred->salt_principal = talloc_strdup(cred, principal); } -/* The 'impersonate_principal' is used to allow on Kerberos principal +/* The 'impersonate_principal' is used to allow one Kerberos principal * (and it's associated keytab etc) to impersonate another. The * ability to do this is controlled by the KDC, but it is generally * permitted to impersonate anyone to yourself. This allows any * member of the domain to get the groups of a user. This is also * known as S4U2Self */ -const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) +_PUBLIC_ const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) { return cred->impersonate_principal; } -_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal) +/* + * The 'self_service' is the service principal that + * represents the same object (by its objectSid) + * as the client principal (typically our machine account). + * When trying to impersonate 'impersonate_principal' with + * S4U2Self. + */ +_PUBLIC_ const char *cli_credentials_get_self_service(struct cli_credentials *cred) +{ + return cred->self_service; +} + +_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service) { talloc_free(cred->impersonate_principal); cred->impersonate_principal = talloc_strdup(cred, principal); + talloc_free(cred->self_service); + cred->self_service = talloc_strdup(cred, self_service); + cli_credentials_set_kerberos_state(cred, CRED_MUST_USE_KERBEROS); } -/* when impersonating for S4U2Self we need to set the target principal - * to ourself, as otherwise we would need additional rights. +/* + * when impersonating for S4U2proxy we need to set the target principal. * Similarly, we may only be authorized to do general impersonation to * some particular services. * diff --git a/source4/auth/gensec/cyrus_sasl.c b/source4/auth/gensec/cyrus_sasl.c index bd7664878c..4a4422645d 100644 --- a/source4/auth/gensec/cyrus_sasl.c +++ b/source4/auth/gensec/cyrus_sasl.c @@ -99,12 +99,12 @@ static int gensec_sasl_get_password(sasl_conn_t *conn, void *context, int id, *psecret = NULL; return SASL_OK; } - secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)); + secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)+1); if (!secret) { return SASL_NOMEM; } secret->len = strlen(password); - safe_strcpy((char*)secret->data, password, secret->len+1); + strlcpy((char*)secret->data, password, secret->len+1); *psecret = secret; return SASL_OK; } diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index e632aec2dc..7e6a83d51f 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -514,7 +514,7 @@ const char **gensec_security_oids(struct gensec_security *gensec_security, static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security) { if (ev == NULL) { @@ -604,7 +604,7 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security) { NTSTATUS status; @@ -639,7 +639,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) if (gensec_security->ops->client_start) { status = gensec_security->ops->client_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("Failed to start GENSEC client mech %s: %s\n", + DEBUG(gensec_security->subcontext?4:2, ("Failed to start GENSEC client mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; @@ -1406,7 +1406,7 @@ bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism /* initialise the GENSEC subsystem */ -_PUBLIC_ NTSTATUS gensec_init(struct loadparm_context *lp_ctx) +_PUBLIC_ NTSTATUS gensec_init(void) { static bool initialized = false; #define _MODULE_PROTO(init) extern NTSTATUS init(void); @@ -1417,7 +1417,7 @@ _PUBLIC_ NTSTATUS gensec_init(struct loadparm_context *lp_ctx) if (initialized) return NT_STATUS_OK; initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "gensec"); + shared_init = load_samba_modules(NULL, "gensec"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 48268c421e..e42b4aa5d2 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -165,7 +165,7 @@ struct gensec_security { /* When we are a server, this may be filled in to provide an * NTLM authentication backend, and user lookup (such as if no * PAC is found) */ - struct auth_context *auth_context; + struct auth4_context *auth_context; }; /* this structure is used by backends to determine the size of some critical types */ @@ -179,7 +179,7 @@ struct gensec_critical_sizes { struct gensec_security; struct socket_context; -struct auth_context; +struct auth4_context; struct auth_user_info_dc; NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, @@ -242,7 +242,7 @@ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid); const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string); struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security); -NTSTATUS gensec_init(struct loadparm_context *lp_ctx); +NTSTATUS gensec_init(void); NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, @@ -270,7 +270,7 @@ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security); NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info); diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 59029e6fc9..72c6b3f991 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -47,44 +47,6 @@ _PUBLIC_ NTSTATUS gensec_gssapi_init(void); static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); -static char *gssapi_error_string(TALLOC_CTX *mem_ctx, - OM_uint32 maj_stat, OM_uint32 min_stat, - const gss_OID mech) -{ - OM_uint32 disp_min_stat, disp_maj_stat; - gss_buffer_desc maj_error_message; - gss_buffer_desc min_error_message; - char *maj_error_string, *min_error_string; - OM_uint32 msg_ctx = 0; - - char *ret; - - maj_error_message.value = NULL; - min_error_message.value = NULL; - maj_error_message.length = 0; - min_error_message.length = 0; - - disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, - mech, &msg_ctx, &maj_error_message); - disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, - mech, &msg_ctx, &min_error_message); - - maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length); - - min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length); - - ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string); - - talloc_free(maj_error_string); - talloc_free(min_error_string); - - gss_release_buffer(&disp_min_stat, &maj_error_message); - gss_release_buffer(&disp_min_stat, &min_error_message); - - return ret; -} - - static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { OM_uint32 maj_stat, min_stat; @@ -340,6 +302,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + if (cli_credentials_get_impersonate_principal(creds)) { + gensec_gssapi_state->want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG); + } + gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); if (gensec_gssapi_state->target_principal) { name_type = GSS_C_NULL_OID; @@ -557,6 +523,65 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gss_release_buffer(&min_stat2, &output_token); return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else if (maj_stat == GSS_S_CONTEXT_EXPIRED) { + gss_cred_id_t creds; + gss_name_t name; + gss_buffer_desc buffer; + OM_uint32 lifetime = 0; + gss_cred_usage_t usage; + const char *role = NULL; + DEBUG(0, ("GSS %s Update(krb5)(%d) Update failed, credentials expired during GSSAPI handshake!\n", + role, + gensec_gssapi_state->gss_exchange_count)); + + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + creds = gensec_gssapi_state->client_cred->creds; + role = "client"; + case GENSEC_SERVER: + creds = gensec_gssapi_state->server_cred->creds; + role = "server"; + } + + maj_stat = gss_inquire_cred(&min_stat, + creds, + &name, &lifetime, &usage, NULL); + + if (maj_stat == GSS_S_COMPLETE) { + const char *usage_string; + switch (usage) { + case GSS_C_BOTH: + usage_string = "GSS_C_BOTH"; + break; + case GSS_C_ACCEPT: + usage_string = "GSS_C_ACCEPT"; + break; + case GSS_C_INITIATE: + usage_string = "GSS_C_INITIATE"; + break; + } + maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); + if (maj_stat) { + buffer.value = NULL; + buffer.length = 0; + } + if (lifetime > 0) { + DEBUG(0, ("GSSAPI gss_inquire_cred indicates expiry of %*.*s in %u sec for %s\n", + (int)buffer.length, (int)buffer.length, (char *)buffer.value, + lifetime, usage_string)); + } else { + DEBUG(0, ("GSSAPI gss_inquire_cred indicates %*.*s has already expired for %s\n", + (int)buffer.length, (int)buffer.length, (char *)buffer.value, + usage_string)); + } + gss_release_buffer(&min_stat, &buffer); + gss_release_name(&min_stat, &name); + } else if (maj_stat != GSS_S_COMPLETE) { + DEBUG(0, ("inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + } + return NT_STATUS_INVALID_PARAMETER; } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { switch (min_stat) { case KRB5KRB_AP_ERR_TKT_NYV: @@ -1262,7 +1287,6 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi struct auth_user_info_dc *user_info_dc = NULL; struct auth_session_info *session_info = NULL; OM_uint32 maj_stat, min_stat; - gss_buffer_desc pac; DATA_BLOB pac_blob; struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; @@ -1277,25 +1301,15 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); - maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_WIN2K_PAC, - &pac); - - - if (maj_stat == 0) { - pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); - gss_release_buffer(&min_stat, &pac); - - } else { - pac_blob = data_blob(NULL, 0); - } + nt_status = gssapi_obtain_pac_blob(mem_ctx, gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->client_name, + &pac_blob); /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some * kind... */ - if (pac_blob.length) { + if (NT_STATUS_IS_OK(nt_status)) { pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); if (!pac_srv_sig) { talloc_free(mem_ctx); diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index fd9726eb75..503974aaa3 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -127,7 +127,7 @@ static PyObject *py_gensec_start_client(PyTypeObject *type, PyObject *args, PyOb return NULL; } - status = gensec_init(settings->lp_ctx); + status = gensec_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); PyObject_DEL(self); @@ -156,7 +156,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb PyObject *py_auth_context = Py_None; struct tevent_context *ev; struct gensec_security *gensec; - struct auth_context *auth_context = NULL; + struct auth4_context *auth_context = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) return NULL; @@ -201,7 +201,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb } if (py_auth_context != Py_None) { - auth_context = py_talloc_get_type(py_auth_context, struct auth_context); + auth_context = py_talloc_get_type(py_auth_context, struct auth4_context); if (!auth_context) { PyErr_Format(PyExc_TypeError, "Expected auth.AuthContext for auth_context argument, got %s", @@ -210,7 +210,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb } } - status = gensec_init(settings->lp_ctx); + status = gensec_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); PyObject_DEL(self); diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 0db0dd3ced..0fc9d143ab 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -81,86 +81,387 @@ The impersonate_principal is the principal if NULL, or the principal to impersonate - The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) + The self_service, should be the local service (for S4U2Self if impersonate_principal is given). + + The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or a remote service (for S4U2Proxy) */ - krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - krb5_principal principal, const char *password, - krb5_principal impersonate_principal, const char *target_service, + krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache store_cc, + krb5_principal init_principal, + const char *init_password, + krb5_principal impersonate_principal, + const char *self_service, + const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time) { krb5_error_code code = 0; - krb5_creds my_creds; - krb5_creds *impersonate_creds; krb5_get_creds_opt options; + krb5_principal store_principal; + krb5_creds store_creds; + krb5_creds *s4u2self_creds; + Ticket s4u2self_ticket; + size_t s4u2self_ticketlen; + krb5_creds *s4u2proxy_creds; + krb5_principal self_princ; + bool s4u2proxy; + krb5_principal target_princ; + krb5_ccache tmp_cc; + const char *self_realm; + krb5_principal blacklist_principal = NULL; + krb5_principal whitelist_principal = NULL; - /* If we are not impersonating, then get this ticket for the + if (impersonate_principal && self_service == NULL) { + return EINVAL; + } + + /* + * If we are not impersonating, then get this ticket for the * target service, otherwise a krbtgt, and get the next ticket - * for the target */ - if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, - NULL, NULL, - 0, - impersonate_principal ? NULL : target_service, - krb_options))) { + * for the target + */ + code = krb5_get_init_creds_password(ctx, &store_creds, + init_principal, + init_password, + NULL, NULL, + 0, + impersonate_principal ? NULL : target_service, + krb_options); + if (code != 0) { return code; } - if ((code = krb5_cc_initialize(ctx, cc, principal))) { - krb5_free_cred_contents(ctx, &my_creds); + store_principal = init_principal; + + if (impersonate_principal == NULL) { + goto store; + } + + /* + * We are trying S4U2Self now: + * + * As we do not want to expose our TGT in the + * krb5_ccache, which is also holds the impersonated creds. + * + * Some low level krb5/gssapi function might use the TGT + * identity and let the client act as our machine account. + * + * We need to avoid that and use a temporary krb5_ccache + * in order to pass our TGT to the krb5_get_creds() function. + */ + code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); return code; } - - if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_free_cred_contents(ctx, &my_creds); + + code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client); + if (code != 0) { + krb5_cc_destroy(ctx, tmp_cc); + krb5_free_cred_contents(ctx, &store_creds); return code; } - - if (expire_time) { - *expire_time = (time_t) my_creds.times.endtime; + + code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + krb5_cc_destroy(ctx, tmp_cc); + return code; } - if (kdc_time) { - *kdc_time = (time_t) my_creds.times.starttime; + /* + * we need to remember the client principal of our + * TGT and make sure the KDC does not return this + * in the impersonated tickets. This can happen + * if the KDC does not support S4U2Self and S4U2Proxy. + */ + blacklist_principal = store_creds.client; + store_creds.client = NULL; + krb5_free_cred_contents(ctx, &store_creds); + + /* + * Check if we also need S4U2Proxy or if S4U2Self is + * enough in order to get a ticket for the target. + */ + if (target_service == NULL) { + s4u2proxy = false; + } else if (strcmp(target_service, self_service) == 0) { + s4u2proxy = false; + } else { + s4u2proxy = true; } - krb5_free_cred_contents(ctx, &my_creds); - - if (code == 0 && impersonate_principal) { - krb5_principal target_princ; - if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { - return code; - } + /* + * For S4U2Self we need our own service principal, + * which belongs to our own realm (available on + * our client principal). + */ + self_realm = krb5_principal_get_realm(ctx, init_principal); - if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { - krb5_get_creds_opt_free(ctx, options); - return code; - } + code = krb5_parse_name(ctx, self_service, &self_princ); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } - if ((code = krb5_parse_name(ctx, target_service, &target_princ))) { - krb5_get_creds_opt_free(ctx, options); - return code; - } + code = krb5_principal_set_realm(ctx, self_princ, self_realm); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } - if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) { - krb5_get_creds_opt_free(ctx, options); - krb5_free_principal(ctx, target_princ); - return code; - } + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } - if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) { - krb5_free_principal(ctx, target_princ); - krb5_get_creds_opt_free(ctx, options); + if (s4u2proxy) { + /* + * If we want S4U2Proxy, we need the forwardable flag + * on the S4U2Self ticket. + */ + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); + } + + code = krb5_get_creds_opt_set_impersonate(ctx, options, + impersonate_principal); + if (code != 0) { + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, blacklist_principal); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds(ctx, options, tmp_cc, + self_princ, &s4u2self_creds); + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, self_princ); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + if (!s4u2proxy) { + krb5_cc_destroy(ctx, tmp_cc); + + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + code = krb5_copy_creds_contents(ctx, s4u2self_creds, + &store_creds); + krb5_free_creds(ctx, s4u2self_creds); + if (code != 0) { return code; } + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + goto store; + } + + /* + * We are trying S4U2Proxy: + * + * We need the ticket from the S4U2Self step + * and our TGT in order to get the delegated ticket. + */ + code = decode_Ticket((const uint8_t *)s4u2self_creds->ticket.data, + s4u2self_creds->ticket.length, + &s4u2self_ticket, + &s4u2self_ticketlen); + if (code != 0) { + krb5_free_creds(ctx, s4u2self_creds); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + /* + * we need to remember the client principal of the + * S4U2Self stage and as it needs to match the one we + * will get for the S4U2Proxy stage. We need this + * in order to detect KDCs which does not support S4U2Proxy. + */ + whitelist_principal = s4u2self_creds->client; + s4u2self_creds->client = NULL; + krb5_free_creds(ctx, s4u2self_creds); + + /* + * For S4U2Proxy we also got a target service principal, + * which also belongs to our own realm (available on + * our client principal). + */ + code = krb5_parse_name(ctx, target_service, &target_princ); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_principal_set_realm(ctx, target_princ, self_realm); + if (code != 0) { + free_Ticket(&s4u2self_ticket); krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_CONSTRAINED_DELEGATION); - code = krb5_cc_store_cred(ctx, cc, impersonate_creds); + code = krb5_get_creds_opt_set_ticket(ctx, options, &s4u2self_ticket); + free_Ticket(&s4u2self_ticket); + if (code != 0) { krb5_get_creds_opt_free(ctx, options); - krb5_free_creds(ctx, impersonate_creds); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; } + code = krb5_get_creds(ctx, options, tmp_cc, + target_princ, &s4u2proxy_creds); + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, target_princ); + krb5_cc_destroy(ctx, tmp_cc); + if (code != 0) { + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + return code; + } + + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + code = krb5_copy_creds_contents(ctx, s4u2proxy_creds, + &store_creds); + krb5_free_creds(ctx, s4u2proxy_creds); + if (code != 0) { + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + return code; + } + + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + + store: + if (blacklist_principal && + krb5_principal_compare(ctx, store_creds.client, blacklist_principal)) { + char *sp = NULL; + char *ip = NULL; + + code = krb5_unparse_name(ctx, blacklist_principal, &sp); + if (code != 0) { + sp = NULL; + } + code = krb5_unparse_name(ctx, impersonate_principal, &ip); + if (code != 0) { + ip = NULL; + } + DEBUG(1, ("kerberos_kinit_password_cc: " + "KDC returned self principal[%s] while impersonating [%s]\n", + sp?sp:"<no memory>", + ip?ip:"<no memory>")); + + SAFE_FREE(sp); + SAFE_FREE(ip); + + krb5_free_principal(ctx, whitelist_principal); + krb5_free_principal(ctx, blacklist_principal); + krb5_free_cred_contents(ctx, &store_creds); + return KRB5_FWD_BAD_PRINCIPAL; + } + if (blacklist_principal) { + krb5_free_principal(ctx, blacklist_principal); + } + + if (whitelist_principal && + !krb5_principal_compare(ctx, store_creds.client, whitelist_principal)) { + char *sp = NULL; + char *ep = NULL; + + code = krb5_unparse_name(ctx, store_creds.client, &sp); + if (code != 0) { + sp = NULL; + } + code = krb5_unparse_name(ctx, whitelist_principal, &ep); + if (code != 0) { + ep = NULL; + } + DEBUG(1, ("kerberos_kinit_password_cc: " + "KDC returned wrong principal[%s] we expected [%s]\n", + sp?sp:"<no memory>", + ep?ep:"<no memory>")); + + SAFE_FREE(sp); + SAFE_FREE(ep); + + krb5_free_principal(ctx, whitelist_principal); + krb5_free_cred_contents(ctx, &store_creds); + return KRB5_FWD_BAD_PRINCIPAL; + } + if (whitelist_principal) { + krb5_free_principal(ctx, whitelist_principal); + } + + code = krb5_cc_initialize(ctx, store_cc, store_principal); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + code = krb5_cc_store_cred(ctx, store_cc, &store_creds); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + if (expire_time) { + *expire_time = (time_t) store_creds.times.endtime; + } + + if (kdc_time) { + *kdc_time = (time_t) store_creds.times.starttime; + } + + krb5_free_cred_contents(ctx, &store_creds); + return 0; } diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h index c712569e5d..31794b8e03 100644 --- a/source4/auth/kerberos/kerberos.h +++ b/source4/auth/kerberos/kerberos.h @@ -97,7 +97,9 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt); krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, krb5_principal principal, const char *password, - krb5_principal impersonate_principal, const char *target_service, + krb5_principal impersonate_principal, + const char *self_service, + const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time); krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c index 5bc80c9a58..8ce970e486 100644 --- a/source4/auth/kerberos/kerberos_pac.c +++ b/source4/auth/kerberos/kerberos_pac.c @@ -448,14 +448,14 @@ NTSTATUS kerberos_pac_blob_to_user_info_dc(TALLOC_CTX *mem_ctx, pac_blob.data, pac_blob.length, &pac); if (ret) { - return map_nt_error_from_unix(ret); + return map_nt_error_from_unix_common(ret); } ret = kerberos_pac_to_user_info_dc(mem_ctx, pac, context, user_info_dc, pac_srv_sig, pac_kdc_sig); krb5_pac_free(context, pac); if (ret) { - return map_nt_error_from_unix(ret); + return map_nt_error_from_unix_common(ret); } return NT_STATUS_OK; } diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 45b0b07e13..9a48e95c6d 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -173,7 +173,7 @@ static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx, return ret; } - /* This song-and-dance effectivly puts the principal + /* This song-and-dance effectively puts the principal * into talloc, so we can't loose it. */ talloc_set_destructor(principals[i], free_principal); i++; @@ -262,7 +262,7 @@ static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx, upper_realm, "host", salt_body, NULL); if (ret == 0) { - /* This song-and-dance effectivly puts the principal + /* This song-and-dance effectively puts the principal * into talloc, so we can't loose it. */ mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); mem_ctx->principal = *salt_princ; @@ -338,7 +338,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, const char **error_string) { krb5_error_code ret; - const char *password, *target_service; + const char *password; + const char *self_service; + const char *target_service; time_t kdc_time = 0; krb5_principal princ; krb5_principal impersonate_principal; @@ -363,6 +365,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, return ret; } + self_service = cli_credentials_get_self_service(credentials); target_service = cli_credentials_get_target_service(credentials); password = cli_credentials_get_password(credentials); @@ -403,7 +406,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, if (password) { ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, princ, password, - impersonate_principal, target_service, + impersonate_principal, + self_service, + target_service, krb_options, NULL, &kdc_time); } else if (impersonate_principal) { @@ -733,7 +738,7 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, /* Release the enumeration. We are going to * have to start this from the top again, * because deletes during enumeration may not - * always be consistant. + * always be consistent. * * Also, the enumeration locks a FILE: keytab */ diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c index db3a5375c9..fbcaad29d9 100644 --- a/source4/auth/kerberos/krb5_init_context.c +++ b/source4/auth/kerberos/krb5_init_context.c @@ -415,7 +415,7 @@ smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx, return ret; } - config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf"); + config_file = lpcfg_config_path(tmp_ctx, lp_ctx, "krb5.conf"); if (!config_file) { krb5_free_context(krb5_ctx); return ENOMEM; diff --git a/source4/auth/kerberos/wscript_build b/source4/auth/kerberos/wscript_build index 586366d422..90e8560573 100644 --- a/source4/auth/kerberos/wscript_build +++ b/source4/auth/kerberos/wscript_build @@ -4,7 +4,7 @@ bld.SAMBA_LIBRARY('authkrb5', source='kerberos.c kerberos_heimdal.c kerberos_pac.c gssapi_parse.c krb5_init_context.c keytab_copy.c', autoproto='proto.h', public_deps='krb5 ndr-krb5pac samba_socket LIBCLI_RESOLVE com_err asn1', - deps='asn1util auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP', + deps='asn1util auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP errors', private_library=True ) diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index e2deab78bc..d2464c3cbf 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -31,7 +31,7 @@ /*************************************************************************** Set a fixed challenge ***************************************************************************/ -_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by) +_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by) { auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by); NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.set_by); @@ -45,7 +45,7 @@ _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, cons /*************************************************************************** Set a fixed challenge ***************************************************************************/ -_PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) +_PUBLIC_ bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx) { return auth_ctx->challenge.may_be_modified; } @@ -54,7 +54,7 @@ _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) Try to get a challenge out of the various authentication modules. Returns a const char of length 8 bytes. ****************************************************************************/ -_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) +_PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]) { NTSTATUS nt_status; struct auth_method_context *method; @@ -104,7 +104,7 @@ PAC isn't available, and for tokenGroups in the DSDB stack. Supply either a principal or a DN ****************************************************************************/ _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc) @@ -155,7 +155,7 @@ _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, * **/ -_PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx, +_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) @@ -188,7 +188,7 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx, } struct auth_check_password_state { - struct auth_context *auth_ctx; + struct auth4_context *auth_ctx; const struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; struct auth_method_context *method; @@ -225,7 +225,7 @@ static void auth_check_password_async_trigger(struct tevent_context *ev, _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const struct auth_usersupplied_info *user_info) { struct tevent_req *req; @@ -409,7 +409,7 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req, /* Wrapper because we don't want to expose all callers to needing to * know that session_info is generated from the main ldb */ static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct auth_user_info_dc *user_info_dc, uint32_t session_info_flags, struct auth_session_info **session_info) @@ -425,13 +425,13 @@ static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, ***************************************************************************/ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, - struct auth_context **auth_ctx) + struct auth4_context **auth_ctx) { int i; - struct auth_context *ctx; + struct auth4_context *ctx; auth4_init(); @@ -440,7 +440,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** return NT_STATUS_INTERNAL_ERROR; } - ctx = talloc(mem_ctx, struct auth_context); + ctx = talloc(mem_ctx, struct auth4_context); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->challenge.set_by = NULL; ctx->challenge.may_be_modified = false; @@ -487,19 +487,21 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - const char **auth_methods = NULL; + char **auth_methods = NULL; + switch (lpcfg_server_role(lp_ctx)) { case ROLE_STANDALONE: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL); + auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL); break; case ROLE_DOMAIN_MEMBER: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL); + auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL); break; - case ROLE_DOMAIN_CONTROLLER: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); + case ROLE_DOMAIN_BDC: + case ROLE_DOMAIN_PDC: + auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL); break; } - return auth_methods; + return (const char **) auth_methods; } /*************************************************************************** @@ -508,9 +510,9 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context * ***************************************************************************/ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, - struct auth_context **auth_ctx) + struct auth4_context **auth_ctx) { NTSTATUS status; const char **auth_methods; @@ -533,7 +535,7 @@ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups) */ -NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx) +NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth4_context **auth_ctx) { NTSTATUS status; const char **auth_methods; @@ -620,10 +622,10 @@ const struct auth_operations *auth_backend_byname(const char *name) const struct auth_critical_sizes *auth_interface_version(void) { static const struct auth_critical_sizes critical_sizes = { - AUTH_INTERFACE_VERSION, + AUTH4_INTERFACE_VERSION, sizeof(struct auth_operations), sizeof(struct auth_method_context), - sizeof(struct auth_context), + sizeof(struct auth4_context), sizeof(struct auth_usersupplied_info), sizeof(struct auth_user_info_dc) }; diff --git a/source4/auth/ntlm/auth_anonymous.c b/source4/auth/ntlm/auth_anonymous.c index 6b21225aad..4b0fff03cc 100644 --- a/source4/auth/ntlm/auth_anonymous.c +++ b/source4/auth/ntlm/auth_anonymous.c @@ -24,7 +24,7 @@ #include "auth/ntlm/auth_proto.h" #include "param/param.h" -_PUBLIC_ NTSTATUS auth_anonymous_init(void); +_PUBLIC_ NTSTATUS auth4_anonymous_init(void); /** * Return a anonymous logon for anonymous users (username = "") @@ -66,7 +66,7 @@ static const struct auth_operations anonymous_auth_ops = { .check_password = anonymous_check_password }; -_PUBLIC_ NTSTATUS auth_anonymous_init(void) +_PUBLIC_ NTSTATUS auth4_anonymous_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_developer.c b/source4/auth/ntlm/auth_developer.c index da842c98ba..bc27f27fa2 100644 --- a/source4/auth/ntlm/auth_developer.c +++ b/source4/auth/ntlm/auth_developer.c @@ -24,7 +24,7 @@ #include "auth/ntlm/auth_proto.h" #include "libcli/security/security.h" -_PUBLIC_ NTSTATUS auth_developer_init(void); +_PUBLIC_ NTSTATUS auth4_developer_init(void); static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, @@ -185,7 +185,7 @@ static const struct auth_operations fixed_challenge_auth_ops = { .check_password = fixed_challenge_check_password }; -_PUBLIC_ NTSTATUS auth_developer_init(void) +_PUBLIC_ NTSTATUS auth4_developer_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index f76057a6df..87a7d27559 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -72,7 +72,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context * Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ -static NTSTATUS authsam_password_ok(struct auth_context *auth_context, +static NTSTATUS authsam_password_ok(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, uint16_t acct_flags, const struct samr_Password *lm_pwd, @@ -142,7 +142,7 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context, send a message to the drepl server telling it to initiate a REPL_SECRET getncchanges extended op to fetch the users secrets */ -static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, +static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, struct ldb_dn *user_dn) { struct dcerpc_binding_handle *irpc_handle; @@ -170,7 +170,7 @@ static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_contex } -static NTSTATUS authsam_authenticate(struct auth_context *auth_context, +static NTSTATUS authsam_authenticate(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, struct ldb_dn *domain_dn, struct ldb_message *msg, @@ -357,7 +357,7 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx, /* Wrapper for the auth subsystem pointer */ static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc) @@ -381,7 +381,7 @@ static const struct auth_operations sam_ops = { .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper }; -_PUBLIC_ NTSTATUS auth_sam_init(void) +_PUBLIC_ NTSTATUS auth4_sam_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index 7efeb9242a..9e1ceae0ca 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -27,7 +27,7 @@ #include "param/param.h" #include "libcli/resolve/resolve.h" -_PUBLIC_ NTSTATUS auth_server_init(void); +_PUBLIC_ NTSTATUS auth4_server_init(void); /* This version of 'security=server' rewirtten from scratch for Samba4 * libraries in 2008 */ @@ -223,7 +223,7 @@ static const struct auth_operations server_auth_ops = { .check_password = server_check_password }; -_PUBLIC_ NTSTATUS auth_server_init(void) +_PUBLIC_ NTSTATUS auth4_server_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index 75eabe855b..241906e281 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -30,7 +30,7 @@ */ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, const char *nt4_domain, const char *nt4_username, @@ -38,7 +38,7 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, const uint32_t logon_parameters, struct auth_session_info **session_info) { - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; NTSTATUS nt_status; diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c index 743cb8103d..d79ebc1772 100644 --- a/source4/auth/ntlm/auth_unix.c +++ b/source4/auth/ntlm/auth_unix.c @@ -28,7 +28,7 @@ #include "../libcli/auth/pam_errors.h" #include "param/param.h" -_PUBLIC_ NTSTATUS auth_unix_init(void); +_PUBLIC_ NTSTATUS auth4_unix_init(void); /* TODO: look at how to best fill in parms retrieveing a struct passwd info * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set @@ -607,12 +607,10 @@ static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp { char *username; char *password; - char *pwcopy; char *salt; char *crypted; struct passwd *pws; NTSTATUS nt_status; - int level = lpcfg_passwordlevel(lp_ctx); *ret_passwd = NULL; @@ -737,46 +735,11 @@ static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp return nt_status; } - if ( user_info->flags | USER_INFO_CASE_INSENSITIVE_PASSWORD) { - return nt_status; - } - - /* if the password was given to us with mixed case then we don't - * need to proceed as we know it hasn't been case modified by the - * client */ - if (strhasupper(password) && strhaslower(password)) { - return nt_status; - } - - /* make a copy of it */ - pwcopy = talloc_strdup(ctx, password); - if (!pwcopy) - return NT_STATUS_NO_MEMORY; - - /* try all lowercase if it's currently all uppercase */ - if (strhasupper(pwcopy)) { - strlower(pwcopy); - nt_status = password_check(username, pwcopy, crypted, salt); - if NT_STATUS_IS_OK(nt_status) { - *ret_passwd = pws; - return nt_status; - } - } - - /* give up? */ - if (level < 1) { - return NT_STATUS_WRONG_PASSWORD; - } - - /* last chance - all combinations of up to level chars upper! */ - strlower(pwcopy); + /* we no longer try different case combinations here. The use + * of this code is now web auth, where trying different case + * combinations makes no sense + */ -#if 0 - if (NT_STATUS_IS_OK(nt_status = string_combinations(pwcopy, password_check, level))) { - *ret_passwd = pws; - return nt_status; - } -#endif return NT_STATUS_WRONG_PASSWORD; } @@ -839,7 +802,7 @@ static const struct auth_operations unix_ops = { .check_password = authunix_check_password }; -_PUBLIC_ NTSTATUS auth_unix_init(void) +_PUBLIC_ NTSTATUS auth4_unix_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 17bfa32167..c19b5cfd42 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -99,7 +99,7 @@ NTSTATUS map_user_info(TALLOC_CTX *mem_ctx, Create an auth_usersupplied_data structure after appropriate mapping. ****************************************************************************/ -NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, +NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted) diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c index dfb8fce2a6..da152e718a 100644 --- a/source4/auth/ntlm/auth_winbind.c +++ b/source4/auth/ntlm/auth_winbind.c @@ -31,7 +31,7 @@ #include "nsswitch/libwbclient/wbclient.h" #include "libcli/security/security.h" -_PUBLIC_ NTSTATUS auth_winbind_init(void); +_PUBLIC_ NTSTATUS auth4_winbind_init(void); static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, struct wbcAuthUserInfo *info, @@ -324,7 +324,7 @@ static const struct auth_operations winbind_wbclient_ops = { .check_password = winbind_check_password_wbclient }; -_PUBLIC_ NTSTATUS auth_winbind_init(void) +_PUBLIC_ NTSTATUS auth4_winbind_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build index 2ac2773c85..d954ec0086 100644 --- a/source4/auth/ntlm/wscript_build +++ b/source4/auth/ntlm/wscript_build @@ -3,7 +3,7 @@ bld.SAMBA_MODULE('auth4_sam_module', source='auth_sam.c', subsystem='auth4', - init_function='auth_sam_init', + init_function='auth4_sam_init', deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig' ) @@ -11,7 +11,7 @@ bld.SAMBA_MODULE('auth4_sam_module', bld.SAMBA_MODULE('auth4_anonymous', source='auth_anonymous.c', subsystem='auth4', - init_function='auth_anonymous_init', + init_function='auth4_anonymous_init', deps='talloc' ) @@ -19,7 +19,7 @@ bld.SAMBA_MODULE('auth4_anonymous', bld.SAMBA_MODULE('auth4_server', source='auth_server.c', subsystem='auth4', - init_function='auth_server_init', + init_function='auth4_server_init', deps='samba-util LIBCLI_SMB CREDENTIALS_NTLM' ) @@ -27,7 +27,7 @@ bld.SAMBA_MODULE('auth4_server', bld.SAMBA_MODULE('auth4_winbind', source='auth_winbind.c', subsystem='auth4', - init_function='auth_winbind_init', + init_function='auth4_winbind_init', deps='RPC_NDR_WINBIND MESSAGING wbclient' ) @@ -35,7 +35,7 @@ bld.SAMBA_MODULE('auth4_winbind', bld.SAMBA_MODULE('auth4_developer', source='auth_developer.c', subsystem='auth4', - init_function='auth_developer_init', + init_function='auth4_developer_init', deps='talloc' ) @@ -43,7 +43,7 @@ bld.SAMBA_MODULE('auth4_developer', bld.SAMBA_MODULE('auth4_unix', source='auth_unix.c', subsystem='auth4', - init_function='auth_unix_init', + init_function='auth4_unix_init', deps='pam PAM_ERRORS LIBTSOCKET' ) diff --git a/source4/auth/ntlmssp/ntlmssp.h b/source4/auth/ntlmssp/ntlmssp.h index ff30317f55..00439e68dd 100644 --- a/source4/auth/ntlmssp/ntlmssp.h +++ b/source4/auth/ntlmssp/ntlmssp.h @@ -26,7 +26,7 @@ struct gensec_ntlmssp_context { struct gensec_security *gensec_security; struct ntlmssp_state *ntlmssp_state; - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_user_info_dc *user_info_dc; }; diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 9db3b560c1..240edbeaad 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -88,7 +88,7 @@ static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_s struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS status; status = auth_context->get_challenge(auth_context, chal); @@ -111,7 +111,7 @@ static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_s struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; return auth_context->challenge_may_be_modified(auth_context); } @@ -125,7 +125,7 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS nt_status; const uint8_t *chal; @@ -155,7 +155,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS nt_status; struct auth_usersupplied_info *user_info; @@ -308,26 +308,26 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx); { - char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN]; - - /* Find out the DNS domain name */ - dnsdomname[0] = '\0'; - safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1); + const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx); + char *dnsname, *lower_netbiosname; + lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name); /* Find out the DNS host name */ - safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1); - if (dnsdomname[0] != '\0') { - safe_strcat(dnsname, ".", sizeof(dnsname) - 1); - safe_strcat(dnsname, dnsdomname, sizeof(dnsname) - 1); + if (dnsdomain && dnsdomain[0] != '\0') { + dnsname = talloc_asprintf(ntlmssp_state, "%s.%s", + lower_netbiosname, + dnsdomain); + talloc_free(lower_netbiosname); + ntlmssp_state->server.dns_name = dnsname; + } else { + ntlmssp_state->server.dns_name = lower_netbiosname; } - strlower_m(dnsname); - ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, - dnsname); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name); - ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, - dnsdomname); + ntlmssp_state->server.dns_domain + = talloc_strdup(ntlmssp_state, + lpcfg_dnsdomain(gensec_security->settings->lp_ctx)); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain); } diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index a4ba88c581..6b3948970f 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -205,7 +205,7 @@ static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, return ret; } -static PyObject *PyAuthContext_FromContext(struct auth_context *auth_context) +static PyObject *PyAuthContext_FromContext(struct auth4_context *auth_context) { return py_talloc_reference(&PyAuthContext, auth_context); } @@ -214,12 +214,12 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec { PyObject *py_lp_ctx = Py_None; PyObject *py_ldb = Py_None; - PyObject *py_messaging_ctx = Py_None; + PyObject *py_imessaging_ctx = Py_None; PyObject *py_auth_context = Py_None; PyObject *py_methods = Py_None; TALLOC_CTX *mem_ctx; - struct auth_context *auth_context; - struct messaging_context *messaging_context = NULL; + struct auth4_context *auth_context; + struct imessaging_context *imessaging_context = NULL; struct loadparm_context *lp_ctx; struct tevent_context *ev; struct ldb_context *ldb; @@ -230,7 +230,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", discard_const_p(char *, kwnames), - &py_lp_ctx, &py_messaging_ctx, &py_ldb, &py_methods)) + &py_lp_ctx, &py_imessaging_ctx, &py_ldb, &py_methods)) return NULL; mem_ctx = talloc_new(NULL); @@ -251,12 +251,12 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec return NULL; } - if (py_messaging_ctx != Py_None) { - messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context); + if (py_imessaging_ctx != Py_None) { + imessaging_context = py_talloc_get_type(py_imessaging_ctx, struct imessaging_context); } if (py_methods == Py_None && py_ldb == Py_None) { - nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context); + nt_status = auth_context_create(mem_ctx, ev, imessaging_context, lp_ctx, &auth_context); } else { if (py_methods != Py_None) { methods = PyList_AsStringList(mem_ctx, py_methods, "methods"); @@ -268,7 +268,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec methods = auth_methods_from_lp(mem_ctx, lp_ctx); } nt_status = auth_context_create_methods(mem_ctx, methods, ev, - messaging_context, lp_ctx, + imessaging_context, lp_ctx, ldb, &auth_context); } diff --git a/source4/auth/samba_server_gensec.c b/source4/auth/samba_server_gensec.c index 07b9b15e17..24b658ad32 100644 --- a/source4/auth/samba_server_gensec.c +++ b/source4/auth/samba_server_gensec.c @@ -29,7 +29,7 @@ NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *server_credentials, const char *target_service, @@ -37,7 +37,7 @@ NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, { NTSTATUS nt_status; struct gensec_security *gensec_ctx; - struct auth_context *auth_context; + struct auth4_context *auth_context; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index 54b8f514cf..3b9edd779d 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -190,7 +190,7 @@ static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx, sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR); user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; - sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS); + sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS); user_info_dc->sids[2] = global_sid_Builtin_Administrators; |