s4:auth Change auth_generate_session_info to take an auth context
authorAndrew Bartlett <abartlet@samba.org>
Tue, 13 Apr 2010 02:00:06 +0000 (12:00 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 14 Apr 2010 00:30:51 +0000 (10:30 +1000)
The auth context was in the past only for NTLM authentication, but we
need a SAM, an event context and and loadparm context for calculating
the local groups too, so re-use that infrustructure we already have in
place.

However, to avoid problems where we may not have an auth_context (in
torture tests, for example), allow a simpler 'session_info' to be
generated, by passing this via an indirection in gensec and an
generate_session_info() function pointer in the struct auth_context.

In the smb_server (for old-style session setups) we need to change the
async context to a new 'struct sesssetup_context'.  This allows us to
use the auth_context in processing the authentication reply .

Andrew Bartlett

15 files changed:
source4/auth/auth.h
source4/auth/gensec/gensec.c
source4/auth/gensec/gensec.h
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/auth_simple.c
source4/auth/ntlmssp/ntlmssp_server.c
source4/auth/sam.c
source4/auth/session.c
source4/auth/session.h
source4/auth/system_session.c
source4/smb_server/smb/sesssetup.c
source4/smbd/service_named_pipe.c

index bbdbbc3127aef0ff0f1a935d8b6fedfdcb20733b..915d10397baf7e6e9143569dae2faa444c154825 100644 (file)
@@ -126,6 +126,7 @@ struct auth_serversupplied_info
 struct auth_method_context;
 struct auth_check_password_request;
 struct auth_context;
+struct auth_session_info;
 
 struct auth_operations {
        const char *name;
@@ -185,6 +186,9 @@ struct auth_context {
        /* loadparm context */
        struct loadparm_context *lp_ctx;
 
+       /* 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,
                                   TALLOC_CTX *mem_ctx,
                                   const struct auth_usersupplied_info *user_info,
@@ -201,6 +205,10 @@ struct auth_context {
                                              const char *principal,
                                              struct auth_serversupplied_info **server_info);
 
+       NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx,
+                                         struct auth_context *auth_context,
+                                         struct auth_serversupplied_info *server_info,
+                                         struct auth_session_info **session_info);
 };
 
 /* this structure is used by backends to determine the size of some critical types */
index 7430eef957246c301e154b7177b122e553851867..b532c1502d304b913dc151d00856604af50fb2d1 100644 (file)
@@ -29,6 +29,8 @@
 #include "librpc/rpc/dcerpc.h"
 #include "auth/credentials/credentials.h"
 #include "auth/gensec/gensec.h"
+#include "auth/auth.h"
+#include "auth/system_session_proto.h"
 #include "param/param.h"
 #include "lib/util/tsort.h"
 
@@ -596,6 +598,8 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx,
        return status;
 }
 
+
+
 /**
   Start the GENSEC system, in server mode, returning a context pointer.
   @param mem_ctx The parent TALLOC memory context.
@@ -1292,7 +1296,6 @@ _PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_s
        return gensec_security->remote_addr;
 }
 
-
 /** 
  * Set the target principal (assuming it it known, say from the SPNEGO reply)
  *  - ensures it is talloc()ed 
@@ -1317,6 +1320,22 @@ const char *gensec_get_target_principal(struct gensec_security *gensec_security)
        return NULL;
 }
 
+NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx,
+                                     struct gensec_security *gensec_security,
+                                     struct auth_serversupplied_info *server_info,
+                                     struct auth_session_info **session_info)
+{
+       NTSTATUS nt_status;
+       if (gensec_security->auth_context) {
+               nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context,
+                                                                                server_info, session_info);
+       } else {
+               nt_status = auth_generate_simple_session_info(mem_ctx,
+                                                             server_info, session_info);
+       }
+       return nt_status;
+}
+
 /*
   register a GENSEC backend. 
 
index 232f1a4500db72d1f55d44c20eca58fa96d55d0e..47adf039c0d3984eb55a7ac4158386b228af830d 100644 (file)
@@ -179,6 +179,7 @@ struct gensec_critical_sizes {
 struct gensec_security;
 struct socket_context;
 struct auth_context;
+struct auth_serversupplied_info;
 
 NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
                            TALLOC_CTX *mem_ctx, 
index 6d59bbe612bae432884612eec3265f28e91afa79..fe9aaa3b90f5901c3fbe7a2a3296cda9715126b4 100644 (file)
@@ -1320,8 +1320,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
        }
 
        /* references the server_info into the session_info */
-       nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, 
-                                              gensec_security->settings->lp_ctx, server_info, &session_info);
+       nt_status = gensec_generate_session_info(mem_ctx, gensec_security,
+                                                server_info, &session_info);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(mem_ctx);
                return nt_status;
index 9a96e5e98389fc706db1b36b1c4becd3ad393ab3..bb9ace70b1d44c29431b7503c2a7cc3fd73cda98 100644 (file)
@@ -703,7 +703,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
        }
 
        /* references the server_info into the session_info */
