[PATCH 5/8] s3:schannel streamline interface

Simo Sorce idra at samba.org
Thu Feb 18 12:44:09 MST 2010


Make calling schannel much easier by removing the need to explicitly open the
database. Let the abstraction do it instead.
---
 libcli/auth/schannel_state.h       |   27 +++---
 libcli/auth/schannel_state_tdb.c   |  198 ++++++++++++++++++++++++++++++-----
 source3/Makefile.in                |    3 +-
 source3/include/proto.h            |    9 --
 source3/include/secrets.h          |    2 -
 source3/passdb/secrets_schannel.c  |  131 ------------------------
 source3/rpc_server/srv_netlog_nt.c |   22 ++---
 source3/rpc_server/srv_pipe.c      |    2 +-
 8 files changed, 192 insertions(+), 202 deletions(-)
 delete mode 100644 source3/passdb/secrets_schannel.c

diff --git a/libcli/auth/schannel_state.h b/libcli/auth/schannel_state.h
index efa8d20..c1fa124 100644
--- a/libcli/auth/schannel_state.h
+++ b/libcli/auth/schannel_state.h
@@ -23,8 +23,20 @@
 #ifndef _LIBCLI_AUTH_SCHANNEL_STATE_H__
 #define _LIBCLI_AUTH_SCHANNEL_STATE_H__
 
+NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
+				  const char *computer_name,
+				  struct netlogon_creds_CredentialState **creds);
+
+NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
+				   struct netlogon_creds_CredentialState *creds);
+
+NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
+				    const char *computer_name,
+				    struct netr_Authenticator *received_authenticator,
+				    struct netr_Authenticator *return_authenticator,
+				    struct netlogon_creds_CredentialState **creds_out);
+
 struct ldb_context;
-struct tdb_context;
 
 NTSTATUS schannel_store_session_key_ldb(struct ldb_context *ldb,
 					TALLOC_CTX *mem_ctx,
@@ -39,17 +51,4 @@ NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
 					      struct netr_Authenticator *received_authenticator,
 					      struct netr_Authenticator *return_authenticator,
 					      struct netlogon_creds_CredentialState **creds_out);
-NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
-					TALLOC_CTX *mem_ctx,
-					struct netlogon_creds_CredentialState *creds);
-NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
-					TALLOC_CTX *mem_ctx,
-					const char *computer_name,
-					struct netlogon_creds_CredentialState **creds);
-NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
-					      TALLOC_CTX *mem_ctx,
-					      const char *computer_name,
-					      struct netr_Authenticator *received_authenticator,
-					      struct netr_Authenticator *return_authenticator,
-					      struct netlogon_creds_CredentialState **creds_out);
 #endif
diff --git a/libcli/auth/schannel_state_tdb.c b/libcli/auth/schannel_state_tdb.c
index 49c8908..434d7d7 100644
--- a/libcli/auth/schannel_state_tdb.c
+++ b/libcli/auth/schannel_state_tdb.c
@@ -26,9 +26,75 @@
 #include "../libcli/auth/schannel_state.h"
 #include "../librpc/gen_ndr/ndr_schannel.h"
 
+#define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
+
+/******************************************************************************
+ Open or create the schannel session store tdb.
+*******************************************************************************/
+
+#define SCHANNEL_STORE_VERSION_1 1
+#define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
+#define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
+
+static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
+{
+	TDB_DATA vers;
+	uint32 ver;
+	TDB_CONTEXT *tdb_sc = NULL;
+	char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
+
+	if (!fname) {
+		return NULL;
+	}
+
+	tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+
+	if (!tdb_sc) {
+		DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
+		TALLOC_FREE(fname);
+		return NULL;
+	}
+
+ again:
+	vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
+	if (vers.dptr == NULL) {
+		/* First opener, no version. */
+		SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
+		vers.dptr = (uint8 *)&ver;
+		vers.dsize = 4;
+		tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
+		vers.dptr = NULL;
+	} else if (vers.dsize == 4) {
+		ver = IVAL(vers.dptr,0);
+		if (ver == SCHANNEL_STORE_VERSION_2) {
+			DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
+				(int)ver, fname ));
+			tdb_wipe_all(tdb_sc);
+			goto again;
+		}
+		if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
+			DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
+				(int)ver, fname ));
+			tdb_close(tdb_sc);
+			tdb_sc = NULL;
+		}
+	} else {
+		tdb_close(tdb_sc);
+		tdb_sc = NULL;
+		DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
+			(int)vers.dsize, fname ));
+	}
+
+	SAFE_FREE(vers.dptr);
+	TALLOC_FREE(fname);
+
+	return tdb_sc;
+}
+
 /********************************************************************
  ********************************************************************/
 
