summaryrefslogtreecommitdiff
path: root/source4/auth/gensec/schannel_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/auth/gensec/schannel_state.c')
-rw-r--r--source4/auth/gensec/schannel_state.c127
1 files changed, 83 insertions, 44 deletions
diff --git a/source4/auth/gensec/schannel_state.c b/source4/auth/gensec/schannel_state.c
index 7ef64ca00b..a73e450ec8 100644
--- a/source4/auth/gensec/schannel_state.c
+++ b/source4/auth/gensec/schannel_state.c
@@ -29,7 +29,7 @@
/*
connect to the schannel ldb
*/
-static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx)
+struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx)
{
char *path;
struct ldb_context *ldb;
@@ -64,44 +64,35 @@ static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx)
remember an established session key for a netr server authentication
use a simple ldb structure
*/
-NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
- struct creds_CredentialState *creds)
+NTSTATUS schannel_store_session_key_ldb(TALLOC_CTX *mem_ctx,
+ struct ldb_context *ldb,
+ struct creds_CredentialState *creds)
{
- struct ldb_context *ldb;
struct ldb_message *msg;
- struct ldb_val val, seed;
+ struct ldb_val val, seed, client_state, server_state;
char *f;
char *sct;
int ret;
- ldb = schannel_db_connect(mem_ctx);
- if (ldb == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags);
if (f == NULL) {
- talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
}
sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type);
if (sct == NULL) {
- talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
}
msg = ldb_msg_new(ldb);
if (msg == NULL) {
- talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
}
msg->dn = ldb_dn_build_child(msg, "computerName", creds->computer_name, NULL);
if (msg->dn == NULL) {
- talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
}
@@ -111,9 +102,16 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
seed.data = creds->seed.data;
seed.length = sizeof(creds->seed.data);
+ client_state.data = creds->client.data;
+ client_state.length = sizeof(creds->client.data);
+ server_state.data = creds->server.data;
+ server_state.length = sizeof(creds->server.data);
+
ldb_msg_add_string(msg, "objectClass", "schannelState");
ldb_msg_add_value(msg, "sessionKey", &val);
ldb_msg_add_value(msg, "seed", &seed);
+ ldb_msg_add_value(msg, "clientState", &client_state);
+ ldb_msg_add_value(msg, "serverState", &server_state);
ldb_msg_add_string(msg, "negotiateFlags", f);
ldb_msg_add_string(msg, "secureChannelType", sct);
ldb_msg_add_string(msg, "accountName", creds->account_name);
@@ -121,49 +119,65 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
ldb_msg_add_string(msg, "flatname", creds->domain);
samdb_msg_add_dom_sid(ldb, mem_ctx, msg, "objectSid", creds->sid);
- ret = ldb_transaction_start(ldb);
+ ldb_delete(ldb, msg->dn);
+
+ ret = ldb_add(ldb, msg);
+
if (ret != 0) {
- DEBUG(0,("Unable to start transaction to add %s to session key db - %s\n",
+ DEBUG(0,("Unable to add %s to session key db - %s\n",
ldb_dn_linearize(msg, msg->dn), ldb_errstring(ldb)));
- talloc_free(ldb);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- ldb_delete(ldb, msg->dn);
+ return NT_STATUS_OK;
+}
- ret = ldb_add(ldb, msg);
+NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
+ struct creds_CredentialState *creds)
+{
+ struct ldb_context *ldb;
+ NTSTATUS nt_status;
+ int ret;
+
+ ldb = schannel_db_connect(mem_ctx);
+ if (!ldb) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ ret = ldb_transaction_start(ldb);
if (ret != 0) {
- DEBUG(0,("Unable to add %s to session key db - %s\n",
- ldb_dn_linearize(msg, msg->dn), ldb_errstring(ldb)));
talloc_free(ldb);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- ret = ldb_transaction_commit(ldb);
+ nt_status = schannel_store_session_key_ldb(mem_ctx, ldb, creds);
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ ret = ldb_transaction_commit(ldb);
+ } else {
+ ret = ldb_transaction_cancel(ldb);
+ }
if (ret != 0) {
- DEBUG(0,("Unable to commit adding %s to session key db - %s\n",
- ldb_dn_linearize(msg, msg->dn), ldb_errstring(ldb)));
+ DEBUG(0,("Unable to commit adding credentials for %s to schannel key db - %s\n",
+ creds->computer_name, ldb_errstring(ldb)));
talloc_free(ldb);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
talloc_free(ldb);
-
- return NT_STATUS_OK;
+ return nt_status;
}
-
/*
read back a credentials back for a computer
*/
-NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
- const char *computer_name,
- const char *domain,
- struct creds_CredentialState **creds)
+NTSTATUS schannel_fetch_session_key_ldb(TALLOC_CTX *mem_ctx,
+ struct ldb_context *ldb,
+ const char *computer_name,
+ const char *domain,
+ struct creds_CredentialState **creds)
{
- struct ldb_context *ldb;
struct ldb_result *res;
int ret;
const struct ldb_val *val;
@@ -174,27 +188,21 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- ldb = schannel_db_connect(mem_ctx);
- if (ldb == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", computer_name, domain);
+ expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))",
+ computer_name, domain);
if (expr == NULL) {
- talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
}
ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res);
if (ret != LDB_SUCCESS || res->count != 1) {
- talloc_free(ldb);
+ DEBUG(3,("schannel: Failed to find a record for client: %s\n", computer_name));
return NT_STATUS_INVALID_HANDLE;
}
val = ldb_msg_find_ldb_val(res->msgs[0], "sessionKey");
if (val == NULL || val->length != 16) {
DEBUG(1,("schannel: record in schannel DB must contain a sessionKey of length 16, when searching for client: %s\n", computer_name));
- talloc_free(ldb);
return NT_STATUS_INTERNAL_ERROR;
}
@@ -203,12 +211,25 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
val = ldb_msg_find_ldb_val(res->msgs[0], "seed");
if (val == NULL || val->length != 8) {
DEBUG(1,("schannel: record in schannel DB must contain a vaid seed of length 8, when searching for client: %s\n", computer_name));
- talloc_free(ldb);
return NT_STATUS_INTERNAL_ERROR;
}
memcpy((*creds)->seed.data, val->data, 8);
+ val = ldb_msg_find_ldb_val(res->msgs[0], "clientState");
+ if (val == NULL || val->length != 8) {
+ DEBUG(1,("schannel: record in schannel DB must contain a vaid clientState of length 8, when searching for client: %s\n", computer_name));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ memcpy((*creds)->client.data, val->data, 8);
+
+ val = ldb_msg_find_ldb_val(res->msgs[0], "serverState");
+ if (val == NULL || val->length != 8) {
+ DEBUG(1,("schannel: record in schannel DB must contain a vaid serverState of length 8, when searching for client: %s\n", computer_name));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ memcpy((*creds)->server.data, val->data, 8);
+
(*creds)->negotiate_flags = ldb_msg_find_int(res->msgs[0], "negotiateFlags", 0);
(*creds)->secure_channel_type = ldb_msg_find_int(res->msgs[0], "secureChannelType", 0);
@@ -221,7 +242,25 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
(*creds)->sid = samdb_result_dom_sid(*creds, res->msgs[0], "objectSid");
- talloc_free(ldb);
-
return NT_STATUS_OK;
}
+
+NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
+ const char *computer_name,
+ const char *domain,
+ struct creds_CredentialState **creds)
+{
+ NTSTATUS nt_status;
+ struct ldb_context *ldb;
+
+ ldb = schannel_db_connect(mem_ctx);
+ if (!ldb) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ nt_status = schannel_fetch_session_key_ldb(mem_ctx, ldb,
+ computer_name, domain,
+ creds);
+ talloc_free(ldb);
+ return nt_status;
+}