summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2010-02-18 14:44:09 -0500
committerSimo Sorce <idra@samba.org>2010-02-23 12:46:50 -0500
commit3b12c38ac09ad253cf56099c243659a3a362ea67 (patch)
tree9a4058a85edaa3da2790630fcdf5009bbe2f6de9
parente5ab64a79902e710636352b01ccd0012d5df1c31 (diff)
downloadsamba-3b12c38ac09ad253cf56099c243659a3a362ea67.tar.gz
samba-3b12c38ac09ad253cf56099c243659a3a362ea67.tar.xz
samba-3b12c38ac09ad253cf56099c243659a3a362ea67.zip
s3:schannel streamline interface
Make calling schannel much easier by removing the need to explicitly open the database. Let the abstraction do it instead.
-rw-r--r--libcli/auth/schannel_state.h27
-rw-r--r--libcli/auth/schannel_state_tdb.c196
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/proto.h9
-rw-r--r--source3/include/secrets.h2
-rw-r--r--source3/passdb/secrets_schannel.c131
-rw-r--r--source3/rpc_server/srv_netlog_nt.c22
-rw-r--r--source3/rpc_server/srv_pipe.c2
8 files changed, 191 insertions, 201 deletions
diff --git a/libcli/auth/schannel_state.h b/libcli/auth/schannel_state.h
index efa8d20b086..c1fa1245cf5 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 49c89085be2..434d7d7f8cf 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;
+ }
- Validate an incoming authenticator against the credentials for the remote
- machine.
+ status = schannel_fetch_session_key_tdb(tdb, mem_ctx,
+ computer_name, creds);
- The credentials are (re)read and from the schannel database, and
- written back after the caclulations are performed.
+ tdb_close(tdb);
- The creds_out parameter (if not NULL) returns the credentials, if
- the caller needs some of that information.
+ 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.
+
+ 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 e966023a1ab..6e40f8362f6 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -508,8 +508,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 f8c3032ff13..be932a960db 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4746,15 +4746,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 f369379c701..d0848bdfa4a 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 f4da625fc60..00000000000
--- 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 769936ca200..15f19b52074 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 23f947f95bf..5cde423dafc 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();