Push sam_get_server_info_principal into the auth subsystem
authorAndrew Bartlett <abartlet@samba.org>
Fri, 13 Feb 2009 03:02:49 +0000 (14:02 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 13 Feb 2009 03:02:49 +0000 (14:02 +1100)
This means it must be accessed via the supplied auth_context in the
GENSEC server, and should remove the hard depenceny of GENSEC on the
auth subsystem and ldb (allowing LDB not to rely on LDB is considered
a good thing, apparently)

Andrew Bartlett

source4/auth/auth.h
source4/auth/gensec/config.mk
source4/auth/gensec/gensec_gssapi.c
source4/auth/gensec/gensec_krb5.c
source4/auth/ntlm/auth.c
source4/auth/ntlm/auth_sam.c
source4/auth/ntlm/config.mk
source4/auth/sam.c

index 0ef1e24cd321cbf6beb87ea20db99f7027f4b6c8..973102d842be635ee3ed61e340d5e20145418fed 100644 (file)
@@ -123,6 +123,7 @@ struct auth_serversupplied_info
 
 struct auth_method_context;
 struct auth_check_password_request;
+struct auth_context;
 
 struct auth_operations {
        const char *name;
@@ -144,6 +145,12 @@ struct auth_operations {
        NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx,
                                   const struct auth_usersupplied_info *user_info,
                                   struct auth_serversupplied_info **server_info);
+
+       /* Lookup a 'server info' return based only on the principal */
+       NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx, 
+                                             struct auth_context *auth_context,
+                                             const char *principal,
+                                             struct auth_serversupplied_info **server_info);
 };
 
 struct auth_method_context {
@@ -187,7 +194,10 @@ struct auth_context {
 
        NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by);
        
-       
+       NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx, 
+                                             struct auth_context *auth_context,
+                                             const char *principal,
+                                             struct auth_serversupplied_info **server_info);
 
 };
 
index 3d13ce7f6de8987db2fc31148dd9611788af5b43..27cf442b68ef298aba6a64adb17b6cf2300012ea 100644 (file)
@@ -21,7 +21,7 @@ $(eval $(call proto_header_template,$(gensecsrcdir)/gensec_proto.h,$(gensec_OBJ_
 [MODULE::gensec_krb5]
 SUBSYSTEM = gensec
 INIT_FUNCTION = gensec_krb5_init
-PRIVATE_DEPENDENCIES = CREDENTIALS KERBEROS auth_session auth_sam
+PRIVATE_DEPENDENCIES = CREDENTIALS KERBEROS auth_session
 # End MODULE gensec_krb5
 ################################################
 
index dcfffef3df6ee05414b9bdbb8ba7c15df46ea1e0..aae04dffe2d3a104684f8cbc7501b3b1cc28c161 100644 (file)
@@ -1290,12 +1290,14 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
                        return NT_STATUS_NO_MEMORY;
                }
 
-               if (!gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
+               if (gensec_security->auth_context && 
+                   !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
                        DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n",
                                  gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
-                       nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, 
-                                                                 gensec_security->settings->lp_ctx, principal_string,
-                                                                 &server_info);
+                       nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx, 
+                                                                                            gensec_security->auth_context, 
+                                                                                            principal_string,
+                                                                                            &server_info);
                        
                        if (!NT_STATUS_IS_OK(nt_status)) {
                                talloc_free(mem_ctx);
index 6e715d0090cbdea07dcd72c95fc7741520f088ad..b04abfc16c83085bb8b54ed5ecbf8e50f8f890a3 100644 (file)
@@ -607,8 +607,23 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
                DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", 
                          smb_get_krb5_error_message(context, 
                                                     ret, mem_ctx)));
-               nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, principal_string,
-                                                         &server_info);
+               if (gensec_security->auth_context && 
+                   !gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
+                       DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s"));
+                       nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx, 
+                                                                                            gensec_security->auth_context, 
+                                                                                            principal_string,
+                                                                                            &server_info);
+                       if (!NT_STATUS_IS_OK(nt_status)) {
+                               talloc_free(mem_ctx);
+                               return nt_status;
+                       }
+               } else {
+                       DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
+                                 principal_string));
+                       return NT_STATUS_ACCESS_DENIED;
+               }
+
                krb5_free_principal(context, client_principal);
                free(principal_string);
                
index 2aae4a075ebcff951d39905e9f631128bb8f9a2b..5520c9d01f185c1ceb37087207b434d39fb7fbba 100644 (file)
@@ -103,6 +103,36 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_
        return NT_STATUS_OK;
 }
 
