The branch, master has been updated
       via  76f249f s3-dcerps: check auth_type
       via  926a3f4 s3-dcerpc: Use spnego own sign/seal functions
       via  6789934 libcli: fix compile warning
       via  b11fff1 s3-dcerpc: remove auth_data_free_func
       via  3453bc7 s3-dcerpc: make auth context opaque
       via  0ec3720 srv_pipe: reorganize code so that related functions are 
close to each other
       via  d10e192 s3-dcerpc: finally remove the legaqcy spnego_type variable 
from pipe_auth_data
       via  b475cfd s3-dcerpc: use new spnego server code
       via  4cdee9b s3-dcerpc: add spnego server helpers
       via  77c73a5 spnego: make spnego_context public
       via  2c9f420 s3-dcerpc: move client spnego stuff in /librpc/crypto
       via  59722ef spnego: avoid explicit dependency on dcerpc specific 
structures
       via  62d7226 s3-dcesrv: use gssapi helper in srv_pipe.c
       via  28c22d0 s3-dcerpc: add server helpers for gssapi auth
       via  8efd31c s3-dcesrv: use ntlmssp helper in srv_pipe.c
       via  bbf5357 s3-dcerpc: add server helpers for ntlmssp auth
       via  4194383 gssapi: remove unused function argument
       via  412ebad gssapi: avoid explicit dependency on dcerpc specific 
structures
       via  0e5eb82 s3-dcerpc: move crypto stuff in /librpc/crypto
      from  ffdfcfb s3-dsgetdcname: always pass in messaging context.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 76f249fb44599450a12b7f0c62f5f3830d203a24
Author: Simo Sorce <[email protected]>
Date:   Sat Sep 11 09:52:42 2010 -0400

    s3-dcerps: check auth_type
    
    make sure the auth type used throught the auth operation is consistent.
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 926a3f4fcdb82c86dff94a9ac78010d59a04ea1b
Author: Simo Sorce <[email protected]>
Date:   Sat Sep 11 09:46:08 2010 -0400

    s3-dcerpc: Use spnego own sign/seal functions
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 678993470fdc86a57841c7d35ec9c60f6b81c1cc
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 16:43:38 2010 -0400

    libcli: fix compile warning
    
    Signed-off-by: Günther Deschner <[email protected]>

commit b11fff1f481a21d84b713421cfbfd42ef1e73f4b
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 16:33:45 2010 -0400

    s3-dcerpc: remove auth_data_free_func
    
    Everything is using a talloc pointer now, no need to have an
    accessor function to free data anymore.
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 3453bc7b1108390354c0825ee6b2b0bb28fca2f3
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 16:27:47 2010 -0400

    s3-dcerpc: make auth context opaque
    
    This way we always double check in advance that the context
    is of the right type with talloc_get_type_abort instead of
    potentially accessing random memory by addressing the wrong
    structure in the union.
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 0ec372057308198cd2f1742c4a56868e6dab7213
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 15:09:34 2010 -0400

    srv_pipe: reorganize code so that related functions are close to each other
    
    Signed-off-by: Günther Deschner <[email protected]>

commit d10e192b83e2c016873d7c2198f62173834287f0
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 11:03:49 2010 -0400

    s3-dcerpc: finally remove the legaqcy spnego_type variable from 
pipe_auth_data
    
    Signed-off-by: Günther Deschner <[email protected]>

commit b475cfd0b2376fdf2a8426f33be8c940b035fe26
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 10:19:27 2010 -0400

    s3-dcerpc: use new spnego server code
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 4cdee9b0eddd47ad2cfb866f63cdeb3f65200a3e
Author: Simo Sorce <[email protected]>
Date:   Tue Aug 31 15:08:31 2010 -0400

    s3-dcerpc: add spnego server helpers
    
    squashed: add michlistMIC signature checks
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 77c73a5ec92f9294195dfef977f66dfe66182c6d
Author: Simo Sorce <[email protected]>
Date:   Fri Sep 3 09:38:57 2010 -0400

    spnego: make spnego_context public
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 2c9f420d75ac0a231b84c2d85e9470bb595d6daf
Author: Simo Sorce <[email protected]>
Date:   Thu Sep 2 17:50:21 2010 -0400

    s3-dcerpc: move client spnego stuff in /librpc/crypto
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 59722ef2fb6973ac06de5c17c3f84995bac20816
Author: Simo Sorce <[email protected]>
Date:   Thu Sep 2 17:43:21 2010 -0400

    spnego: avoid explicit dependency on dcerpc specific structures
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 62d7226b7898ade0dc19a5b13a9632fd096c5771
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 18:31:05 2010 -0400

    s3-dcesrv: use gssapi helper in srv_pipe.c
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 28c22d04fb816f1c4418b95e9e69710e488af94c
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 18:27:53 2010 -0400

    s3-dcerpc: add server helpers for gssapi auth
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 8efd31ccad96bb6da1bdb6bf2fbb8fe9d67b640e
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 17:09:52 2010 -0400

    s3-dcesrv: use ntlmssp helper in srv_pipe.c
    
    Signed-off-by: Günther Deschner <[email protected]>