+static
 NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
 					TALLOC_CTX *mem_ctx,
 					struct netlogon_creds_CredentialState *creds)
@@ -79,6 +145,7 @@ NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
 /********************************************************************
  ********************************************************************/
 
+static
 NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
 					TALLOC_CTX *mem_ctx,
 					const char *computer_name,
@@ -147,61 +214,134 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
 	return NT_STATUS_OK;
 }
 
+/******************************************************************************
+ Wrapper around schannel_fetch_session_key_tdb()
+ Note we must be root here.
+*******************************************************************************/
+
+NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
+				  const char *computer_name,
+				  struct netlogon_creds_CredentialState **creds)
+{
+	struct tdb_context *tdb;
+	NTSTATUS status;
+
+	tdb = open_schannel_session_store(mem_ctx);
+	if (!tdb) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	status = schannel_fetch_session_key_tdb(tdb, mem_ctx,
+						computer_name, creds);
+
+	tdb_close(tdb);
+
+	return status;
+}
+
+/******************************************************************************
+ Wrapper around schannel_store_session_key_tdb()
+ Note we must be root here.
+*******************************************************************************/
+
+NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
+				   struct netlogon_creds_CredentialState *creds)
+{
+	struct tdb_context *tdb;
+	NTSTATUS status;
+
+	tdb = open_schannel_session_store(mem_ctx);
+	if (!tdb) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
+
+	tdb_close(tdb);
+
+	return status;
+}
+
 /********************************************************************
+ Validate an incoming authenticator against the credentials for the
+ remote machine stored in the schannel database.
 
-  Validate an incoming authenticator against the credentials for the remote
-  machine.
-
-  The credentials are (re)read and from the schannel database, and
-  written back after the caclulations are performed.
-
-  The creds_out parameter (if not NULL) returns the credentials, if
-  the caller needs some of that information.
+ The credentials are (re)read and from the schannel database, and
+ written back after the caclulations are performed.
 
+ If the creds_out parameter is not NULL returns the credentials.
  ********************************************************************/
 
-NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
-					      TALLOC_CTX *mem_ctx,
-					      const char *computer_name,
-					      struct netr_Authenticator *received_authenticator,
-					      struct netr_Authenticator *return_authenticator,
-					      struct netlogon_creds_CredentialState **creds_out)
+NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
+				    const char *computer_name,
+				    struct netr_Authenticator *received_authenticator,
+				    struct netr_Authenticator *return_authenticator,
+				    struct netlogon_creds_CredentialState **creds_out)
 {
+	TALLOC_CTX *tmpctx;
+	struct tdb_context *tdb;
 	struct netlogon_creds_CredentialState *creds;
 	NTSTATUS status;
 	int ret;
 
+	tmpctx = talloc_named(mem_ctx, 0, "schannel_check_creds_state");
+	if (!tmpctx) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	tdb = open_schannel_session_store(tmpctx);
+	if (!tdb) {
+		status = NT_STATUS_ACCESS_DENIED;
+		goto done;
+	}
+
 	ret = tdb_transaction_start(tdb);
 	if (ret != 0) {
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+		goto done;
 	}
 
 	/* Because this is a shared structure (even across
 	 * disconnects) we must update the database every time we
 	 * update the structure */
 
-	status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name,
-						&creds);
+	status = schannel_fetch_session_key_tdb(tdb, tmpctx,
+						computer_name, &creds);
+	if (!NT_STATUS_IS_OK(status)) {
+		tdb_transaction_cancel(tdb);
+		goto done;
+	}
 
