2 Unix SMB/CIFS implementation.
4 module to store/fetch session keys for the schannel server
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006-2009
8 Copyright (C) Guenther Deschner 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "../libcli/auth/libcli_auth.h"
26 #include "../libcli/auth/schannel_state.h"
27 #include "../librpc/gen_ndr/ndr_schannel.h"
29 /********************************************************************
30 ********************************************************************/
32 NTSTATUS
schannel_store_session_key_tdb(struct tdb_context
*tdb
,
34 struct netlogon_creds_CredentialState
*creds
)
36 enum ndr_err_code ndr_err
;
42 keystr
= talloc_asprintf_strupper_m(mem_ctx
, "%s/%s",
43 SECRETS_SCHANNEL_STATE
,
44 creds
->computer_name
);
46 return NT_STATUS_NO_MEMORY
;
49 ndr_err
= ndr_push_struct_blob(&blob
, mem_ctx
, NULL
, creds
,
50 (ndr_push_flags_fn_t
)ndr_push_netlogon_creds_CredentialState
);
51 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
53 return ndr_map_error2ntstatus(ndr_err
);
56 value
.dptr
= blob
.data
;
57 value
.dsize
= blob
.length
;
59 ret
= tdb_store_bystring(tdb
, keystr
, value
, TDB_REPLACE
);
60 if (ret
!= TDB_SUCCESS
) {
61 DEBUG(0,("Unable to add %s to session key db - %s\n",
62 keystr
, tdb_errorstr(tdb
)));
64 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
67 DEBUG(3,("schannel_store_session_key_tdb: stored schannel info with key %s\n",
70 if (DEBUGLEVEL
>= 10) {
71 NDR_PRINT_DEBUG(netlogon_creds_CredentialState
, creds
);
79 /********************************************************************
80 ********************************************************************/
82 NTSTATUS
schannel_fetch_session_key_tdb(struct tdb_context
*tdb
,
84 const char *computer_name
,
85 struct netlogon_creds_CredentialState
**pcreds
)
89 enum ndr_err_code ndr_err
;
91 struct netlogon_creds_CredentialState
*creds
= NULL
;
96 keystr
= talloc_asprintf_strupper_m(mem_ctx
, "%s/%s",
97 SECRETS_SCHANNEL_STATE
,
100 status
= NT_STATUS_NO_MEMORY
;
104 value
= tdb_fetch_bystring(tdb
, keystr
);
106 DEBUG(0,("schannel_fetch_session_key_tdb: Failed to find entry with key %s\n",
108 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
112 creds
= talloc_zero(mem_ctx
, struct netlogon_creds_CredentialState
);
114 status
= NT_STATUS_NO_MEMORY
;
118 blob
= data_blob_const(value
.dptr
, value
.dsize
);
120 ndr_err
= ndr_pull_struct_blob(&blob
, creds
, NULL
, creds
,
121 (ndr_pull_flags_fn_t
)ndr_pull_netlogon_creds_CredentialState
);
122 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
123 status
= ndr_map_error2ntstatus(ndr_err
);
127 if (DEBUGLEVEL
>= 10) {
128 NDR_PRINT_DEBUG(netlogon_creds_CredentialState
, creds
);
131 DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n",
134 status
= NT_STATUS_OK
;
140 if (!NT_STATUS_IS_OK(status
)) {
150 /********************************************************************
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.
161 ********************************************************************/
163 NTSTATUS
schannel_creds_server_step_check_tdb(struct tdb_context
*tdb
,
165 const char *computer_name
,
166 struct netr_Authenticator
*received_authenticator
,
167 struct netr_Authenticator
*return_authenticator
,
168 struct netlogon_creds_CredentialState
**creds_out
)
170 struct netlogon_creds_CredentialState
*creds
;
174 ret
= tdb_transaction_start(tdb
);
176 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
179 /* Because this is a shared structure (even across
180 * disconnects) we must update the database every time we
181 * update the structure */
183 status
= schannel_fetch_session_key_tdb(tdb
, mem_ctx
, computer_name
,
186 if (NT_STATUS_IS_OK(status
)) {
187 status
= netlogon_creds_server_step_check(creds
,
188 received_authenticator
,
189 return_authenticator
);
192 if (NT_STATUS_IS_OK(status
)) {
193 status
= schannel_store_session_key_tdb(tdb
, mem_ctx
, creds
);
196 if (NT_STATUS_IS_OK(status
)) {
197 tdb_transaction_commit(tdb
);
200 talloc_steal(mem_ctx
, creds
);
203 tdb_transaction_cancel(tdb
);