[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Thu Sep 23 11:59:31 MDT 2010


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 <idra at samba.org>
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 <gd at samba.org>

commit 926a3f4fcdb82c86dff94a9ac78010d59a04ea1b
Author: Simo Sorce <idra at samba.org>
Date:   Sat Sep 11 09:46:08 2010 -0400

    s3-dcerpc: Use spnego own sign/seal functions
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 678993470fdc86a57841c7d35ec9c60f6b81c1cc
Author: Simo Sorce <idra at samba.org>
Date:   Fri Sep 3 16:43:38 2010 -0400

    libcli: fix compile warning
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit b11fff1f481a21d84b713421cfbfd42ef1e73f4b
Author: Simo Sorce <idra at samba.org>
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 <gd at samba.org>

commit 3453bc7b1108390354c0825ee6b2b0bb28fca2f3
Author: Simo Sorce <idra at samba.org>
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 <gd at samba.org>

commit 0ec372057308198cd2f1742c4a56868e6dab7213
Author: Simo Sorce <idra at samba.org>
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 <gd at samba.org>

commit d10e192b83e2c016873d7c2198f62173834287f0
Author: Simo Sorce <idra at samba.org>
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 <gd at samba.org>

commit b475cfd0b2376fdf2a8426f33be8c940b035fe26
Author: Simo Sorce <idra at samba.org>
Date:   Fri Sep 3 10:19:27 2010 -0400

    s3-dcerpc: use new spnego server code
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 4cdee9b0eddd47ad2cfb866f63cdeb3f65200a3e
Author: Simo Sorce <idra at samba.org>
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 <gd at samba.org>

commit 77c73a5ec92f9294195dfef977f66dfe66182c6d
Author: Simo Sorce <idra at samba.org>
Date:   Fri Sep 3 09:38:57 2010 -0400

    spnego: make spnego_context public
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 2c9f420d75ac0a231b84c2d85e9470bb595d6daf
Author: Simo Sorce <idra at samba.org>
Date:   Thu Sep 2 17:50:21 2010 -0400

    s3-dcerpc: move client spnego stuff in /librpc/crypto
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 59722ef2fb6973ac06de5c17c3f84995bac20816
Author: Simo Sorce <idra at samba.org>
Date:   Thu Sep 2 17:43:21 2010 -0400

    spnego: avoid explicit dependency on dcerpc specific structures
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 62d7226b7898ade0dc19a5b13a9632fd096c5771
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 18:31:05 2010 -0400

    s3-dcesrv: use gssapi helper in srv_pipe.c
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 28c22d04fb816f1c4418b95e9e69710e488af94c
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 18:27:53 2010 -0400

    s3-dcerpc: add server helpers for gssapi auth
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 8efd31ccad96bb6da1bdb6bf2fbb8fe9d67b640e
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 17:09:52 2010 -0400

    s3-dcesrv: use ntlmssp helper in srv_pipe.c
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit bbf535764b39941e64664b51562cb1525a99a959
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 15:50:06 2010 -0400

    s3-dcerpc: add server helpers for ntlmssp auth
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 4194383cfe151aa57e0b288c77a113c5922eb019
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 19:05:43 2010 -0400

    gssapi: remove unused function argument
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 412ebad02b74d8fbb1f6493e87abab7e345dc000
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 17:27:56 2010 -0400

    gssapi: avoid explicit dependency on dcerpc specific structures
    
    Signed-off-by: Günther Deschner <gd at samba.org>

commit 0e5eb82a6f29e33ca2cafe0ed7103395837b3fc0
Author: Simo Sorce <idra at samba.org>
Date:   Wed Sep 1 11:58:33 2010 -0400

    s3-dcerpc: move crypto stuff in /librpc/crypto
    
    Signed-off-by: Günther Deschner <gd at samba.org>

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

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


More information about the samba-cvs mailing list