-       nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info);
+       nt_status = gensec_generate_session_info(mem_ctx, gensec_security, server_info, &session_info);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(mem_ctx);
index d5df387d8065e897fcafa5656005ee4fba7f2eb4..e9e72fa2a5d8cf682db7f53102e1203a331f48e1 100644 (file)
@@ -25,6 +25,8 @@
 #include "auth/auth.h"
 #include "auth/ntlm/auth_proto.h"
 #include "param/param.h"
+#include "dsdb/samdb/samdb.h"
+
 
 /***************************************************************************
  Set a fixed challenge
@@ -435,6 +437,8 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **
        ctx->msg_ctx                    = msg;
        ctx->lp_ctx                     = lp_ctx;
 
+       ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx));
+
        for (i=0; methods[i] ; i++) {
                struct auth_method_context *method;
 
@@ -461,6 +465,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **
        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;
+       ctx->generate_session_info = auth_generate_session_info;
 
        *auth_ctx = ctx;
 
index f476e1c3b2c2579e00b7303a40343b59bfc4f1cd..e4e56e1219a65c79971af7af49d2ca88c2322d34 100644 (file)
@@ -144,7 +144,7 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
        struct samr_Password *lm_pwd, *nt_pwd;
        NTSTATUS nt_status;
 
-       uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
+       uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn);
        
        /* Quit if the account was locked out. */
        if (acct_flags & ACB_AUTOLOCK) {
@@ -168,7 +168,7 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
                                        user_info, user_sess_key, lm_sess_key);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
-       nt_status = authsam_account_ok(mem_ctx, sam_ctx, 
+       nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx,
                                       user_info->logon_parameters,
                                       domain_dn,
                                       msg,
@@ -189,11 +189,15 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
        NTSTATUS nt_status;
        const char *account_name = user_info->mapped.account_name;
        struct ldb_message *msg;
-       struct ldb_context *sam_ctx;
        struct ldb_dn *domain_dn;
        DATA_BLOB user_sess_key, lm_sess_key;
        TALLOC_CTX *tmp_ctx;
 
+       if (ctx->auth_ctx->sam_ctx == NULL) {
+               DEBUG(0, ("No SAM available, cannot log in users\n"));
+               return NT_STATUS_INVALID_SYSTEM_SERVICE;
+       }
+
        if (!account_name || !*account_name) {
                /* 'not for me' */
                return NT_STATUS_NOT_IMPLEMENTED;
@@ -204,32 +208,26 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
                return NT_STATUS_NO_MEMORY;
        }
 
-       sam_ctx = samdb_connect(tmp_ctx, ctx->auth_ctx->event_ctx, ctx->auth_ctx->lp_ctx, system_session(ctx->auth_ctx->lp_ctx));
-       if (sam_ctx == NULL) {
-               talloc_free(tmp_ctx);
-               return NT_STATUS_INVALID_SYSTEM_SERVICE;
-       }
-
-       domain_dn = ldb_get_default_basedn(sam_ctx);
+       domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
        if (domain_dn == NULL) {
                talloc_free(tmp_ctx);
                return NT_STATUS_NO_SUCH_DOMAIN;
        }
 
-       nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msg);
+       nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
                return nt_status;
        }
 
