24
24
#include "includes.h"
25
#include "../libcli/auth/libcli_auth.h"
26
#include "../libcli/auth/schannel_state.h"
25
#include "system/filesys.h"
27
#include "../lib/util/util_tdb.h"
28
#include "../libcli/auth/schannel.h"
27
29
#include "../librpc/gen_ndr/ndr_schannel.h"
30
#include "lib/util/tdb_wrap.h"
32
#define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL"
34
/******************************************************************************
35
Open or create the schannel session store tdb. Non-static so it can
36
be called from parent processes to corectly handle TDB_CLEAR_IF_FIRST
37
*******************************************************************************/
39
struct tdb_wrap *open_schannel_session_store(TALLOC_CTX *mem_ctx,
40
const char *private_dir)
42
struct tdb_wrap *tdb_sc = NULL;
43
char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", private_dir);
49
tdb_sc = tdb_wrap_open(mem_ctx, fname, 0, TDB_CLEAR_IF_FIRST|TDB_NOSYNC, O_RDWR|O_CREAT, 0600);
52
DEBUG(0,("open_schannel_session_store: Failed to open %s - %s\n",
53
fname, strerror(errno)));
29
63
/********************************************************************
30
64
********************************************************************/
32
NTSTATUS schannel_store_session_key_tdb(struct tdb_context *tdb,
67
NTSTATUS schannel_store_session_key_tdb(struct tdb_wrap *tdb_sc,
33
68
TALLOC_CTX *mem_ctx,
34
69
struct netlogon_creds_CredentialState *creds)
147
195
return NT_STATUS_OK;
198
/******************************************************************************
199
Wrapper around schannel_fetch_session_key_tdb()
200
Note we must be root here.
201
*******************************************************************************/
203
NTSTATUS schannel_get_creds_state(TALLOC_CTX *mem_ctx,
204
const char *db_priv_dir,
205
const char *computer_name,
206
struct netlogon_creds_CredentialState **_creds)
209
struct tdb_wrap *tdb_sc;
210
struct netlogon_creds_CredentialState *creds;
213
tmpctx = talloc_named(mem_ctx, 0, "schannel_get_creds_state");
215
return NT_STATUS_NO_MEMORY;
218
tdb_sc = open_schannel_session_store(tmpctx, db_priv_dir);
220
return NT_STATUS_ACCESS_DENIED;
223
status = schannel_fetch_session_key_tdb(tdb_sc, tmpctx,
224
computer_name, &creds);
225
if (NT_STATUS_IS_OK(status)) {
226
*_creds = talloc_steal(mem_ctx, creds);
228
status = NT_STATUS_NO_MEMORY;
236
/******************************************************************************
237
Wrapper around schannel_store_session_key_tdb()
238
Note we must be root here.
239
*******************************************************************************/
241
NTSTATUS schannel_save_creds_state(TALLOC_CTX *mem_ctx,
242
const char *db_priv_dir,
243
struct netlogon_creds_CredentialState *creds)
246
struct tdb_wrap *tdb_sc;
249
tmpctx = talloc_named(mem_ctx, 0, "schannel_save_creds_state");
251
return NT_STATUS_NO_MEMORY;
254
tdb_sc = open_schannel_session_store(tmpctx, db_priv_dir);
256
return NT_STATUS_ACCESS_DENIED;
259
status = schannel_store_session_key_tdb(tdb_sc, tmpctx, creds);
150
265
/********************************************************************
152
Validate an incoming authenticator against the credentials for the remote
155
The credentials are (re)read and from the schannel database, and
156
written back after the caclulations are performed.
158
The creds_out parameter (if not NULL) returns the credentials, if
159
the caller needs some of that information.
266
Validate an incoming authenticator against the credentials for the
267
remote machine stored in the schannel database.
269
The credentials are (re)read and from the schannel database, and
270
written back after the caclulations are performed.
272
If the creds_out parameter is not NULL returns the credentials.
161
273
********************************************************************/
163
NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
165
const char *computer_name,
166
bool schannel_required_for_call,
167
bool schannel_in_use,
168
struct netr_Authenticator *received_authenticator,
169
struct netr_Authenticator *return_authenticator,
170
struct netlogon_creds_CredentialState **creds_out)
275
NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx,
276
const char *db_priv_dir,
277
const char *computer_name,
278
struct netr_Authenticator *received_authenticator,
279
struct netr_Authenticator *return_authenticator,
280
struct netlogon_creds_CredentialState **creds_out)
283
struct tdb_wrap *tdb_sc;
172
284
struct netlogon_creds_CredentialState *creds;
176
ret = tdb_transaction_start(tdb);
288
tmpctx = talloc_named(mem_ctx, 0, "schannel_check_creds_state");
290
return NT_STATUS_NO_MEMORY;
293
tdb_sc = open_schannel_session_store(tmpctx, db_priv_dir);
295
status = NT_STATUS_ACCESS_DENIED;
299
ret = tdb_transaction_start(tdb_sc->tdb);
178
return NT_STATUS_INTERNAL_DB_CORRUPTION;
301
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
181
305
/* Because this is a shared structure (even across
182
306
* disconnects) we must update the database every time we
183
307
* update the structure */
185
status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name,
188
/* If we are flaged that schannel is required for a call, and
189
* it is not in use, then make this an error */
191
/* It would be good to make this mandatory once schannel is
192
* negotiated, but this is not what windows does */
193
if (schannel_required_for_call && !schannel_in_use) {
194
DEBUG(0,("schannel_creds_server_step_check_tdb: "
195
"client %s not using schannel for netlogon, despite negotiating it\n",
196
creds->computer_name ));
197
tdb_transaction_cancel(tdb);
198
return NT_STATUS_ACCESS_DENIED;
201
if (NT_STATUS_IS_OK(status)) {
202
status = netlogon_creds_server_step_check(creds,
203
received_authenticator,
204
return_authenticator);
207
if (NT_STATUS_IS_OK(status)) {
208
status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
211
if (NT_STATUS_IS_OK(status)) {
212
tdb_transaction_commit(tdb);
215
talloc_steal(mem_ctx, creds);
309
status = schannel_fetch_session_key_tdb(tdb_sc, tmpctx,
310
computer_name, &creds);
311
if (!NT_STATUS_IS_OK(status)) {
312
tdb_transaction_cancel(tdb_sc->tdb);
316
status = netlogon_creds_server_step_check(creds,
317
received_authenticator,
318
return_authenticator);
319
if (!NT_STATUS_IS_OK(status)) {
320
tdb_transaction_cancel(tdb_sc->tdb);
324
status = schannel_store_session_key_tdb(tdb_sc, tmpctx, creds);
325
if (!NT_STATUS_IS_OK(status)) {
326
tdb_transaction_cancel(tdb_sc->tdb);
330
tdb_transaction_commit(tdb_sc->tdb);
333
*creds_out = talloc_steal(mem_ctx, creds);
335
status = NT_STATUS_NO_MEMORY;
218
tdb_transaction_cancel(tdb);
340
status = NT_STATUS_OK;