diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-06-05 01:27:02 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:56:27 -0500 |
commit | cd35e12c7f96ef5297e78e6cd7a37f118382d722 (patch) | |
tree | c85ca76931c2897f79828569e6cb80907395d0d8 | |
parent | 4ee70616cc25d8b1bfec2c7d0285eb06b35ea873 (diff) | |
download | samba-cd35e12c7f96ef5297e78e6cd7a37f118382d722.tar.gz samba-cd35e12c7f96ef5297e78e6cd7a37f118382d722.tar.bz2 samba-cd35e12c7f96ef5297e78e6cd7a37f118382d722.zip |
r1015: commit the schannel session key handling code now, so abartlet and
metze can have a look. Not tested yet, as I'm still writing the server
side schannel code.
(This used to be commit 768cc0193a1267274f297c47a36bef4acd391e83)
-rw-r--r-- | source4/rpc_server/netlogon/schannel_state.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/source4/rpc_server/netlogon/schannel_state.c b/source4/rpc_server/netlogon/schannel_state.c new file mode 100644 index 0000000000..f4190f21b4 --- /dev/null +++ b/source4/rpc_server/netlogon/schannel_state.c @@ -0,0 +1,143 @@ +/* + Unix SMB/CIFS implementation. + + module to store/fetch session keys for the schannel server + + Copyright (C) Andrew Tridgell 2004 + + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* a reasonable amount of time to keep credentials live */ +#define SCHANNEL_CREDENTIALS_EXPIRY 600 + +/* + connect to the schannel ldb +*/ +static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) +{ + char *path; + struct ldb_context *ldb; + + path = lock_path(mem_ctx, "schannel.ldb"); + if (!path) { + return NULL; + } + + ldb = ldb_connect(path, 0, NULL); + if (!ldb) { + return NULL; + } + + ldb_set_alloc(ldb, talloc_ldb_alloc, mem_ctx); + + return ldb; +} + +/* + remember an established session key for a netr server authentication + use a simple ldb structure +*/ +NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, + const char *computer_name, struct creds_CredentialState *creds) +{ + struct ldb_context *ldb; + struct ldb_message msg; + struct ldb_val val; + char *s = NULL; + time_t expiry = time(NULL) + SCHANNEL_CREDENTIALS_EXPIRY; + int ret; + + ldb = schannel_db_connect(mem_ctx); + if (ldb == NULL) { + return NT_STATUS_NO_MEMORY; + } + + asprintf(&s, "%u", (unsigned int)expiry); + + if (s == NULL) { + ldb_close(ldb); + return NT_STATUS_NO_MEMORY; + } + + + ZERO_STRUCT(msg); + msg.dn = talloc_strdup(mem_ctx, computer_name); + if (msg.dn == NULL) { + ldb_close(ldb); + return NT_STATUS_NO_MEMORY; + } + + val.data = creds->session_key; + val.length = sizeof(creds->session_key); + + ldb_msg_add_value(ldb, &msg, "sessionKey", &val); + ldb_msg_add_string(ldb, &msg, "expiry", s); + + ret = ldb_add(ldb, &msg); + ldb_close(ldb); + + if (ret != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + return NT_STATUS_OK; +} + + +/* + read back a session key for a computer +*/ +NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, + const char *computer_name, uint8_t session_key[16]) +{ + struct ldb_context *ldb; + time_t expiry; + struct ldb_message **res; + int ret; + const struct ldb_val *val; + + ldb = schannel_db_connect(mem_ctx); + if (ldb == NULL) { + return NT_STATUS_NO_MEMORY; + } + + ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, "(dn=%s)", NULL, &res); + if (ret != 1) { + ldb_close(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + expiry = ldb_msg_find_uint(res[0], "expiry", 0); + if (expiry < time(NULL)) { + DEBUG(1,("schannel: attempt to use expired session key for %s\n", computer_name)); + ldb_close(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + val = ldb_msg_find_ldb_val(res[0], "sessionKey"); + if (val == NULL || val->length != 16) { + ldb_close(ldb); + return NT_STATUS_INVALID_HANDLE; + } + + memcpy(session_key, val->data, 16); + + ldb_close(ldb); + + return NT_STATUS_OK; +} |