-       nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msg, user_info,
+       nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, ctx->auth_ctx->sam_ctx, domain_dn, msg, user_info,
                                         &user_sess_key, &lm_sess_key);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
                return nt_status;
        }
 
-       nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx), 
+       nt_status = authsam_make_server_info(tmp_ctx, ctx->auth_ctx->sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
                                             lp_sam_name(ctx->auth_ctx->lp_ctx),
                                             domain_dn,
                                             msg,
index 1de74ec2e299c3c22414144e1eb9112b398547a7..7f972ac29699f77ea06b12923323bcf25c9d7698 100644 (file)
@@ -87,7 +87,8 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
        }
 
        if (session_info) {
-               nt_status = auth_generate_session_info(tmp_ctx, ev, lp_ctx, server_info, session_info);
+               nt_status = auth_context->generate_session_info(tmp_ctx, auth_context,
+                                                               server_info, session_info);
 
                if (NT_STATUS_IS_OK(nt_status)) {
                        talloc_steal(mem_ctx, *session_info);
index fc7d6d78038665b222fcd503a1fb433d4d457ded..8a8c579c687247cd5257187bee0c4f23f2d82570 100644 (file)
@@ -28,6 +28,7 @@
 #include "../libcli/auth/libcli_auth.h"
 #include "../lib/crypto/crypto.h"
 #include "auth/gensec/gensec.h"
+#include "auth/gensec/gensec_proto.h"
 #include "auth/auth.h"
 #include "param/param.h"
 
@@ -722,11 +723,10 @@ NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
                                      struct gensec_ntlmssp_context);
        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
 
-       nt_status = auth_generate_session_info(ntlmssp_state,
-                                              gensec_security->event_ctx,
-                                              gensec_security->settings->lp_ctx,
-                                              gensec_ntlmssp->server_info,
-                                              session_info);
+       nt_status = gensec_generate_session_info(ntlmssp_state,
+                                                gensec_security,
+                                                gensec_ntlmssp->server_info,
+                                                session_info);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
        (*session_info)->session_key = data_blob_talloc(*session_info, 
index fc3e810ef7f5fe0546d476a695ccecae0e0d763c..201185cf4de0129365054ae6c0673b7fcda59183 100644 (file)
@@ -283,6 +283,7 @@ static bool sids_contains_sid(const struct dom_sid **sids,
        return false;
 }
 
+
 /*
  * This function generates the transitive closure of a given SID "sid" (it
  * basically expands nested groups of a SID).
index 8efdcd880754421156bc4bc6bb68078a0cee180d..03d1c91054be77d76165f7c5105d3704e0a255d2 100644 (file)
@@ -42,11 +42,10 @@ _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
        return session_info;
 }
 
-_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 
-                                   struct tevent_context *event_ctx, 
-                                   struct loadparm_context *lp_ctx,
-                                   struct auth_serversupplied_info *server_info, 
-                                   struct auth_session_info **_session_info) 
+_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
+                                            struct auth_context *auth_context,
+                                            struct auth_serversupplied_info *server_info,
+                                            struct auth_session_info **_session_info)
 {
        struct auth_session_info *session_info;
        NTSTATUS nt_status;
@@ -61,8 +60,8 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
        session_info->session_key = server_info->user_session_key;
 
        nt_status = security_token_create(session_info,
-                                         event_ctx,
-                                         lp_ctx,
+                                         auth_context->event_ctx,
+                                         auth_context->lp_ctx,
                                          server_info->account_sid,
                                          server_info->primary_group_sid,
                                          server_info->n_domain_groups,
index e988855a155d248814b994c4780810f59b143039..574b76946e1067059fb6e4940ed89b38734ca066 100644 (file)
@@ -31,7 +31,7 @@ struct auth_session_info {
 #include "librpc/gen_ndr/netlogon.h"
 
 struct tevent_context;
-
+struct auth_context;
 /* Create a security token for a session SYSTEM (the most
  * trusted/prvilaged account), including the local machine account as
  * the off-host credentials */
@@ -47,11 +47,10 @@ struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadpa
 NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx, 
                                    const char *netbios_name,
                                    struct auth_serversupplied_info **_server_info) ;
-NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 
-                                   struct tevent_context *event_ctx,
-                                   struct loadparm_context *lp_ctx,
+NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
+                                   struct auth_context *auth_context,
                                    struct auth_serversupplied_info *server_info, 
-                                   struct auth_session_info **_session_info) ;
+                                   struct auth_session_info **_session_info);
 
 NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 
                                     struct loadparm_context *lp_ctx,