+/****************************************************************************
+ Try to get a challenge out of the various authentication modules.
+ Returns a const char of length 8 bytes.
+****************************************************************************/
+_PUBLIC_ NTSTATUS auth_get_server_info_principal(TALLOC_CTX *mem_ctx, 
+                                                 struct auth_context *auth_ctx,
+                                                 const char *principal,
+                                                 struct auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status;
+       struct auth_method_context *method;
+
+       for (method = auth_ctx->methods; method; method = method->next) {
+               if (!method->ops->get_server_info_principal) {
+                       continue;
+               }
+
+               nt_status = method->ops->get_server_info_principal(mem_ctx, auth_ctx, principal, server_info);
+               if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
+                       continue;
+               }
+
+               NT_STATUS_NOT_OK_RETURN(nt_status);
+
+               break;
+       }
+
+       return NT_STATUS_OK;
+}
+
 struct auth_check_password_sync_state {
        bool finished;
        NTSTATUS status;
@@ -411,6 +441,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **
        ctx->get_challenge = auth_get_challenge;
        ctx->set_challenge = auth_context_set_challenge;
        ctx->challenge_may_be_modified = auth_challenge_may_be_modified;
+       ctx->get_server_info_principal = auth_get_server_info_principal;
 
        *auth_ctx = ctx;
 
index 384d342e00d4143e1b80fa0c26c4b76f13d341a4..96a13d5ed9c0613b7aff7e9b6026f322e589a7b9 100644 (file)
@@ -1,7 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
    Password and authentication handling
-   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2009
    Copyright (C) Gerald Carter                             2003
    Copyright (C) Stefan Metzmacher                         2005
    
@@ -419,18 +419,65 @@ static NTSTATUS authsam_check_password(struct auth_method_context *ctx,
        return authsam_check_password_internals(ctx, mem_ctx, domain, user_info, server_info);
 }
 
+                                  
+/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
+NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx, 
+                                          struct auth_context *auth_context,
+                                          const char *principal,
+                                          struct auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status;
+       DATA_BLOB user_sess_key = data_blob(NULL, 0);
+       DATA_BLOB lm_sess_key = data_blob(NULL, 0);
+
+       struct ldb_message **msgs;
+       struct ldb_message **msgs_domain_ref;
+       struct ldb_context *sam_ctx;
+
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       if (!tmp_ctx) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       sam_ctx = samdb_connect(tmp_ctx, auth_context->event_ctx, auth_context->lp_ctx, 
+                               system_session(tmp_ctx, auth_context->lp_ctx));
+       if (sam_ctx == NULL) {
+               talloc_free(tmp_ctx);
+               return NT_STATUS_INVALID_SYSTEM_SERVICE;
+       }
+
+       nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, 
+                                             &msgs, &msgs_domain_ref);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return nt_status;
+       }
+
+       nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, 
+                                            lp_netbios_name(auth_context->lp_ctx),
+                                            msgs[0], msgs_domain_ref[0],
+                                            user_sess_key, lm_sess_key,
+                                            server_info);
+       if (NT_STATUS_IS_OK(nt_status)) {
+               talloc_steal(mem_ctx, *server_info);
+       }
+       talloc_free(tmp_ctx);
+       return nt_status;
+}
+
 static const struct auth_operations sam_ignoredomain_ops = {
-       .name           = "sam_ignoredomain",
-       .get_challenge  = auth_get_challenge_not_implemented,
-       .want_check     = authsam_ignoredomain_want_check,
-       .check_password = authsam_ignoredomain_check_password
+       .name                      = "sam_ignoredomain",
+       .get_challenge             = auth_get_challenge_not_implemented,
+       .want_check                = authsam_ignoredomain_want_check,
+       .check_password            = authsam_ignoredomain_check_password,
+       .get_server_info_principal = authsam_get_server_info_principal
 };
 
 static const struct auth_operations sam_ops = {
-       .name           = "sam",
-       .get_challenge  = auth_get_challenge_not_implemented,
-       .want_check     = authsam_want_check,
-       .check_password = authsam_check_password
+       .name                      = "sam",
+       .get_challenge             = auth_get_challenge_not_implemented,
+       .want_check                = authsam_want_check,
+       .check_password            = authsam_check_password,
+       .get_server_info_principal = authsam_get_server_info_principal
 };
 
 _PUBLIC_ NTSTATUS auth_sam_init(void)
index 6a487f9b9e052c3fcd6305045fcad11a156cbbd3..668c528ea910b641b153dd52facaacf5d1f7f447 100644 (file)
@@ -8,7 +8,6 @@ ntlm_check_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, ntlm_check.o)
 #######################
 # Start MODULE auth_sam
 [MODULE::auth_sam_module]
-# gensec_krb5 and gensec_gssapi depend on it
 INIT_FUNCTION = auth_sam_init
 SUBSYSTEM = auth
 PRIVATE_DEPENDENCIES = \
index 0017db260cb2c20bb86ab2c5d9e8549e4e4f771a..819bca0db0422b5eae77ec555db1163e5a254e89 100644 (file)
@@ -428,48 +428,3 @@ NTSTATUS sam_get_results_principal(struct ldb_context *sam_ctx,
        
        return NT_STATUS_OK;
 }
-                                  
-/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
-NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, 
-                                      struct tevent_context *event_ctx,
-                                      struct loadparm_context *lp_ctx,
-                                      const char *principal,
-                                      struct auth_serversupplied_info **server_info)
-{
-       NTSTATUS nt_status;
-       DATA_BLOB user_sess_key = data_blob(NULL, 0);
-       DATA_BLOB lm_sess_key = data_blob(NULL, 0);
-
-       struct ldb_message **msgs;
-       struct ldb_message **msgs_domain_ref;
-       struct ldb_context *sam_ctx;
-
-       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-       if (!tmp_ctx) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       sam_ctx = samdb_connect(tmp_ctx, event_ctx, lp_ctx, 
-                               system_session(tmp_ctx, lp_ctx));
-       if (sam_ctx == NULL) {
-               talloc_free(tmp_ctx);
-               return NT_STATUS_INVALID_SYSTEM_SERVICE;
-       }
-
-       nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, 
-                                             &msgs, &msgs_domain_ref);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       }
-
-       nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, 
-                                            lp_netbios_name(lp_ctx),
-                                            msgs[0], msgs_domain_ref[0],
-                                            user_sess_key, lm_sess_key,
-                                            server_info);
-       if (NT_STATUS_IS_OK(nt_status)) {
-               talloc_steal(mem_ctx, *server_info);
-       }
-       talloc_free(tmp_ctx);
-       return nt_status;
-}