commit bbf535764b39941e64664b51562cb1525a99a959
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 15:50:06 2010 -0400

    s3-dcerpc: add server helpers for ntlmssp auth
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 4194383cfe151aa57e0b288c77a113c5922eb019
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 19:05:43 2010 -0400

    gssapi: remove unused function argument
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 412ebad02b74d8fbb1f6493e87abab7e345dc000
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 17:27:56 2010 -0400

    gssapi: avoid explicit dependency on dcerpc specific structures
    
    Signed-off-by: Günther Deschner <[email protected]>

commit 0e5eb82a6f29e33ca2cafe0ed7103395837b3fc0
Author: Simo Sorce <[email protected]>
Date:   Wed Sep 1 11:58:33 2010 -0400

    s3-dcerpc: move crypto stuff in /librpc/crypto
    
    Signed-off-by: Günther Deschner <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 libcli/auth/schannel_proto.h        |    2 +
 source3/Makefile.in                 |   12 +-
 source3/include/ntdomain.h          |   16 +-
 source3/include/proto.h             |   10 +
 source3/librpc/crypto/cli_spnego.c  |  436 ++++++++++++++
 source3/librpc/crypto/gse.c         | 1010 +++++++++++++++++++++++++++++++++
 source3/librpc/crypto/gse.h         |   73 +++
 source3/librpc/crypto/gse_krb5.c    |  388 +++++++++++++
 source3/librpc/crypto/gse_krb5.h    |   30 +
 source3/librpc/crypto/spnego.h      |  101 ++++
 source3/librpc/rpc/dcerpc_gssapi.c  | 1034 ---------------------------------
 source3/librpc/rpc/dcerpc_gssapi.h  |   76 ---
 source3/librpc/rpc/dcerpc_helpers.c |  204 +++----
 source3/librpc/rpc/dcerpc_krb5.c    |  388 -------------
 source3/librpc/rpc/dcerpc_krb5.h    |   30 -
 source3/librpc/rpc/dcerpc_spnego.c  |  359 ------------
 source3/librpc/rpc/dcerpc_spnego.h  |   54 --
 source3/libsmb/clispnego.c          |   79 +++-
 source3/rpc_client/cli_pipe.c       |  172 ++++---
 source3/rpc_server/dcesrv_gssapi.c  |  248 ++++++++
 source3/rpc_server/dcesrv_gssapi.h  |   42 ++
 source3/rpc_server/dcesrv_ntlmssp.c |  134 +++++
 source3/rpc_server/dcesrv_ntlmssp.h |   42 ++
 source3/rpc_server/dcesrv_spnego.c  |  308 ++++++++++
 source3/rpc_server/dcesrv_spnego.h  |   37 ++
 source3/rpc_server/rpc_ncacn_np.c   |    4 +-
 source3/rpc_server/srv_netlog_nt.c  |    8 +-
 source3/rpc_server/srv_pipe.c       | 1066 +++++++++++++----------------------
 source3/rpc_server/srv_samr_nt.c    |    4 +-
 source3/rpcclient/rpcclient.c       |    6 +
 30 files changed, 3552 insertions(+), 2821 deletions(-)
 create mode 100644 source3/librpc/crypto/cli_spnego.c
 create mode 100644 source3/librpc/crypto/gse.c
 create mode 100644 source3/librpc/crypto/gse.h
 create mode 100644 source3/librpc/crypto/gse_krb5.c
 create mode 100644 source3/librpc/crypto/gse_krb5.h
 create mode 100644 source3/librpc/crypto/spnego.h
 delete mode 100644 source3/librpc/rpc/dcerpc_gssapi.c
 delete mode 100644 source3/librpc/rpc/dcerpc_gssapi.h
 delete mode 100644 source3/librpc/rpc/dcerpc_krb5.c
 delete mode 100644 source3/librpc/rpc/dcerpc_krb5.h
 delete mode 100644 source3/librpc/rpc/dcerpc_spnego.c
 delete mode 100644 source3/librpc/rpc/dcerpc_spnego.h
 create mode 100644 source3/rpc_server/dcesrv_gssapi.c
 create mode 100644 source3/rpc_server/dcesrv_gssapi.h
 create mode 100644 source3/rpc_server/dcesrv_ntlmssp.c
 create mode 100644 source3/rpc_server/dcesrv_ntlmssp.h
 create mode 100644 source3/rpc_server/dcesrv_spnego.c
 create mode 100644 source3/rpc_server/dcesrv_spnego.h