index 4df96884ca38b9cc49e59f1a07ff199955c2b471..c6df082f69756ef55683d25e19828c063cb3d829 100644 (file)
@@ -114,9 +114,9 @@ static NTSTATUS create_token(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS generate_simple_session_info(TALLOC_CTX *mem_ctx, 
-                                     struct auth_serversupplied_info *server_info, 
-                                     struct auth_session_info **_session_info) 
+NTSTATUS auth_generate_simple_session_info(TALLOC_CTX *mem_ctx,
+                                          struct auth_serversupplied_info *server_info,
+                                          struct auth_session_info **_session_info)
 {
        struct auth_session_info *session_info;
        NTSTATUS nt_status;
@@ -197,7 +197,7 @@ static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx,
        }
 
        /* references the server_info into the session_info */
-       nt_status = generate_simple_session_info(parent_ctx, server_info, &session_info);
+       nt_status = auth_generate_simple_session_info(parent_ctx, server_info, &session_info);
        talloc_free(mem_ctx);
 
        NT_STATUS_NOT_OK_RETURN(nt_status);
@@ -528,7 +528,7 @@ _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
        }
 
        /* references the server_info into the session_info */
-       nt_status = generate_simple_session_info(parent_ctx, server_info, &session_info);
+       nt_status = auth_generate_simple_session_info(parent_ctx, server_info, &session_info);
        talloc_free(mem_ctx);
 
        NT_STATUS_NOT_OK_RETURN(nt_status);
index aecd49fb0b737ee35b29bd938f525b28768ce004..afc33dd3c6ceacc55ea8a78357ea4473f7ec94e1 100644 (file)
 #include "param/param.h"
 #include "../lib/tsocket/tsocket.h"
 
+struct sesssetup_context {
+       struct auth_context *auth_context;
+       struct smbsrv_request *req;
+};
+
 /*
   setup the OS, Lanman and domain portions of a session setup reply
 */
