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