-	if (NT_STATUS_IS_OK(status)) {
-		status = netlogon_creds_server_step_check(creds,
-							  received_authenticator,
-							  return_authenticator);
+	status = netlogon_creds_server_step_check(creds,
+						  received_authenticator,
+						  return_authenticator);
+	if (!NT_STATUS_IS_OK(status)) {
+		tdb_transaction_cancel(tdb);
+		goto done;
 	}
 
-	if (NT_STATUS_IS_OK(status)) {
-		status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
+	status = schannel_store_session_key_tdb(tdb, tmpctx, creds);
+	if (!NT_STATUS_IS_OK(status)) {
+		tdb_transaction_cancel(tdb);
+		goto done;
 	}
 
-	if (NT_STATUS_IS_OK(status)) {
-		tdb_transaction_commit(tdb);
-		if (creds_out) {
-			*creds_out = creds;
-			talloc_steal(mem_ctx, creds);
+	tdb_transaction_commit(tdb);
+
+	if (creds_out) {
+		*creds_out = talloc_steal(mem_ctx, creds);
+		if (!*creds_out) {
+			status = NT_STATUS_NO_MEMORY;
+			goto done;
 		}
-	} else {
-		tdb_transaction_cancel(tdb);
 	}
 
+	status = NT_STATUS_OK;
+
+done:
+	talloc_free(tmpctx);
+	if (tdb) tdb_close(tdb);
 	return status;
 }
+
diff --git a/source3/Makefile.in b/source3/Makefile.in
index c409308..916fedd 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -507,8 +507,7 @@ SCHANNEL_OBJ = ../libcli/auth/credentials.o \
 	       ../libcli/auth/schannel_sign.o \
 	       ../libcli/auth/schannel_state_tdb.o \
 	       ../librpc/gen_ndr/ndr_schannel.o \
-	       ../librpc/ndr/ndr_schannel.o \
-	       passdb/secrets_schannel.o
+	       ../librpc/ndr/ndr_schannel.o
 
 LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
 	     libsmb/clikrb5.o libsmb/clispnego.o \
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 63270e1..54def2c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4750,15 +4750,6 @@ bool secrets_delete_generic(const char *owner, const char *key);
 bool secrets_store_local_schannel_key(uint8_t schannel_key[16]);
 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16]);
 
-/* The following definitions come from passdb/secrets_schannel.c  */
-
-TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx);
-NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
-				    const char *computer_name,
-				    struct netlogon_creds_CredentialState **pcreds);
-NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
-				    struct netlogon_creds_CredentialState *creds);
-
 /* The following definitions come from passdb/util_builtin.c  */
 
 bool lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name);
