s3:dbwrap_ctdb: change db_ctdb_transaction_store() to return NTSTATUS.
[amitay/samba.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 "../libcli/auth/libcli_auth.h"
27 #include "librpc/gen_ndr/ndr_secrets.h"
28
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_PASSDB
31
32 static struct db_context *db_ctx;
33
34 /* Urrrg. global.... */
35 bool global_machine_password_needs_changing;
36
37 /**
38  * Use a TDB to store an incrementing random seed.
39  *
40  * Initialised to the current pid, the very first time Samba starts,
41  * and incremented by one each time it is needed.
42  *
43  * @note Not called by systems with a working /dev/urandom.
44  */
45 static void get_rand_seed(void *userdata, int *new_seed)
46 {
47         *new_seed = sys_getpid();
48         if (db_ctx) {
49                 dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed",
50                                                  new_seed, 1);
51         }
52 }
53
54 /* open up the secrets database */
55 bool secrets_init(void)
56 {
57         char *fname = NULL;
58         unsigned char dummy;
59
60         if (db_ctx != NULL)
61                 return True;
62
63         fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
64                                 lp_private_dir());
65         if (fname == NULL) {
66                 return false;
67         }
68
69         db_ctx = db_open(NULL, fname, 0,
70                          TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
71
72         if (db_ctx == NULL) {
73                 DEBUG(0,("Failed to open %s\n", fname));
74                 TALLOC_FREE(fname);
75                 return False;
76         }
77
78         TALLOC_FREE(fname);
79
80         /**
81          * Set a reseed function for the crypto random generator
82          *
83          * This avoids a problem where systems without /dev/urandom
84          * could send the same challenge to multiple clients
85          */
86         set_rand_reseed_callback(get_rand_seed, NULL);
87
88         /* Ensure that the reseed is done now, while we are root, etc */
89         generate_random_buffer(&dummy, sizeof(dummy));
90
91         return True;
92 }
93
94 struct db_context *secrets_db_ctx(void)
95 {
96         if (!secrets_init()) {
97                 return NULL;
98         }
99
100         return db_ctx;
101 }
102
103 /*
104  * close secrets.tdb
105  */
106 void secrets_shutdown(void)
107 {
108         TALLOC_FREE(db_ctx);
109 }
110
111 /* read a entry from the secrets database - the caller must free the result
112    if size is non-null then the size of the entry is put in there
113  */
114 void *secrets_fetch(const char *key, size_t *size)
115 {
116         TDB_DATA dbuf;
117         void *result;
118
119         if (!secrets_init()) {
120                 return NULL;
121         }
122
123         if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
124                           &dbuf) != 0) {
125                 return NULL;
126         }
127
128         result = memdup(dbuf.dptr, dbuf.dsize);
129         if (result == NULL) {
130                 return NULL;
131         }
132         TALLOC_FREE(dbuf.dptr);
133
134         if (size) {
135                 *size = dbuf.dsize;
136         }
137
138         return result;
139 }
140
141 /* store a secrets entry
142  */
143 bool secrets_store(const char *key, const void *data, size_t size)
144 {
145         NTSTATUS status;
146
147         if (!secrets_init()) {
148                 return false;
149         }
150
151         status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
152                                     make_tdb_data((const uint8 *)data, size),
153                                     TDB_REPLACE);
154         return NT_STATUS_IS_OK(status);
155 }
156
157
158 /* delete a secets database entry
159  */
160 bool secrets_delete(const char *key)
161 {
162         NTSTATUS status;
163         if (!secrets_init()) {
164                 return false;
165         }
166
167         status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
168
169         return NT_STATUS_IS_OK(status);
170 }
171
172 /**
173  * Form a key for fetching the domain sid
174  *
175  * @param domain domain name
176  *
177  * @return keystring
178  **/
179 static const char *domain_sid_keystr(const char *domain)
180 {
181         char *keystr;
182
183         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
184                                             SECRETS_DOMAIN_SID, domain);
185         SMB_ASSERT(keystr != NULL);
186         return keystr;
187 }
188
189 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
190 {
191         bool ret;
192
193         ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
194
195         /* Force a re-query, in case we modified our domain */
196         if (ret)
197                 reset_global_sam_sid();
198         return ret;
199 }
200
201 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
202 {
203         DOM_SID *dyn_sid;
204         size_t size = 0;
205
206         dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
207
208         if (dyn_sid == NULL)
209                 return False;
210
211         if (size != sizeof(DOM_SID)) {
212                 SAFE_FREE(dyn_sid);
213                 return False;
214         }
215
216         *sid = *dyn_sid;
217         SAFE_FREE(dyn_sid);
218         return True;
219 }
220
221 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
222 {
223         fstring key;
224
225         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
226         strupper_m(key);
227         return secrets_store(key, guid, sizeof(struct GUID));
228 }
229
230 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
231 {
232         struct GUID *dyn_guid;
233         fstring key;
234         size_t size = 0;
235         struct GUID new_guid;
236
237         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
238         strupper_m(key);
239         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
240
241         if (!dyn_guid) {
242                 if (lp_server_role() == ROLE_DOMAIN_PDC) {
243                         new_guid = GUID_random();
244                         if (!secrets_store_domain_guid(domain, &new_guid))
245                                 return False;
246                         dyn_guid = (struct GUID *)secrets_fetch(key, &size);
247                 }
248                 if (dyn_guid == NULL) {
249                         return False;
250                 }
251         }
252
253         if (size != sizeof(struct GUID)) {
254                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
255                 SAFE_FREE(dyn_guid);
256                 return False;
257         }
258
259         *guid = *dyn_guid;
260         SAFE_FREE(dyn_guid);
261         return True;
262 }
263
264 bool secrets_store_local_schannel_key(uint8_t schannel_key[16])
265 {
266         return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16);
267 }
268
269 bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16])
270 {
271         size_t size = 0;
272         uint8_t *key;
273
274         key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size);
275         if (key == NULL) {
276                 return false;
277         }
278
279         if (size != 16) {
280                 SAFE_FREE(key);
281                 return false;
282         }
283
284         memcpy(schannel_key, key, 16);
285         SAFE_FREE(key);
286         return true;
287 }
288
289 /**
290  * Form a key for fetching the machine trust account sec channel type
291  *
292  * @param domain domain name
293  *
294  * @return keystring
295  **/
296 static const char *machine_sec_channel_type_keystr(const char *domain)
297 {
298         char *keystr;
299
300         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
301                                             SECRETS_MACHINE_SEC_CHANNEL_TYPE,
302                                             domain);
303         SMB_ASSERT(keystr != NULL);
304         return keystr;
305 }
306
307 /**
308  * Form a key for fetching the machine trust account last change time
309  *
310  * @param domain domain name
311  *
312  * @return keystring
313  **/
314 static const char *machine_last_change_time_keystr(const char *domain)
315 {
316         char *keystr;
317
318         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
319                                             SECRETS_MACHINE_LAST_CHANGE_TIME,
320                                             domain);
321         SMB_ASSERT(keystr != NULL);
322         return keystr;
323 }
324
325
326 /**
327  * Form a key for fetching the machine trust account password
328  *
329  * @param domain domain name
330  *
331  * @return keystring
332  **/
333 static const char *machine_password_keystr(const char *domain)
334 {
335         char *keystr;
336
337         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
338                                             SECRETS_MACHINE_PASSWORD, domain);
339         SMB_ASSERT(keystr != NULL);
340         return keystr;
341 }
342
343 /**
344  * Form a key for fetching the machine trust account password
345  *
346  * @param domain domain name
347  *
348  * @return stored password's key
349  **/
350 static const char *trust_keystr(const char *domain)
351 {
352         char *keystr;
353
354         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
355                                             SECRETS_MACHINE_ACCT_PASS, domain);
356         SMB_ASSERT(keystr != NULL);
357         return keystr;
358 }
359
360 /**
361  * Form a key for fetching a trusted domain password
362  *
363  * @param domain trusted domain name
364  *
365  * @return stored password's key
366  **/
367 static char *trustdom_keystr(const char *domain)
368 {
369         char *keystr;
370
371         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
372                                             SECRETS_DOMTRUST_ACCT_PASS,
373                                             domain);
374         SMB_ASSERT(keystr != NULL);
375         return keystr;
376 }
377
378 /************************************************************************
379  Lock the trust password entry.
380 ************************************************************************/
381
382 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
383 {
384         if (!secrets_init()) {
385                 return NULL;
386         }
387
388         return db_ctx->fetch_locked(
389                 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
390 }
391
392 /************************************************************************
393  Routine to get the default secure channel type for trust accounts
394 ************************************************************************/
395
396 enum netr_SchannelType get_default_sec_channel(void)
397 {
398         if (lp_server_role() == ROLE_DOMAIN_BDC ||
399             lp_server_role() == ROLE_DOMAIN_PDC) {
400                 return SEC_CHAN_BDC;
401         } else {
402                 return SEC_CHAN_WKSTA;
403         }
404 }
405
406 /************************************************************************
407  Routine to get the trust account password for a domain.
408  This only tries to get the legacy hashed version of the password.
409  The user of this function must have locked the trust password file using
410  the above secrets_lock_trust_account_password().
411 ************************************************************************/
412
413 bool secrets_fetch_trust_account_password_legacy(const char *domain,
414                                                  uint8 ret_pwd[16],
415                                                  time_t *pass_last_set_time,
416                                                  enum netr_SchannelType *channel)
417 {
418         struct machine_acct_pass *pass;
419         size_t size = 0;
420
421         if (!(pass = (struct machine_acct_pass *)secrets_fetch(
422                       trust_keystr(domain), &size))) {
423                 DEBUG(5, ("secrets_fetch failed!\n"));
424                 return False;
425         }
426
427         if (size != sizeof(*pass)) {
428                 DEBUG(0, ("secrets were of incorrect size!\n"));
429                 SAFE_FREE(pass);
430                 return False;
431         }
432
433         if (pass_last_set_time) {
434                 *pass_last_set_time = pass->mod_time;
435         }
436         memcpy(ret_pwd, pass->hash, 16);
437
438         if (channel) {
439                 *channel = get_default_sec_channel();
440         }
441
442         /* Test if machine password has expired and needs to be changed */
443         if (lp_machine_password_timeout()) {
444                 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
445                                 (time_t)lp_machine_password_timeout())) {
446                         global_machine_password_needs_changing = True;
447                 }
448         }
449
450         SAFE_FREE(pass);
451         return True;
452 }
453
454 /************************************************************************
455  Routine to get the trust account password for a domain.
456  The user of this function must have locked the trust password file using
457  the above secrets_lock_trust_account_password().
458 ************************************************************************/
459
460 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
461                                           time_t *pass_last_set_time,
462                                           enum netr_SchannelType *channel)
463 {
464         char *plaintext;
465
466         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
467                                                    channel);
468         if (plaintext) {
469                 DEBUG(4,("Using cleartext machine password\n"));
470                 E_md4hash(plaintext, ret_pwd);
471                 SAFE_FREE(plaintext);
472                 return True;
473         }
474
475         return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
476                                                            pass_last_set_time,
477                                                            channel);
478 }
479
480 /************************************************************************
481  Routine to get account password to trusted domain
482 ************************************************************************/
483
484 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
485                                            DOM_SID *sid, time_t *pass_last_set_time)
486 {
487         struct TRUSTED_DOM_PASS pass;
488         enum ndr_err_code ndr_err;
489
490         /* unpacking structures */
491         DATA_BLOB blob;
492
493         /* fetching trusted domain password structure */
494         if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
495                                                    &blob.length))) {
496                 DEBUG(5, ("secrets_fetch failed!\n"));
497                 return False;
498         }
499
500         /* unpack trusted domain password */
501         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass,
502                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
503         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
504                 return false;
505         }
506
507         SAFE_FREE(blob.data);
508
509         /* the trust's password */
510         if (pwd) {
511                 *pwd = SMB_STRDUP(pass.pass);
512                 if (!*pwd) {
513                         return False;
514                 }
515         }
516
517         /* last change time */
518         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
519
520         /* domain sid */
521         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
522
523         return True;
524 }
525
526 /**
527  * Routine to store the password for trusted domain
528  *
529  * @param domain remote domain name
530  * @param pwd plain text password of trust relationship
531  * @param sid remote domain sid
532  *
533  * @return true if succeeded
534  **/
535
536 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
537                                            const DOM_SID *sid)
538 {
539         bool ret;
540
541         /* packing structures */
542         DATA_BLOB blob;
543         enum ndr_err_code ndr_err;
544         struct TRUSTED_DOM_PASS pass;
545         ZERO_STRUCT(pass);
546
547         pass.uni_name = domain;
548         pass.uni_name_len = strlen(domain)+1;
549
550         /* last change time */
551         pass.mod_time = time(NULL);
552
553         /* password of the trust */
554         pass.pass_len = strlen(pwd);
555         pass.pass = pwd;
556
557         /* domain sid */
558         sid_copy(&pass.domain_sid, sid);
559
560         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &pass,
561                         (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
562         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
563                 return false;
564         }
565
566         ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
567
568         data_blob_free(&blob);
569
570         return ret;
571 }
572
573 /************************************************************************
574  Routine to delete the plaintext machine account password
575 ************************************************************************/
576
577 bool secrets_delete_machine_password(const char *domain)
578 {
579         return secrets_delete(machine_password_keystr(domain));
580 }
581
582 /************************************************************************
583  Routine to delete the plaintext machine account password, sec channel type and
584  last change time from secrets database
585 ************************************************************************/
586
587 bool secrets_delete_machine_password_ex(const char *domain)
588 {
589         if (!secrets_delete(machine_password_keystr(domain))) {
590                 return false;
591         }
592         if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
593                 return false;
594         }
595         return secrets_delete(machine_last_change_time_keystr(domain));
596 }
597
598 /************************************************************************
599  Routine to delete the domain sid
600 ************************************************************************/
601
602 bool secrets_delete_domain_sid(const char *domain)
603 {
604         return secrets_delete(domain_sid_keystr(domain));
605 }
606
607 /************************************************************************
608  Routine to set the plaintext machine account password for a realm
609 the password is assumed to be a null terminated ascii string
610 ************************************************************************/
611
612 bool secrets_store_machine_password(const char *pass, const char *domain,
613                                     enum netr_SchannelType sec_channel)
614 {
615         bool ret;
616         uint32 last_change_time;
617         uint32 sec_channel_type;
618
619         ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
620         if (!ret)
621                 return ret;
622
623         SIVAL(&last_change_time, 0, time(NULL));
624         ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
625
626         SIVAL(&sec_channel_type, 0, sec_channel);
627         ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
628
629         return ret;
630 }
631
632 /************************************************************************
633  Routine to fetch the plaintext machine account password for a realm
634  the password is assumed to be a null terminated ascii string.
635 ************************************************************************/
636
637 char *secrets_fetch_machine_password(const char *domain,
638                                      time_t *pass_last_set_time,
639                                      enum netr_SchannelType *channel)
640 {
641         char *ret;
642         ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
643
644         if (pass_last_set_time) {
645                 size_t size;
646                 uint32 *last_set_time;
647                 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
648                 if (last_set_time) {
649                         *pass_last_set_time = IVAL(last_set_time,0);
650                         SAFE_FREE(last_set_time);
651                 } else {
652                         *pass_last_set_time = 0;
653                 }
654         }
655
656         if (channel) {
657                 size_t size;
658                 uint32 *channel_type;
659                 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
660                 if (channel_type) {
661                         *channel = IVAL(channel_type,0);
662                         SAFE_FREE(channel_type);
663                 } else {
664                         *channel = get_default_sec_channel();
665                 }
666         }
667
668         return ret;
669 }
670
671 /************************************************************************
672  Routine to delete the password for trusted domain
673 ************************************************************************/
674
675 bool trusted_domain_password_delete(const char *domain)
676 {
677         return secrets_delete(trustdom_keystr(domain));
678 }
679
680 bool secrets_store_ldap_pw(const char* dn, char* pw)
681 {
682         char *key = NULL;
683         bool ret;
684
685         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
686                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
687                 return False;
688         }
689
690         ret = secrets_store(key, pw, strlen(pw)+1);
691
692         SAFE_FREE(key);
693         return ret;
694 }
695
696 /*******************************************************************
697  Find the ldap password.
698 ******************************************************************/
699
700 bool fetch_ldap_pw(char **dn, char** pw)
701 {
702         char *key = NULL;
703         size_t size = 0;
704
705         *dn = smb_xstrdup(lp_ldap_admin_dn());
706
707         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
708                 SAFE_FREE(*dn);
709                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
710                 return false;
711         }
712
713         *pw=(char *)secrets_fetch(key, &size);
714         SAFE_FREE(key);
715
716         if (!size) {
717                 /* Upgrade 2.2 style entry */
718                 char *p;
719                 char* old_style_key = SMB_STRDUP(*dn);
720                 char *data;
721                 fstring old_style_pw;
722
723                 if (!old_style_key) {
724                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
725                         return False;
726                 }
727
728                 for (p=old_style_key; *p; p++)
729                         if (*p == ',') *p = '/';
730
731                 data=(char *)secrets_fetch(old_style_key, &size);
732                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
733                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
734                         SAFE_FREE(old_style_key);
735                         SAFE_FREE(*dn);
736                         SAFE_FREE(data);
737                         return False;
738                 }
739
740                 size = MIN(size, sizeof(fstring)-1);
741                 strncpy(old_style_pw, data, size);
742                 old_style_pw[size] = 0;
743
744                 SAFE_FREE(data);
745
746                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
747                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
748                         SAFE_FREE(old_style_key);
749                         SAFE_FREE(*dn);
750                         return False;
751                 }
752                 if (!secrets_delete(old_style_key)) {
753                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
754                 }
755
756                 SAFE_FREE(old_style_key);
757
758                 *pw = smb_xstrdup(old_style_pw);
759         }
760
761         return True;
762 }
763
764 /**
765  * Get trusted domains info from secrets.tdb.
766  **/
767
768 struct list_trusted_domains_state {
769         uint32 num_domains;
770         struct trustdom_info **domains;
771 };
772
773 static int list_trusted_domain(struct db_record *rec, void *private_data)
774 {
775         const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
776         struct TRUSTED_DOM_PASS pass;
777         enum ndr_err_code ndr_err;
778         DATA_BLOB blob;
779         struct trustdom_info *dom_info;
780
781         struct list_trusted_domains_state *state =
782                 (struct list_trusted_domains_state *)private_data;
783
784         if ((rec->key.dsize < prefix_len)
785             || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
786                         prefix_len) != 0)) {
787                 return 0;
788         }
789
790         blob = data_blob_const(rec->value.dptr, rec->value.dsize);
791
792         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass,
793                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
794         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
795                 return false;
796         }
797
798         if (pass.domain_sid.num_auths != 4) {
799                 DEBUG(0, ("SID %s is not a domain sid, has %d "
800                           "auths instead of 4\n",
801                           sid_string_dbg(&pass.domain_sid),
802                           pass.domain_sid.num_auths));
803                 return 0;
804         }
805
806         if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
807                 DEBUG(0, ("talloc failed\n"));
808                 return 0;
809         }
810
811         dom_info->name = talloc_strdup(dom_info, pass.uni_name);
812         if (!dom_info->name) {
813                 TALLOC_FREE(dom_info);
814                 return 0;
815         }
816
817         sid_copy(&dom_info->sid, &pass.domain_sid);
818
819         ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
820                      &state->domains, &state->num_domains);
821
822         if (state->domains == NULL) {
823                 state->num_domains = 0;
824                 return -1;
825         }
826         return 0;
827 }
828
829 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
830                                  struct trustdom_info ***domains)
831 {
832         struct list_trusted_domains_state state;
833
834         secrets_init();
835
836         if (db_ctx == NULL) {
837                 return NT_STATUS_ACCESS_DENIED;
838         }
839
840         state.num_domains = 0;
841
842         /*
843          * Make sure that a talloc context for the trustdom_info structs
844          * exists
845          */
846
847         if (!(state.domains = TALLOC_ARRAY(
848                       mem_ctx, struct trustdom_info *, 1))) {
849                 return NT_STATUS_NO_MEMORY;
850         }
851
852         db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
853
854         *num_domains = state.num_domains;
855         *domains = state.domains;
856         return NT_STATUS_OK;
857 }
858
859 /*******************************************************************************
860  Store a complete AFS keyfile into secrets.tdb.
861 *******************************************************************************/
862
863 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
864 {
865         fstring key;
866
867         if ((cell == NULL) || (keyfile == NULL))
868                 return False;
869
870         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
871                 return False;
872
873         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
874         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
875 }
876
877 /*******************************************************************************
878  Fetch the current (highest) AFS key from secrets.tdb
879 *******************************************************************************/
880 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
881 {
882         fstring key;
883         struct afs_keyfile *keyfile;
884         size_t size = 0;
885         uint32 i;
886
887         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
888
889         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
890
891         if (keyfile == NULL)
892                 return False;
893
894         if (size != sizeof(struct afs_keyfile)) {
895                 SAFE_FREE(keyfile);
896                 return False;
897         }
898
899         i = ntohl(keyfile->nkeys);
900
901         if (i > SECRETS_AFS_MAXKEYS) {
902                 SAFE_FREE(keyfile);
903                 return False;
904         }
905
906         *result = keyfile->entry[i-1];
907
908         result->kvno = ntohl(result->kvno);
909
910         SAFE_FREE(keyfile);
911
912         return True;
913 }
914
915 /******************************************************************************
916   When kerberos is not available, choose between anonymous or
917   authenticated connections.
918
919   We need to use an authenticated connection if DCs have the
920   RestrictAnonymous registry entry set > 0, or the "Additional
921   restrictions for anonymous connections" set in the win2k Local
922   Security Policy.
923
924   Caller to free() result in domain, username, password
925 *******************************************************************************/
926 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
927 {
928         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
929         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
930         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
931
932         if (*username && **username) {
933
934                 if (!*domain || !**domain)
935                         *domain = smb_xstrdup(lp_workgroup());
936
937                 if (!*password || !**password)
938                         *password = smb_xstrdup("");
939
940                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
941                           *domain, *username));
942
943         } else {
944                 DEBUG(3, ("IPC$ connections done anonymously\n"));
945                 *username = smb_xstrdup("");
946                 *domain = smb_xstrdup("");
947                 *password = smb_xstrdup("");
948         }
949 }
950
951 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
952 {
953         char *tdbkey = NULL;
954         bool ret;
955
956         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
957                 DEBUG(0, ("asprintf failed!\n"));
958                 return False;
959         }
960
961         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
962
963         SAFE_FREE(tdbkey);
964         return ret;
965 }
966
967 bool secrets_delete_generic(const char *owner, const char *key)
968 {
969         char *tdbkey = NULL;
970         bool ret;
971
972         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
973                 DEBUG(0, ("asprintf failed!\n"));
974                 return False;
975         }
976
977         ret = secrets_delete(tdbkey);
978
979         SAFE_FREE(tdbkey);
980         return ret;
981 }
982
983 /*******************************************************************
984  Find the ldap password.
985 ******************************************************************/
986
987 char *secrets_fetch_generic(const char *owner, const char *key)
988 {
989         char *secret = NULL;
990         char *tdbkey = NULL;
991
992         if (( ! owner) || ( ! key)) {
993                 DEBUG(1, ("Invalid Paramters"));
994                 return NULL;
995         }
996
997         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
998                 DEBUG(0, ("Out of memory!\n"));
999                 return NULL;
1000         }
1001
1002         secret = (char *)secrets_fetch(tdbkey, NULL);
1003         SAFE_FREE(tdbkey);
1004
1005         return secret;
1006 }
1007