s3-auth Add hook to start a GENSEC mech to auth_samba4
authorAndrew Bartlett <abartlet@samba.org>
Thu, 21 Jul 2011 04:48:59 +0000 (14:48 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 3 Aug 2011 08:48:03 +0000 (18:48 +1000)
Signed-off-by: Andrew Tridgell <tridge@samba.org>
source3/auth/auth_samba4.c
source3/auth/wscript_build

index 03b7884068da70c98fda2d3e8988b535af6e0d58..cf185f750a6c788cbf3149d763b8ab900d4c2dcd 100644 (file)
@@ -24,6 +24,9 @@
 #include "auth/auth_sam_reply.h"
 #include "param/param.h"
 #include "source4/lib/events/events.h"
+#include "source4/lib/messaging/messaging.h"
+#include "auth/gensec/gensec.h"
+#include "source4/auth/credentials/credentials.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -92,6 +95,88 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
        return nt_status;
 }
 
+/* Hook to allow GENSEC to handle blob-based authentication
+ * mechanisms, without directly linking the mechansim code */
+static NTSTATUS start_gensec(TALLOC_CTX *mem_ctx, const char *oid_string,
+                             struct gensec_security **gensec_context)
+{
+       NTSTATUS status;
+       struct loadparm_context *lp_ctx;
+       struct tevent_context *event_ctx;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct gensec_security *gensec_ctx;
+       struct imessaging_context *msg_ctx;
+       struct server_id *server_id;
+       struct cli_credentials *server_credentials;
+
+       lp_ctx = loadparm_init_s3(frame, loadparm_s3_context());
+       if (lp_ctx == NULL) {
+               DEBUG(1, ("loadparm_init_s3 failed\n"));
+               TALLOC_FREE(frame);
+               return NT_STATUS_INVALID_SERVER_STATE;
+       }
+       event_ctx = s4_event_context_init(mem_ctx);
+       if (event_ctx == NULL) {
+               DEBUG(1, ("s4_event_context_init failed\n"));
+               TALLOC_FREE(frame);
+               return NT_STATUS_INVALID_SERVER_STATE;
+       }
+
+       msg_ctx = imessaging_client_init(frame,
+                                        lpcfg_imessaging_path(frame, lp_ctx),
+                                        event_ctx);
+       if (msg_ctx == NULL) {
+               DEBUG(1, ("imessaging_init failed\n"));
+               TALLOC_FREE(frame);
+               return NT_STATUS_INVALID_SERVER_STATE;
+       }
+
+       server_credentials
+               = cli_credentials_init(frame);
+       if (!server_credentials) {
+               DEBUG(1, ("Failed to init server credentials"));
+               TALLOC_FREE(frame);
+               return NT_STATUS_INVALID_SERVER_STATE;
+       }
+
+       cli_credentials_set_conf(server_credentials, lp_ctx);
+       status = cli_credentials_set_machine_account(server_credentials, lp_ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status)));
+               talloc_free(server_credentials);
+               server_credentials = NULL;
+       }
+
+       status = samba_server_gensec_start(mem_ctx,
+                                          event_ctx, msg_ctx,
+                                          lp_ctx, server_credentials, "cifs",
+                                          &gensec_ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(status)));
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       talloc_reparent(frame, gensec_ctx, msg_ctx);
+       talloc_reparent(frame, gensec_ctx, event_ctx);
+       talloc_reparent(frame, gensec_ctx, lp_ctx);
+       talloc_reparent(frame, gensec_ctx, server_credentials);
+
+       gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY);
+       gensec_want_feature(gensec_ctx, GENSEC_FEATURE_UNIX_TOKEN);
+
+       status = gensec_start_mech_by_oid(gensec_ctx, oid_string);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to start GENSEC %s server code: %s\n",
+                         gensec_get_name_by_oid(gensec_ctx, oid_string), nt_errstr(status)));
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       *gensec_context = gensec_ctx;
+       return status;
+}
+
 /* module initialisation */
 static NTSTATUS auth_init_samba4(struct auth_context *auth_context,
                                    const char *param,
@@ -99,12 +184,15 @@ static NTSTATUS auth_init_samba4(struct auth_context *auth_context,
 {
        struct auth_methods *result;
 
+       gensec_init();
+
        result = talloc_zero(auth_context, struct auth_methods);
        if (result == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
        result->name = "samba4";
        result->auth = check_samba4_security;
+       result->start_gensec = start_gensec;
 
         *auth_method = result;
        return NT_STATUS_OK;
index aa6603b85dee398dcf5ec2f8e576091e9e884388..28415d84b4f79021975e2530e4756768b80781ce 100644 (file)
@@ -111,6 +111,6 @@ bld.SAMBA3_MODULE('auth_samba4',
                   subsystem='auth',
                   source='auth_samba4.c',
                   init_function='',
-                  deps='auth4',
+                  deps='auth4 samba_server_gensec gensec',
                   internal_module=bld.SAMBA3_IS_STATIC_MODULE('auth_samba4'),
                   enabled=bld.SAMBA3_IS_ENABLED_MODULE('auth_samba4'))