diff --git a/source3/include/secrets.h b/source3/include/secrets.h
index f369379..d0848bd 100644
--- a/source3/include/secrets.h
+++ b/source3/include/secrets.h
@@ -87,6 +87,4 @@ struct afs_keyfile {
 
 #define SECRETS_AFS_KEYFILE "SECRETS/AFS_KEYFILE"
 
-#define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
-
 #endif /* _SECRETS_H */
diff --git a/source3/passdb/secrets_schannel.c b/source3/passdb/secrets_schannel.c
deleted file mode 100644
index f4da625..0000000
--- a/source3/passdb/secrets_schannel.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-   Copyright (C) Guenther Deschner    2009
-
-   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/libcli_auth.h"
-#include "../libcli/auth/schannel_state.h"
-
-/******************************************************************************
- Open or create the schannel session store tdb.
-*******************************************************************************/
-
-#define SCHANNEL_STORE_VERSION_1 1
-#define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
-#define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
-
-TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
-{
-	TDB_DATA vers;
-	uint32 ver;
-	TDB_CONTEXT *tdb_sc = NULL;
-	char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
-
-	if (!fname) {
-		return NULL;
-	}
-
-	tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-
-	if (!tdb_sc) {
-		DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
-		TALLOC_FREE(fname);
-		return NULL;
-	}
-
- again:
-	vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
-	if (vers.dptr == NULL) {
-		/* First opener, no version. */
-		SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
-		vers.dptr = (uint8 *)&ver;
-		vers.dsize = 4;
-		tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
-		vers.dptr = NULL;
-	} else if (vers.dsize == 4) {
-		ver = IVAL(vers.dptr,0);
-		if (ver == SCHANNEL_STORE_VERSION_2) {
-			DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
-				(int)ver, fname ));
-			tdb_wipe_all(tdb_sc);
-			goto again;
-		}
-		if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
-			DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
-				(int)ver, fname ));
-			tdb_close(tdb_sc);
-			tdb_sc = NULL;
-		}
-	} else {
-		tdb_close(tdb_sc);
-		tdb_sc = NULL;
-		DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
-			(int)vers.dsize, fname ));
-	}
-
-	SAFE_FREE(vers.dptr);
-	TALLOC_FREE(fname);
-
-	return tdb_sc;
-}
-
-/******************************************************************************
- Wrapper around schannel_fetch_session_key_tdb()
- Note we must be root here.
-*******************************************************************************/
-
-NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
-				    const char *computer_name,
-				    struct netlogon_creds_CredentialState **pcreds)
-{
-	struct tdb_context *tdb;
-	NTSTATUS status;
-
-	tdb = open_schannel_session_store(mem_ctx);
-	if (!tdb) {
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
-	status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name, pcreds);
-
-	tdb_close(tdb);
-
-	return status;
-}
-
-/******************************************************************************
- Wrapper around schannel_store_session_key_tdb()
- Note we must be root here.
-*******************************************************************************/
-
-NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
-				    struct netlogon_creds_CredentialState *creds)
-{
-	struct tdb_context *tdb;
-	NTSTATUS status;
-
-	tdb = open_schannel_session_store(mem_ctx);
-	if (!tdb) {
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
-	status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
-
-	tdb_close(tdb);
-
-	return status;
-}
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index aeb321c..2ba0ffc 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -724,7 +724,7 @@ NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
 
 	/* Store off the state so we can continue after client disconnect. */
 	become_root();
-	status = schannel_store_session_key(p->mem_ctx, creds);
+	status = schannel_save_creds_state(p->mem_ctx, creds);
 	unbecome_root();
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -806,7 +806,6 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
 					     struct netlogon_creds_CredentialState **creds_out)
 {
 	NTSTATUS status;
-	struct tdb_context *tdb;
 	bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
 
 	if (schannel_global_required) {
@@ -818,17 +817,11 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
 		}
 	}
 
-	tdb = open_schannel_session_store(mem_ctx);
-	if (!tdb) {
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
-	status = schannel_creds_server_step_check_tdb(tdb, mem_ctx,
-						      computer_name,
-						      received_authenticator,
-						      return_authenticator,
-						      creds_out);
-	tdb_close(tdb);
+	status = schannel_check_creds_state(mem_ctx,
+					    computer_name,
+					    received_authenticator,
+					    return_authenticator,
+					    creds_out);
 
 	return status;
 }
@@ -1393,7 +1386,8 @@ NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p,
 	struct netlogon_creds_CredentialState *creds = NULL;
 
 	become_root();
-	status = schannel_fetch_session_key(p->mem_ctx, r->in.computer_name, &creds);
+	status = schannel_get_creds_state(p->mem_ctx,
+					  r->in.computer_name, &creds);
 	unbecome_root();
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 23f947f..5cde423 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1477,7 +1477,7 @@ static bool pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
 	 */
 
 	become_root();
-	status = schannel_fetch_session_key(p,
+	status = schannel_get_creds_state(p,
 					    neg.oem_netbios_computer.a,
 					    &creds);
 	unbecome_root();
-- 
1.6.6


--=-s85XraIvagGPiKkswX0v
Content-Disposition: attachment; filename="0006-schannel_tdb-make-code-compilable-in-both-trees.patch"
Content-Type: text/x-patch; name="0006-schannel_tdb-make-code-compilable-in-both-trees.patch"; charset="UTF-8"
Content-Transfer-Encoding: 7bit



More information about the samba-technical mailing list