summaryrefslogtreecommitdiff
path: root/source4/auth
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-06-24 16:26:23 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-06-24 16:26:23 +1000
commit6da26870e0ae5acd6ff49a30ec2f6886b44d095e (patch)
tree850c71039563c16a5d563c47e7ba2ab645baf198 /source4/auth
parent6925a799d04c6fa59dd2ddef1f5510f9bb7d17d1 (diff)
parent2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 (diff)
downloadsamba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.gz
samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.bz2
samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.zip
Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16
Diffstat (limited to 'source4/auth')
-rw-r--r--source4/auth/auth.h57
-rw-r--r--source4/auth/credentials/credentials.c1
-rw-r--r--source4/auth/credentials/credentials.h6
-rw-r--r--source4/auth/credentials/credentials_krb5.c110
-rw-r--r--source4/auth/gensec/cyrus_sasl.c4
-rw-r--r--source4/auth/gensec/gensec.c10
-rw-r--r--source4/auth/gensec/gensec.h8
-rw-r--r--source4/auth/gensec/gensec_gssapi.c120
-rw-r--r--source4/auth/gensec/pygensec.c8
-rw-r--r--source4/auth/kerberos/kerberos.c397
-rw-r--r--source4/auth/kerberos/kerberos.h4
-rw-r--r--source4/auth/kerberos/kerberos_pac.c4
-rw-r--r--source4/auth/kerberos/kerberos_util.c15
-rw-r--r--source4/auth/kerberos/krb5_init_context.c2
-rw-r--r--source4/auth/kerberos/wscript_build2
-rw-r--r--source4/auth/ntlm/auth.c48
-rw-r--r--source4/auth/ntlm/auth_anonymous.c4
-rw-r--r--source4/auth/ntlm/auth_developer.c4
-rw-r--r--source4/auth/ntlm/auth_sam.c10
-rw-r--r--source4/auth/ntlm/auth_server.c4
-rw-r--r--source4/auth/ntlm/auth_simple.c4
-rw-r--r--source4/auth/ntlm/auth_unix.c49
-rw-r--r--source4/auth/ntlm/auth_util.c2
-rw-r--r--source4/auth/ntlm/auth_winbind.c4
-rw-r--r--source4/auth/ntlm/wscript_build12
-rw-r--r--source4/auth/ntlmssp/ntlmssp.h2
-rw-r--r--source4/auth/ntlmssp/ntlmssp_server.c36
-rw-r--r--source4/auth/pyauth.c18
-rw-r--r--source4/auth/samba_server_gensec.c4
-rw-r--r--source4/auth/system_session.c2
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;