s3-ntlmssp Add hooks to optionally call into GENSEC in auth_ntlmssp
authorAndrew Bartlett <abartlet@samba.org>
Wed, 27 Jul 2011 03:34:34 +0000 (13:34 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 3 Aug 2011 08:48:03 +0000 (18:48 +1000)
This allows the current behaviour of the NTLMSSP code to be unchanged
while adding a way to hook in an alternate implementation via an auth
module.

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
source3/Makefile.in
source3/auth/auth_ntlmssp.c
source3/include/ntlmssp_wrap.h
source3/libsmb/ntlmssp_wrap.c
source3/wscript_build
source4/auth/gensec/schannel.c
source4/auth/gensec/socket.c

index 9bf3bc03996bca6007d0fc3a9848052e53e51457..927cd0c81ae8603080f3938848851719b1d08950 100644 (file)
@@ -550,6 +550,7 @@ LIBSMB_OBJ0 = \
               ../libcli/auth/ntlm_check.o \
               libsmb/ntlmssp.o \
               libsmb/ntlmssp_wrap.o \
+              ../auth/gensec/gensec.o \
               ../libcli/auth/ntlmssp.o \
               ../libcli/auth/ntlmssp_sign.o \
               $(LIBNDR_NTLMSSP_OBJ) \
index 2157d355d204e5caa93420762ffdb64a84aadc01..64307bea48955dbd4f17359c2ea932d57f2507e4 100644 (file)
 #include "ntlmssp_wrap.h"
 #include "../librpc/gen_ndr/netlogon.h"
 #include "../lib/tsocket/tsocket.h"
+#include "auth/gensec/gensec.h"
 
 NTSTATUS auth_ntlmssp_steal_session_info(TALLOC_CTX *mem_ctx,
                                        struct auth_ntlmssp_state *auth_ntlmssp_state,
                                        struct auth_session_info **session_info)
 {
-       NTSTATUS nt_status = create_local_token(mem_ctx,
-                                               auth_ntlmssp_state->server_info,
-                                               &auth_ntlmssp_state->ntlmssp_state->session_key,
+       NTSTATUS nt_status;
+       if (auth_ntlmssp_state->gensec_security) {
+
+               nt_status = gensec_session_info(auth_ntlmssp_state->gensec_security,
+                                               mem_ctx,
                                                session_info);
+               return nt_status;
+       }
+
+       nt_status = create_local_token(mem_ctx,
+                                      auth_ntlmssp_state->server_info,
+                                      &auth_ntlmssp_state->ntlmssp_state->session_key,
+                                      session_info);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(10, ("create_local_token failed: %s\n",
@@ -190,6 +200,29 @@ NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
        struct auth_ntlmssp_state *ans;
        struct auth_context *auth_context;
 
+       ans = talloc_zero(NULL, struct auth_ntlmssp_state);
+       if (!ans) {
+               DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(ans);
+               return nt_status;
+       }
+
+       if (auth_context->start_gensec) {
+               nt_status = auth_context->start_gensec(ans, GENSEC_OID_NTLMSSP, &ans->gensec_security);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       TALLOC_FREE(ans);
+                       return nt_status;
+               } else {
+                       *auth_ntlmssp_state = ans;
+                       return NT_STATUS_OK;
+               }
+       }
+
        if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
                is_standalone = true;
        } else {
@@ -205,12 +238,6 @@ NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
        }
        dns_name = get_mydnsfullname();
 
-       ans = talloc_zero(NULL, struct auth_ntlmssp_state);
-       if (!ans) {
-               DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-
        ans->remote_address = tsocket_address_copy(remote_address, ans);
        if (ans->remote_address == NULL) {
                DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
@@ -228,10 +255,6 @@ NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
                return nt_status;
        }
 
-       nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       }
        ans->auth_context = talloc_steal(ans, auth_context);
 
        ans->ntlmssp_state->callback_private = ans;
index ed2e82758c54247b9786895ee05884d4584f3cd9..ff534da46fe9b75d687175b6ca20789fbe9ec938 100644 (file)
 #ifndef _NTLMSSP_WRAP_
 #define _NTLMSSP_WRAP_
 
+struct gensec_security;
+
 struct auth_ntlmssp_state {
        /* used only by server implementation */
        struct auth_context *auth_context;
        struct auth_serversupplied_info *server_info;
        struct tsocket_address *remote_address;
+       struct gensec_security *gensec_security;
 
        /* used by both client and server implementation */
        struct ntlmssp_state *ntlmssp_state;
index de883dd8cb8b0eebcf080b7d2239e43538ca3649..43cde19b3b70d86e1e93c6828f508861610443d7 100644 (file)
@@ -21,6 +21,7 @@
 #include "includes.h"
 #include "libcli/auth/ntlmssp.h"
 #include "ntlmssp_wrap.h"
+#include "auth/gensec/gensec.h"
 
 NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *ans,
                                  TALLOC_CTX *sig_mem_ctx,
@@ -30,6 +31,10 @@ NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *ans,
                                  size_t pdu_length,
                                  DATA_BLOB *sig)
 {
+       if (ans->gensec_security) {
+               return gensec_sign_packet(ans->gensec_security,
+                                         sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
+       }
        return ntlmssp_sign_packet(ans->ntlmssp_state,
                                   sig_mem_ctx,
                                   data, length,
@@ -44,6 +49,10 @@ NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *ans,
                                   size_t pdu_length,
                                   const DATA_BLOB *sig)
 {
+       if (ans->gensec_security) {
+               return gensec_check_packet(ans->gensec_security,
+                                          data, length, whole_pdu, pdu_length, sig);
+       }
        return ntlmssp_check_packet(ans->ntlmssp_state,
                                    data, length,
                                    whole_pdu, pdu_length,
@@ -58,6 +67,10 @@ NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *ans,
                                  size_t pdu_length,
                                  DATA_BLOB *sig)
 {
+       if (ans->gensec_security) {
+               return gensec_seal_packet(ans->gensec_security,
+                                         sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
+       }
        return ntlmssp_seal_packet(ans->ntlmssp_state,
                                   sig_mem_ctx,
                                   data, length,
@@ -72,6 +85,10 @@ NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *ans,
                                    size_t pdu_length,
                                    const DATA_BLOB *sig)
 {
+       if (ans->gensec_security) {
+               return gensec_unseal_packet(ans->gensec_security,
+                                           data, length, whole_pdu, pdu_length, sig);
+       }
        return ntlmssp_unseal_packet(ans->ntlmssp_state,
                                     data, length,
                                     whole_pdu, pdu_length,
@@ -80,17 +97,26 @@ NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *ans,
 
 bool auth_ntlmssp_negotiated_sign(struct auth_ntlmssp_state *ans)
 {
+       if (ans->gensec_security) {
+               return gensec_have_feature(ans->gensec_security, GENSEC_FEATURE_SIGN);
+       }
        return ans->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN;
 }
 
 bool auth_ntlmssp_negotiated_seal(struct auth_ntlmssp_state *ans)
 {
+       if (ans->gensec_security) {
+               return gensec_have_feature(ans->gensec_security, GENSEC_FEATURE_SEAL);
+       }
        return ans->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL;
 }
 
 /* Needed for 'smb username' processing */
 const char *auth_ntlmssp_get_username(struct auth_ntlmssp_state *ans)
 {
+       if (ans->gensec_security) {
+               return ""; /* We can't get at this value, and it's just for the %U macros */
+       }
        return ans->ntlmssp_state->user;
 }
 
@@ -129,17 +155,42 @@ void auth_ntlmssp_or_flags(struct auth_ntlmssp_state *ans, uint32_t flags)
 
 void auth_ntlmssp_want_feature(struct auth_ntlmssp_state *ans, uint32_t feature)
 {
-       ntlmssp_want_feature(ans->ntlmssp_state, feature);
+       if (ans->gensec_security) {
+               /* You need to negotiate signing to get a windows server to calculate a session key */
+               if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
+                       return gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SESSION_KEY);
+               }
+               if (feature & NTLMSSP_FEATURE_SIGN) {
+                       return gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SIGN);
+               }
+               if (feature & NTLMSSP_FEATURE_SEAL) {
+                       return gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SEAL);
+               }
+       } else {
+               ntlmssp_want_feature(ans->ntlmssp_state, feature);
+       }
 }
 
 DATA_BLOB auth_ntlmssp_get_session_key(struct auth_ntlmssp_state *ans, TALLOC_CTX *mem_ctx)
 {
+       if (ans->gensec_security) {
+               DATA_BLOB session_key;
+               NTSTATUS status = gensec_session_key(ans->gensec_security, mem_ctx, &session_key);
+               if (NT_STATUS_IS_OK(status)) {
+                       return session_key;
+               } else {
+                       return data_blob_null;
+               }
+       }
        return data_blob_talloc(mem_ctx, ans->ntlmssp_state->session_key.data, ans->ntlmssp_state->session_key.length);
 }
 
 NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *ans,
                             const DATA_BLOB request, DATA_BLOB *reply)
 {
+       if (ans->gensec_security) {
+               return gensec_update(ans->gensec_security, ans, request, reply);
+       }
        return ntlmssp_update(ans->ntlmssp_state, request, reply);
 }
 
index 266a0e3fad705754290b53d0c2cc5af01cf0ee32..42a12be0cb022986efd5080f013452e88b492f97 100755 (executable)
@@ -817,7 +817,7 @@ bld.SAMBA3_SUBSYSTEM('LIBSMB_ERR',
 
 bld.SAMBA3_SUBSYSTEM('LIBNTLMSSP',
                     source=LIBNTLMSSP_SRC,
-                    deps='LIBSMB_ERR NDR_NTLMSSP NTLMSSP_COMMON',
+                    deps='LIBSMB_ERR NDR_NTLMSSP NTLMSSP_COMMON gensec_runtime',
                     vars=locals())
 
 bld.SAMBA3_LIBRARY('libsmb',
index 67d928e710b639aa170dda08b98fdf456377fd68..4587d431843efbd4f61931c375c42be81782c3af 100644 (file)
@@ -29,6 +29,7 @@
 #include "../libcli/auth/schannel.h"
 #include "librpc/rpc/dcerpc.h"
 #include "param/param.h"
+#include "auth/gensec/schannel.h"
 
 _PUBLIC_ NTSTATUS gensec_schannel_init(void);
 
index 8ee6cbc552924bbcd32163f1da1049b7d3f17bce..38eab6ac448098eddcac3808ce51a85c1c5c62fc 100644 (file)
@@ -25,6 +25,7 @@
 #include "lib/stream/packet.h"
 #include "auth/gensec/gensec.h"
 #include "auth/gensec/gensec_proto.h"
+#include "auth/gensec/gensec_socket.h"
 
 static const struct socket_ops gensec_socket_ops;