Changeset truncated at 500 lines:

diff --git a/libcli/auth/schannel_proto.h b/libcli/auth/schannel_proto.h
index f1731a7..a85a6db 100644
--- a/libcli/auth/schannel_proto.h
+++ b/libcli/auth/schannel_proto.h
@@ -23,6 +23,8 @@
 #ifndef _LIBCLI_AUTH_SCHANNEL_PROTO_H__
 #define _LIBCLI_AUTH_SCHANNEL_PROTO_H__
 
+struct schannel_state;
+
 struct tdb_wrap *open_schannel_session_store(TALLOC_CTX *mem_ctx,
                                             const char *private_dir);
 
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 2f32251..882ad43 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -593,9 +593,9 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o 
libsmb/clifile.o \
 
 LIBMSRPC_OBJ = $(SCHANNEL_OBJ) \
               rpc_client/cli_pipe.o \
-              librpc/rpc/dcerpc_krb5.o \
-              librpc/rpc/dcerpc_gssapi.o \
-              librpc/rpc/dcerpc_spnego.o \
+              librpc/crypto/gse_krb5.o \
+              librpc/crypto/gse.o \
+              librpc/crypto/cli_spnego.o \
               librpc/rpc/rpc_common.o \
               rpc_client/rpc_transport_np.o \
               rpc_client/rpc_transport_sock.o \
@@ -712,8 +712,12 @@ RPC_NCACN_NP = rpc_server/srv_pipe_register.o 
rpc_server/rpc_ncacn_np.o \
 
 RPC_SERVICE = rpc_server/rpc_server.o
 
+RPC_CRYPTO = rpc_server/dcesrv_ntlmssp.o \
+               rpc_server/dcesrv_gssapi.o \
+               rpc_server/dcesrv_spnego.o
+
 RPC_PIPE_OBJ = rpc_server/srv_pipe.o rpc_server/srv_pipe_hnd.o \
