s3-libads: use ldap_init_fd() to initialize a ldap session if possible
[bbaumbach/samba-autobuild/.git] / source3 / passdb / secrets.c
1 /*
2    Unix SMB/CIFS implementation.
3    Copyright (C) Andrew Tridgell 1992-2001
4    Copyright (C) Andrew Bartlett      2002
5    Copyright (C) Rafal Szczesniak     2002
6    Copyright (C) Tim Potter           2001
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /* the Samba secrets database stores any generated, private information
23    such as the local SID and machine trust password */
24
25 #include "includes.h"
26 #include "system/filesys.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "librpc/gen_ndr/ndr_secrets.h"
29 #include "secrets.h"
30 #include "dbwrap/dbwrap.h"
31 #include "dbwrap/dbwrap_open.h"
32 #include "../libcli/security/security.h"
33 #include "util_tdb.h"
34
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_PASSDB
37
38 static struct db_context *db_ctx;
39
40 /* open up the secrets database with specified private_dir path */
41 bool secrets_init_path(const char *private_dir)
42 {
43         char *fname = NULL;
44         TALLOC_CTX *frame;
45
46         if (db_ctx != NULL) {
47                 return True;
48         }
49
50         if (private_dir == NULL) {
51                 return False;
52         }
53
54         frame = talloc_stackframe();
55         fname = talloc_asprintf(frame, "%s/secrets.tdb", private_dir);
56         if (fname == NULL) {
57                 TALLOC_FREE(frame);
58                 return False;
59         }
60
61         db_ctx = db_open(NULL, fname, 0,
62                          TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
63                          DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
64
65         if (db_ctx == NULL) {
66                 DEBUG(0,("Failed to open %s\n", fname));
67                 TALLOC_FREE(frame);
68                 return False;
69         }
70
71         TALLOC_FREE(frame);
72         return True;
73 }
74
75 /* open up the secrets database */
76 bool secrets_init(void)
77 {
78         return secrets_init_path(lp_private_dir());
79 }
80
81 struct db_context *secrets_db_ctx(void)
82 {
83         if (!secrets_init()) {
84                 return NULL;
85         }
86
87         return db_ctx;
88 }
89
90 /*
91  * close secrets.tdb
92  */
93 void secrets_shutdown(void)
94 {
95         TALLOC_FREE(db_ctx);
96 }
97
98 /* read a entry from the secrets database - the caller must free the result
99    if size is non-null then the size of the entry is put in there
100  */
101 void *secrets_fetch(const char *key, size_t *size)
102 {
103         TDB_DATA dbuf;
104         void *result;
105         NTSTATUS status;
106
107         if (!secrets_init()) {
108                 return NULL;
109         }
110
111         status = dbwrap_fetch(db_ctx, talloc_tos(), string_tdb_data(key),
112                               &dbuf);
113         if (!NT_STATUS_IS_OK(status)) {
114                 return NULL;
115         }
116
117         result = smb_memdup(dbuf.dptr, dbuf.dsize);
118         if (result == NULL) {
119                 return NULL;
120         }
121         TALLOC_FREE(dbuf.dptr);
122
123         if (size) {
124                 *size = dbuf.dsize;
125         }
126
127         return result;
128 }
129
130 /* store a secrets entry
131  */
132 bool secrets_store(const char *key, const void *data, size_t size)
133 {
134         NTSTATUS status;
135
136         if (!secrets_init()) {
137                 return false;
138         }
139
140         status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
141                                     make_tdb_data((const uint8_t *)data, size),
142                                     TDB_REPLACE);
143         return NT_STATUS_IS_OK(status);
144 }
145
146
147 /* delete a secets database entry
148  */
149 bool secrets_delete_entry(const char *key)
150 {
151         NTSTATUS status;
152         if (!secrets_init()) {
153                 return false;
154         }
155
156         status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
157
158         return NT_STATUS_IS_OK(status);
159 }
160
161 /*
162  * Deletes the key if it exists.
163  */
164 bool secrets_delete(const char *key)
165 {
166         bool exists;
167
168         if (!secrets_init()) {
169                 return false;
170         }
171
172         exists = dbwrap_exists(db_ctx, string_tdb_data(key));
173         if (!exists) {
174                 return true;
175         }
176
177         return secrets_delete_entry(key);
178 }
179
180 /**
181  * Form a key for fetching a trusted domain password
182  *
183  * @param domain trusted domain name
184  *
185  * @return stored password's key
186  **/
187 static char *trustdom_keystr(const char *domain)
188 {
189         char *keystr;
190
191         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
192                                             SECRETS_DOMTRUST_ACCT_PASS,
193                                             domain);
194         SMB_ASSERT(keystr != NULL);
195         return keystr;
196 }
197
198 /************************************************************************
199  Routine to get account password to trusted domain
200 ************************************************************************/
201
202 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
203                                            struct dom_sid *sid, time_t *pass_last_set_time)
204 {
205         struct TRUSTED_DOM_PASS pass;
206         enum ndr_err_code ndr_err;
207
208         /* unpacking structures */
209         DATA_BLOB blob;
210
211         /* fetching trusted domain password structure */
212         if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
213                                                    &blob.length))) {
214                 DEBUG(5, ("secrets_fetch failed!\n"));
215                 return False;
216         }
217
218         /* unpack trusted domain password */
219         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
220                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
221
222         SAFE_FREE(blob.data);
223
224         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
225                 return false;
226         }
227
228
229         /* the trust's password */
230         if (pwd) {
231                 *pwd = SMB_STRDUP(pass.pass);
232                 if (!*pwd) {
233                         return False;
234                 }
235         }
236
237         /* last change time */
238         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
239
240         /* domain sid */
241         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
242
243         return True;
244 }
245
246 /**
247  * Routine to store the password for trusted domain
248  *
249  * @param domain remote domain name
250  * @param pwd plain text password of trust relationship
251  * @param sid remote domain sid
252  *
253  * @return true if succeeded
254  **/
255
256 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
257                                            const struct dom_sid *sid)
258 {
259         bool ret;
260
261         /* packing structures */
262         DATA_BLOB blob;
263         enum ndr_err_code ndr_err;
264         struct TRUSTED_DOM_PASS pass;
265         ZERO_STRUCT(pass);
266
267         pass.uni_name = domain;
268         pass.uni_name_len = strlen(domain)+1;
269
270         /* last change time */
271         pass.mod_time = time(NULL);
272
273         /* password of the trust */
274         pass.pass_len = strlen(pwd);
275         pass.pass = pwd;
276
277         /* domain sid */
278         sid_copy(&pass.domain_sid, sid);
279
280         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
281                         (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
282         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
283                 return false;
284         }
285
286         ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
287
288         data_blob_free(&blob);
289
290         return ret;
291 }
292
293 /************************************************************************
294  Routine to delete the password for trusted domain
295 ************************************************************************/
296
297 bool trusted_domain_password_delete(const char *domain)
298 {
299         return secrets_delete_entry(trustdom_keystr(domain));
300 }
301
302 bool secrets_store_ldap_pw(const char* dn, char* pw)
303 {
304         char *key = NULL;
305         bool ret;
306
307         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
308                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
309                 return False;
310         }
311
312         ret = secrets_store(key, pw, strlen(pw)+1);
313
314         SAFE_FREE(key);
315         return ret;
316 }
317
318 /*******************************************************************
319  Find the ldap password.
320 ******************************************************************/
321
322 bool fetch_ldap_pw(char **dn, char** pw)
323 {
324         char *key = NULL;
325         size_t size = 0;
326
327         *dn = smb_xstrdup(lp_ldap_admin_dn());
328
329         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
330                 SAFE_FREE(*dn);
331                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
332                 return false;
333         }
334
335         *pw=(char *)secrets_fetch(key, &size);
336         SAFE_FREE(key);
337
338         if ((size != 0) && ((*pw)[size-1] != '\0')) {
339                 DBG_ERR("Non 0-terminated password for dn %s\n", *dn);
340                 SAFE_FREE(*pw);
341                 SAFE_FREE(*dn);
342                 return false;
343         }
344
345         if (!size) {
346                 /* Upgrade 2.2 style entry */
347                 char *p;
348                 char* old_style_key = SMB_STRDUP(*dn);
349                 char *data;
350                 fstring old_style_pw;
351
352                 if (!old_style_key) {
353                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
354                         SAFE_FREE(*pw);
355                         SAFE_FREE(*dn);
356                         return False;
357                 }
358
359                 for (p=old_style_key; *p; p++)
360                         if (*p == ',') *p = '/';
361
362                 data=(char *)secrets_fetch(old_style_key, &size);
363                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
364                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
365                         SAFE_FREE(old_style_key);
366                         SAFE_FREE(*pw);
367                         SAFE_FREE(*dn);
368                         SAFE_FREE(data);
369                         return False;
370                 }
371
372                 size = MIN(size, sizeof(fstring)-1);
373                 strncpy(old_style_pw, data, size);
374                 old_style_pw[size] = 0;
375
376                 SAFE_FREE(data);
377
378                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
379                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
380                         SAFE_FREE(old_style_key);
381                         SAFE_FREE(*pw);
382                         SAFE_FREE(*dn);
383                         return False;
384                 }
385                 if (!secrets_delete_entry(old_style_key)) {
386                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
387                 }
388
389                 SAFE_FREE(old_style_key);
390
391                 *pw = smb_xstrdup(old_style_pw);
392         }
393
394         return True;
395 }
396
397 /*******************************************************************************
398  Store a complete AFS keyfile into secrets.tdb.
399 *******************************************************************************/
400
401 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
402 {
403         fstring key;
404
405         if ((cell == NULL) || (keyfile == NULL))
406                 return False;
407
408         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
409                 return False;
410
411         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
412         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
413 }
414
415 /*******************************************************************************
416  Fetch the current (highest) AFS key from secrets.tdb
417 *******************************************************************************/
418 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
419 {
420         fstring key;
421         struct afs_keyfile *keyfile;
422         size_t size = 0;
423         uint32_t i;
424
425         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
426
427         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
428
429         if (keyfile == NULL)
430                 return False;
431
432         if (size != sizeof(struct afs_keyfile)) {
433                 SAFE_FREE(keyfile);
434                 return False;
435         }
436
437         i = ntohl(keyfile->nkeys);
438
439         if (i > SECRETS_AFS_MAXKEYS) {
440                 SAFE_FREE(keyfile);
441                 return False;
442         }
443
444         *result = keyfile->entry[i-1];
445
446         result->kvno = ntohl(result->kvno);
447
448         SAFE_FREE(keyfile);
449
450         return True;
451 }
452
453 /******************************************************************************
454   When kerberos is not available, choose between anonymous or
455   authenticated connections.
456
457   We need to use an authenticated connection if DCs have the
458   RestrictAnonymous registry entry set > 0, or the "Additional
459   restrictions for anonymous connections" set in the win2k Local
460   Security Policy.
461
462   Caller to free() result in domain, username, password
463 *******************************************************************************/
464 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
465 {
466         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
467         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
468         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
469
470         if (*username && **username) {
471
472                 if (!*domain || !**domain)
473                         *domain = smb_xstrdup(lp_workgroup());
474
475                 if (!*password || !**password)
476                         *password = smb_xstrdup("");
477
478                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
479                           *domain, *username));
480
481         } else {
482                 DEBUG(3, ("IPC$ connections done anonymously\n"));
483                 *username = smb_xstrdup("");
484                 *domain = smb_xstrdup("");
485                 *password = smb_xstrdup("");
486         }
487 }
488
489 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
490 {
491         char *tdbkey = NULL;
492         bool ret;
493
494         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
495                 DEBUG(0, ("asprintf failed!\n"));
496                 return False;
497         }
498
499         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
500
501         SAFE_FREE(tdbkey);
502         return ret;
503 }
504
505 /*******************************************************************
506  Find the ldap password.
507 ******************************************************************/
508
509 char *secrets_fetch_generic(const char *owner, const char *key)
510 {
511         char *secret = NULL;
512         char *tdbkey = NULL;
513
514         if (( ! owner) || ( ! key)) {
515                 DEBUG(1, ("Invalid Parameters"));
516                 return NULL;
517         }
518
519         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
520                 DEBUG(0, ("Out of memory!\n"));
521                 return NULL;
522         }
523
524         secret = (char *)secrets_fetch(tdbkey, NULL);
525         SAFE_FREE(tdbkey);
526
527         return secret;
528 }
529