f4da625fc6008334d90838d00b20a39aad834226
[ira/wip.git] / source3 / passdb / secrets_schannel.c
1 /*
2    Unix SMB/CIFS implementation.
3    Copyright (C) Guenther Deschner    2009
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "includes.h"
20 #include "../libcli/auth/libcli_auth.h"
21 #include "../libcli/auth/schannel_state.h"
22
23 /******************************************************************************
24  Open or create the schannel session store tdb.
25 *******************************************************************************/
26
27 #define SCHANNEL_STORE_VERSION_1 1
28 #define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
29 #define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
30
31 TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
32 {
33         TDB_DATA vers;
34         uint32 ver;
35         TDB_CONTEXT *tdb_sc = NULL;
36         char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
37
38         if (!fname) {
39                 return NULL;
40         }
41
42         tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
43
44         if (!tdb_sc) {
45                 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
46                 TALLOC_FREE(fname);
47                 return NULL;
48         }
49
50  again:
51         vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
52         if (vers.dptr == NULL) {
53                 /* First opener, no version. */
54                 SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT);
55                 vers.dptr = (uint8 *)&ver;
56                 vers.dsize = 4;
57                 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
58                 vers.dptr = NULL;
59         } else if (vers.dsize == 4) {
60                 ver = IVAL(vers.dptr,0);
61                 if (ver == SCHANNEL_STORE_VERSION_2) {
62                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
63                                 (int)ver, fname ));
64                         tdb_wipe_all(tdb_sc);
65                         goto again;
66                 }
67                 if (ver != SCHANNEL_STORE_VERSION_CURRENT) {
68                         DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
69                                 (int)ver, fname ));
70                         tdb_close(tdb_sc);
71                         tdb_sc = NULL;
72                 }
73         } else {
74                 tdb_close(tdb_sc);
75                 tdb_sc = NULL;
76                 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
77                         (int)vers.dsize, fname ));
78         }
79
80         SAFE_FREE(vers.dptr);
81         TALLOC_FREE(fname);
82
83         return tdb_sc;
84 }
85
86 /******************************************************************************
87  Wrapper around schannel_fetch_session_key_tdb()
88  Note we must be root here.
89 *******************************************************************************/
90
91 NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
92                                     const char *computer_name,
93                                     struct netlogon_creds_CredentialState **pcreds)
94 {
95         struct tdb_context *tdb;
96         NTSTATUS status;
97
98         tdb = open_schannel_session_store(mem_ctx);
99         if (!tdb) {
100                 return NT_STATUS_ACCESS_DENIED;
101         }
102
103         status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name, pcreds);
104
105         tdb_close(tdb);
106
107         return status;
108 }
109
110 /******************************************************************************
111  Wrapper around schannel_store_session_key_tdb()
112  Note we must be root here.
113 *******************************************************************************/
114
115 NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
116                                     struct netlogon_creds_CredentialState *creds)
117 {
118         struct tdb_context *tdb;
119         NTSTATUS status;
120
121         tdb = open_schannel_session_store(mem_ctx);
122         if (!tdb) {
123                 return NT_STATUS_ACCESS_DENIED;
124         }
125
126         status = schannel_store_session_key_tdb(tdb, mem_ctx, creds);
127
128         tdb_close(tdb);
129
130         return status;
131 }