-              $(RPC_NCACN_NP) $(RPC_SERVICE)
+              $(RPC_NCACN_NP) $(RPC_SERVICE) $(RPC_CRYPTO)
 
 RPC_RPCECHO_OBJ = rpc_server/srv_echo_nt.o librpc/gen_ndr/srv_echo.o
 
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 073efe5..ba4f392 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -93,34 +93,20 @@ typedef struct pipe_rpc_fns {
  * Can't keep in sync with wire values as spnego wraps different auth methods.
  */
 
-enum pipe_auth_type_spnego {
-       PIPE_AUTH_TYPE_SPNEGO_NONE = 0,
-       PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
-       PIPE_AUTH_TYPE_SPNEGO_KRB5
-};
-
 struct gse_context;
 
 /* auth state for all bind types. */
 
 struct pipe_auth_data {
        enum dcerpc_AuthType auth_type;
-       enum pipe_auth_type_spnego spnego_type; /* used by server only */
        enum dcerpc_AuthLevel auth_level;
 
-       union {
-               struct schannel_state *schannel_auth;
-               struct auth_ntlmssp_state *auth_ntlmssp_state;
-               struct gse_context *gssapi_state;
-               struct spnego_context *spnego_state;
-       } a_u;
+       void *auth_ctx;
 
        /* Only the client code uses these 3 for now */
        char *domain;
        char *user_name;
        DATA_BLOB user_session_key;
-
-       void (*auth_data_free_func)(struct pipe_auth_data *);
 };
 
 /*
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3349e02..849a062 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2557,6 +2557,16 @@ bool spnego_parse_auth_response(TALLOC_CTX *ctx,
                                const char *mechOID,
                                DATA_BLOB *auth);
 
+bool spnego_parse_auth_and_mic(TALLOC_CTX *ctx, DATA_BLOB blob,
+                               DATA_BLOB *auth, DATA_BLOB *signature);
+DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx,
+                                          NTSTATUS nt_status,
+                                          const char *mechOID,
+                                          DATA_BLOB *reply,
+                                          DATA_BLOB *mechlistMIC);
+bool spnego_mech_list_blob(TALLOC_CTX *mem_ctx,
+                          char **oid_list, DATA_BLOB *data);
+
 /* The following definitions come from libsmb/clistr.c  */
 
 size_t clistr_push_fn(const char *function,
diff --git a/source3/librpc/crypto/cli_spnego.c 
b/source3/librpc/crypto/cli_spnego.c
new file mode 100644
index 0000000..bf58e25
--- /dev/null
+++ b/source3/librpc/crypto/cli_spnego.c
@@ -0,0 +1,436 @@
+/*
+ *  SPNEGO Encapsulation
+ *  Client functions
+ *  Copyright (C) Simo Sorce 2010.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "../libcli/auth/spnego.h"
+#include "include/ntlmssp_wrap.h"
+#include "librpc/gen_ndr/ntlmssp.h"
+#include "librpc/crypto/gse.h"
+#include "librpc/crypto/spnego.h"
+
+static NTSTATUS spnego_context_init(TALLOC_CTX *mem_ctx,
+                                   bool do_sign, bool do_seal,
+                                   struct spnego_context **spnego_ctx)
+{
+       struct spnego_context *sp_ctx;
+
+       sp_ctx = talloc_zero(mem_ctx, struct spnego_context);
+       if (!sp_ctx) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       sp_ctx->do_sign = do_sign;
+       sp_ctx->do_seal = do_seal;
+       sp_ctx->state = SPNEGO_CONV_INIT;
+
+       *spnego_ctx = sp_ctx;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS spnego_gssapi_init_client(TALLOC_CTX *mem_ctx,
+                                  bool do_sign, bool do_seal,
+                                  bool is_dcerpc,
+                                  const char *ccache_name,
+                                  const char *server,
+                                  const char *service,
+                                  const char *username,
+                                  const char *password,
+                                  struct spnego_context **spnego_ctx)
+{
+       struct spnego_context *sp_ctx = NULL;
+       uint32_t add_gss_c_flags = 0;
+       NTSTATUS status;
+
+       status = spnego_context_init(mem_ctx, do_sign, do_seal, &sp_ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       sp_ctx->mech = SPNEGO_KRB5;
+
+       if (is_dcerpc) {
+               add_gss_c_flags = GSS_C_DCE_STYLE;
+       }
+
+       status = gse_init_client(sp_ctx,
+                                do_sign, do_seal,
+                                ccache_name, server, service,
+                                username, password, add_gss_c_flags,
+                                &sp_ctx->mech_ctx.gssapi_state);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       *spnego_ctx = sp_ctx;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS spnego_ntlmssp_init_client(TALLOC_CTX *mem_ctx,
+                                   bool do_sign, bool do_seal,
+                                   bool is_dcerpc,
+                                   const char *domain,
+                                   const char *username,
+                                   const char *password,
+                                   struct spnego_context **spnego_ctx)
+{
+       struct spnego_context *sp_ctx = NULL;
+       NTSTATUS status;
+
+       status = spnego_context_init(mem_ctx, do_sign, do_seal, &sp_ctx);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       sp_ctx->mech = SPNEGO_NTLMSSP;
+
+       status = auth_ntlmssp_client_start(sp_ctx,
+                                       global_myname(),
+                                       lp_workgroup(),
+                                       lp_client_ntlmv2_auth(),
+                                       &sp_ctx->mech_ctx.ntlmssp_state);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       status = auth_ntlmssp_set_username(sp_ctx->mech_ctx.ntlmssp_state,
+                                          username);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       status = auth_ntlmssp_set_domain(sp_ctx->mech_ctx.ntlmssp_state,
+                                        domain);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       status = auth_ntlmssp_set_password(sp_ctx->mech_ctx.ntlmssp_state,
+                                          password);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       /*
+        * Turn off sign+seal to allow selected auth level to turn it back on.
+        */
+       auth_ntlmssp_and_flags(sp_ctx->mech_ctx.ntlmssp_state,
+                                               ~(NTLMSSP_NEGOTIATE_SIGN |
+                                                 NTLMSSP_NEGOTIATE_SEAL));
+
+       if (do_sign) {
+               auth_ntlmssp_or_flags(sp_ctx->mech_ctx.ntlmssp_state,
+                                               NTLMSSP_NEGOTIATE_SIGN);
+       } else if (do_seal) {
+               auth_ntlmssp_or_flags(sp_ctx->mech_ctx.ntlmssp_state,
+                                               NTLMSSP_NEGOTIATE_SEAL |
+                                               NTLMSSP_NEGOTIATE_SIGN);
+       }
+
+       *spnego_ctx = sp_ctx;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
+                                     struct spnego_context *sp_ctx,
+                                     DATA_BLOB *spnego_in,
+                                     DATA_BLOB *spnego_out)
+{
+       struct gse_context *gse_ctx;
+       struct auth_ntlmssp_state *ntlmssp_ctx;
+       struct spnego_data sp_in, sp_out;
+       DATA_BLOB token_in = data_blob_null;
+       DATA_BLOB token_out = data_blob_null;
+       const char *mech_oids[2] = { NULL, NULL };
+       char *principal = NULL;
+       ssize_t len_in = 0;
+       ssize_t len_out = 0;
+       bool mech_wants_more = false;
+       NTSTATUS status;
+
+       if (!spnego_in->length) {
+               /* server didn't send anything, is init ? */
+               if (sp_ctx->state != SPNEGO_CONV_INIT) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+       } else {
+               len_in = spnego_read_data(mem_ctx, *spnego_in, &sp_in);
+               if (len_in == -1) {
+                       status = NT_STATUS_INVALID_PARAMETER;
+                       goto done;
+               }
+               if (sp_in.type != SPNEGO_NEG_TOKEN_TARG) {
+                       status = NT_STATUS_INVALID_PARAMETER;
+                       goto done;
+               }
+               if (sp_in.negTokenTarg.negResult == SPNEGO_REJECT) {
+                       status = NT_STATUS_ACCESS_DENIED;
+                       goto done;
+               }
+               token_in = sp_in.negTokenTarg.responseToken;
+       }
+
+       if (sp_ctx->state == SPNEGO_CONV_AUTH_CONFIRM) {
+               if (sp_in.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
+                       sp_ctx->state = SPNEGO_CONV_AUTH_DONE;
+                       *spnego_out = data_blob_null;
+                       status = NT_STATUS_OK;
+               } else {
+                       status = NT_STATUS_ACCESS_DENIED;
+               }
+               goto done;
+       }
+
+       switch (sp_ctx->mech) {
+       case SPNEGO_KRB5:
+
+               gse_ctx = sp_ctx->mech_ctx.gssapi_state;
+               status = gse_get_client_auth_token(mem_ctx, gse_ctx,
+                                                  &token_in, &token_out);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
+
+               mech_oids[0] = OID_KERBEROS5;
+               mech_wants_more = gse_require_more_processing(gse_ctx);
+
+               break;
+
+       case SPNEGO_NTLMSSP:
+
+               ntlmssp_ctx = sp_ctx->mech_ctx.ntlmssp_state;
+               status = auth_ntlmssp_update(ntlmssp_ctx,
+                                            token_in, &token_out);
+               if (NT_STATUS_EQUAL(status,
+                                   NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+                       mech_wants_more = true;
+               } else if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
+
+               mech_oids[0] = OID_NTLMSSP;
+
+               break;
+
+       default:
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       switch (sp_ctx->state) {
+       case SPNEGO_CONV_INIT:
+               *spnego_out = spnego_gen_negTokenInit(mem_ctx, mech_oids,
+                                                     &token_out, principal);
+               if (!spnego_out->data) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       goto done;
+               }
+               sp_ctx->state = SPNEGO_CONV_AUTH_MORE;
+               break;
+
+       case SPNEGO_CONV_AUTH_MORE:
+               /* server says it's done and we do not seem to agree */
+               if (sp_in.negTokenTarg.negResult ==
+                                               SPNEGO_ACCEPT_COMPLETED) {
+                       status = NT_STATUS_INVALID_PARAMETER;
+                       goto done;
+               }
+
+               sp_out.type = SPNEGO_NEG_TOKEN_TARG;
+               sp_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT;
+               sp_out.negTokenTarg.supportedMech = NULL;
+               sp_out.negTokenTarg.responseToken = token_out;
+               sp_out.negTokenTarg.mechListMIC = data_blob_null;
+
+               len_out = spnego_write_data(mem_ctx, spnego_out, &sp_out);
+               if (len_out == -1) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       goto done;
+               }
+
+               if (!mech_wants_more) {
+                       /* we still need to get an ack from the server */
+                       sp_ctx->state = SPNEGO_CONV_AUTH_CONFIRM;
+               }
+
+               break;
+
+       default:
+               status = NT_STATUS_INTERNAL_ERROR;
+               goto done;
+       }
+
+       status = NT_STATUS_OK;
+
+done:
+       if (len_in > 0) {
+               spnego_free_data(&sp_in);
+       }
+       data_blob_free(&token_out);
+       return status;
+}
+
+bool spnego_require_more_processing(struct spnego_context *sp_ctx)
+{
+       struct gse_context *gse_ctx;
+
+       /* see if spnego processing itself requires more */
+       if (sp_ctx->state == SPNEGO_CONV_AUTH_MORE ||
+           sp_ctx->state == SPNEGO_CONV_AUTH_CONFIRM) {
+               return true;
+       }
+
+       /* otherwise see if underlying mechnism does */
+       switch (sp_ctx->mech) {
+       case SPNEGO_KRB5:
+               gse_ctx = sp_ctx->mech_ctx.gssapi_state;
+               return gse_require_more_processing(gse_ctx);
+       case SPNEGO_NTLMSSP:
+               return false;
+       default:
+               DEBUG(0, ("Unsupported type in request!\n"));
+               return false;
+       }
+}
+
+NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
+                                   enum spnego_mech *type,
+                                   void **auth_context)
+{
+       switch (sp_ctx->mech) {
+       case SPNEGO_KRB5:
+               *auth_context = sp_ctx->mech_ctx.gssapi_state;
+               break;
+       case SPNEGO_NTLMSSP:
+               *auth_context = sp_ctx->mech_ctx.ntlmssp_state;
+               break;
+       default:
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       *type = sp_ctx->mech;
+       return NT_STATUS_OK;
+}
+
+DATA_BLOB spnego_get_session_key(TALLOC_CTX *mem_ctx,
+                                struct spnego_context *sp_ctx)
+{
+       DATA_BLOB sk;
+
+       switch (sp_ctx->mech) {
+       case SPNEGO_KRB5:
+               return gse_get_session_key(mem_ctx,
+                                          sp_ctx->mech_ctx.gssapi_state);
+       case SPNEGO_NTLMSSP:
+               sk = auth_ntlmssp_get_session_key(
+                                       sp_ctx->mech_ctx.ntlmssp_state);
+               return data_blob_dup_talloc(mem_ctx, &sk);
+       default:
+               DEBUG(0, ("Unsupported type in request!\n"));
+               return data_blob_null;
+       }
+}
+
+NTSTATUS spnego_sign(TALLOC_CTX *mem_ctx,
+                       struct spnego_context *sp_ctx,
+                       DATA_BLOB *data, DATA_BLOB *full_data,
+                       DATA_BLOB *signature)
+{
+       switch(sp_ctx->mech) {
+       case SPNEGO_KRB5:
+               return gse_sign(mem_ctx,
+                               sp_ctx->mech_ctx.gssapi_state,
+                               data, signature);
+       case SPNEGO_NTLMSSP:
+               return auth_ntlmssp_sign_packet(
+                                       sp_ctx->mech_ctx.ntlmssp_state,
+                                       mem_ctx,
+                                       data->data, data->length,
+                                       full_data->data, full_data->length,
+                                       signature);
+       default:
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+}
+
+NTSTATUS spnego_sigcheck(TALLOC_CTX *mem_ctx,
+                        struct spnego_context *sp_ctx,
+                        DATA_BLOB *data, DATA_BLOB *full_data,
+                        DATA_BLOB *signature)
+{
+       switch(sp_ctx->mech) {
+       case SPNEGO_KRB5:
+               return gse_sigcheck(mem_ctx,
+                                   sp_ctx->mech_ctx.gssapi_state,
+                                   data, signature);
+       case SPNEGO_NTLMSSP:
+               return auth_ntlmssp_check_packet(
+                                       sp_ctx->mech_ctx.ntlmssp_state,
+                                       data->data, data->length,
+                                       full_data->data, full_data->length,
+                                       signature);


-- 
Samba Shared Repository

Reply via email to