@@ -58,8 +63,9 @@ static void smbsrv_sesssetup_backend_send(struct smbsrv_request *req,
 
 static void sesssetup_old_send(struct tevent_req *subreq)
 {
-       struct smbsrv_request *req =
-               tevent_req_callback_data(subreq, struct smbsrv_request);
+       struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
+       struct smbsrv_request *req = state->req;
+
        union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
        struct auth_serversupplied_info *server_info = NULL;
        struct auth_session_info *session_info;
@@ -71,8 +77,9 @@ static void sesssetup_old_send(struct tevent_req *subreq)
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
        /* This references server_info into session_info */
-       status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx, req->smb_conn->lp_ctx, 
-                                           server_info, &session_info);
+       status = req->smb_conn->negotiate.auth_context->generate_session_info(req,
+                                                                             req->smb_conn->negotiate.auth_context,
+                                                                             server_info, &session_info);
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
        /* allocate a new session */
@@ -106,6 +113,7 @@ static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
        struct tsocket_address *remote_address;
        const char *remote_machine = NULL;
        struct tevent_req *subreq;
+       struct sesssetup_context *state;
 
        sess->old.out.vuid = 0;
        sess->old.out.action = 0;
@@ -147,12 +155,32 @@ static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
        user_info->password.response.lanman.data = talloc_steal(user_info, sess->old.in.password.data);
        user_info->password.response.nt = data_blob(NULL, 0);
 
-       subreq = auth_check_password_send(req,
+       state = talloc(req, struct sesssetup_context);
+       if (!state) goto nomem;
+
+       if (req->smb_conn->negotiate.auth_context) {
+               state->auth_context = req->smb_conn->negotiate.auth_context;
+       } else {
+               /* TODO: should we use just "anonymous" here? */
+               NTSTATUS status = auth_context_create(state,
+                                                     req->smb_conn->connection->event.ctx,
+                                                     req->smb_conn->connection->msg_ctx,
+                                                     req->smb_conn->lp_ctx,
+                                                     &state->auth_context);
+               if (!NT_STATUS_IS_OK(status)) {
+                       smbsrv_sesssetup_backend_send(req, sess, status);
+                       return;
+               }
+       }
+
+       state->req = req;
+
+       subreq = auth_check_password_send(state,
                                          req->smb_conn->connection->event.ctx,
                                          req->smb_conn->negotiate.auth_context,
                                          user_info);
        if (!subreq) goto nomem;
-       tevent_req_set_callback(subreq, sesssetup_old_send, req);
+       tevent_req_set_callback(subreq, sesssetup_old_send, state);
        return;
 
 nomem:
@@ -161,12 +189,13 @@ nomem:
 
 static void sesssetup_nt1_send(struct tevent_req *subreq)
 {
-       struct smbsrv_request *req =
-               tevent_req_callback_data(subreq, struct smbsrv_request);
+       struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
+       struct smbsrv_request *req = state->req;
        union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
        struct auth_serversupplied_info *server_info = NULL;
        struct auth_session_info *session_info;
        struct smbsrv_session *smb_sess;
+
        NTSTATUS status;
 
        status = auth_check_password_recv(subreq, req, &server_info);
@@ -174,9 +203,10 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
        /* This references server_info into session_info */
-       status = auth_generate_session_info(req, req->smb_conn->connection->event.ctx, 
-                                           req->smb_conn->lp_ctx, 
-                                           server_info, &session_info);
+       status = state->auth_context->generate_session_info(req,
+                                                           state->auth_context,
+                                                           server_info,
+                                                           &session_info);
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
        /* allocate a new session */
@@ -214,11 +244,11 @@ failed:
 static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
 {
        NTSTATUS status;
-       struct auth_context *auth_context;
        struct auth_usersupplied_info *user_info = NULL;
        struct tsocket_address *remote_address;
        const char *remote_machine = NULL;
        struct tevent_req *subreq;
+       struct sesssetup_context *state;
 
        sess->nt1.out.vuid = 0;
        sess->nt1.out.action = 0;
@@ -233,6 +263,11 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
                req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities;
        }
 
+       state = talloc(req, struct sesssetup_context);
+       if (!state) goto nomem;
+
+       state->req = req;
+
        if (req->smb_conn->negotiate.oid) {
                if (sess->nt1.in.user && *sess->nt1.in.user) {
                        /* We can't accept a normal login, because we
@@ -242,14 +277,22 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
                }
 
                /* TODO: should we use just "anonymous" here? */
-               status = auth_context_create(req, 
+               status = auth_context_create(state,
                                             req->smb_conn->connection->event.ctx,
                                             req->smb_conn->connection->msg_ctx,
                                             req->smb_conn->lp_ctx,
-                                            &auth_context);
+                                            &state->auth_context);
                if (!NT_STATUS_IS_OK(status)) goto failed;
+       } else if (req->smb_conn->negotiate.auth_context) {
+               state->auth_context = req->smb_conn->negotiate.auth_context;
        } else {
-               auth_context = req->smb_conn->negotiate.auth_context;
+               /* TODO: should we use just "anonymous" here? */
+               status = auth_context_create(state,
+                                            req->smb_conn->connection->event.ctx,
+                                            req->smb_conn->connection->msg_ctx,
+                                            req->smb_conn->lp_ctx,
+                                            &state->auth_context);
+               if (!NT_STATUS_IS_OK(status)) goto failed;
        }
 
        if (req->smb_conn->negotiate.calling_name) {
@@ -281,12 +324,12 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
        user_info->password.response.nt = sess->nt1.in.password2;
        user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);
 
-       subreq = auth_check_password_send(req,
+       subreq = auth_check_password_send(state,
                                          req->smb_conn->connection->event.ctx,
-                                         auth_context,
+                                         state->auth_context,
                                          user_info);
        if (!subreq) goto nomem;
-       tevent_req_set_callback(subreq, sesssetup_nt1_send, req);
+       tevent_req_set_callback(subreq, sesssetup_nt1_send, state);
 
        return;
 
index ec833d0c5a9c0534e8a1a502eb86e6be9644afa5..6409a0099ef98bb29df6d496b23b7202e78c836a 100644 (file)
@@ -23,6 +23,7 @@
 #include <tevent.h>
 #include "smbd/service.h"
 #include "param/param.h"
+#include "auth/auth.h"
 #include "auth/session.h"
 #include "auth/auth_sam_reply.h"
 #include "lib/socket/socket.h"
@@ -162,6 +163,7 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
        struct auth_serversupplied_info *server_info;
        struct named_pipe_auth_req pipe_request;
        struct named_pipe_auth_rep pipe_reply;
+       struct auth_context *auth_context;
        NTSTATUS status;
 
        call = talloc(pipe_conn, struct named_pipe_call);
@@ -252,12 +254,23 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
                        goto reply;
                }
 
+               pipe_reply.status = auth_context_create(conn,
+                                                       conn->event.ctx, conn->msg_ctx,
+                                                       conn->lp_ctx,
+                                                       &auth_context);
+               if (!NT_STATUS_IS_OK(pipe_reply.status)) {
+                       DEBUG(2, ("auth_context_create returned "
+                                 "%s\n", nt_errstr(pipe_reply.status)));
+                       goto reply;
+               }
+
+
                /* setup the session_info on the connection */
-               pipe_reply.status = auth_generate_session_info(conn,
-                                                              conn->event.ctx,
-                                                              conn->lp_ctx,
-                                                              server_info,
-                                                              &conn->session_info);
+               pipe_reply.status = auth_context->generate_session_info(conn,
+                                                                       auth_context,
+                                                                       server_info,
+                                                                       &conn->session_info);
+               talloc_free(auth_context);
                if (!NT_STATUS_IS_OK(pipe_reply.status)) {
                        DEBUG(2, ("auth_generate_session_info failed: %s\n",
                                  nt_errstr(pipe_reply.status)));
@@ -292,11 +305,21 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
                }
 
                /* setup the session_info on the connection */
-               pipe_reply.status = auth_generate_session_info(conn,
-                                                       conn->event.ctx,
+               pipe_reply.status = auth_context_create(conn,
+                                                       conn->event.ctx, conn->msg_ctx,
                                                        conn->lp_ctx,
-                                                       server_info,
-                                                       &conn->session_info);
+                                                       &auth_context);
+               if (!NT_STATUS_IS_OK(pipe_reply.status)) {
+                       DEBUG(2, ("auth_context_create returned "
+                                 "%s\n", nt_errstr(pipe_reply.status)));
+                       goto reply;
+               }
+
+               pipe_reply.status = auth_context->generate_session_info(conn,
+                                                                       auth_context,
+                                                                       server_info,
+                                                                       &conn->session_info);
+               talloc_free(auth_context);
                if (!NT_STATUS_IS_OK(pipe_reply.status)) {
                        DEBUG(2, ("auth_generate_session_info failed: %s\n",
                                  nt_errstr(pipe_reply.status)));
@@ -335,11 +358,22 @@ static void named_pipe_auth_request(struct tevent_req *subreq)
                }
 
                /* setup the session_info on the connection */
-               pipe_reply.status = auth_generate_session_info(conn,
-                                                              conn->event.ctx,
-                                                              conn->lp_ctx,
-                                                              server_info,
-                                                              &conn->session_info);
+               pipe_reply.status = auth_context_create(conn,
+                                                       conn->event.ctx, conn->msg_ctx,
+                                                       conn->lp_ctx,
+                                                       &auth_context);
+               if (!NT_STATUS_IS_OK(pipe_reply.status)) {
+                       DEBUG(2, ("auth_context_create returned "
+                                 "%s\n", nt_errstr(pipe_reply.status)));
+                       goto reply;
+               }
+
+               /* setup the session_info on the connection */
+               pipe_reply.status = auth_context->generate_session_info(conn,
+                                                                       auth_context,
+                                                                       server_info,
+                                                                       &conn->session_info);
+               talloc_free(auth_context);
                if (!NT_STATUS_IS_OK(pipe_reply.status)) {
                        DEBUG(2, ("auth_generate_session_info failed: %s\n",
                                  nt_errstr(pipe_reply.status)));