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
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.
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.
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/>.
22 /* the Samba secrets database stores any generated, private information
23 such as the local SID and machine trust password */
28 #define DBGC_CLASS DBGC_PASSDB
30 static struct db_context
*db_ctx
;
32 /* Urrrg. global.... */
33 bool global_machine_password_needs_changing
;
36 * Use a TDB to store an incrementing random seed.
38 * Initialised to the current pid, the very first time Samba starts,
39 * and incremented by one each time it is needed.
41 * @note Not called by systems with a working /dev/urandom.
43 static void get_rand_seed(int *new_seed
)
45 *new_seed
= sys_getpid();
47 dbwrap_change_int32_atomic(db_ctx
, "INFO/random_seed",
52 /* open up the secrets database */
53 bool secrets_init(void)
61 fname
= talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
67 db_ctx
= db_open(NULL
, fname
, 0,
68 TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
71 DEBUG(0,("Failed to open %s\n", fname
));
79 * Set a reseed function for the crypto random generator
81 * This avoids a problem where systems without /dev/urandom
82 * could send the same challenge to multiple clients
84 set_rand_reseed_callback(get_rand_seed
);
86 /* Ensure that the reseed is done now, while we are root, etc */
87 generate_random_buffer(&dummy
, sizeof(dummy
));
92 struct db_context
*secrets_db_ctx(void)
94 if (!secrets_init()) {
104 void secrets_shutdown(void)
109 /* read a entry from the secrets database - the caller must free the result
110 if size is non-null then the size of the entry is put in there
112 void *secrets_fetch(const char *key
, size_t *size
)
117 if (!secrets_init()) {
121 if (db_ctx
->fetch(db_ctx
, talloc_tos(), string_tdb_data(key
),
126 result
= memdup(dbuf
.dptr
, dbuf
.dsize
);
127 if (result
== NULL
) {
130 TALLOC_FREE(dbuf
.dptr
);
139 /* store a secrets entry
141 bool secrets_store(const char *key
, const void *data
, size_t size
)
145 if (!secrets_init()) {
149 status
= dbwrap_trans_store(db_ctx
, string_tdb_data(key
),
150 make_tdb_data((const uint8
*)data
, size
),
152 return NT_STATUS_IS_OK(status
);
156 /* delete a secets database entry
158 bool secrets_delete(const char *key
)
161 if (!secrets_init()) {
165 status
= dbwrap_trans_delete(db_ctx
, string_tdb_data(key
));
167 return NT_STATUS_IS_OK(status
);
171 * Form a key for fetching the domain sid
173 * @param domain domain name
177 static const char *domain_sid_keystr(const char *domain
)
181 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
182 SECRETS_DOMAIN_SID
, domain
);
183 SMB_ASSERT(keystr
!= NULL
);
187 bool secrets_store_domain_sid(const char *domain
, const DOM_SID
*sid
)
191 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(DOM_SID
));
193 /* Force a re-query, in case we modified our domain */
195 reset_global_sam_sid();
199 bool secrets_fetch_domain_sid(const char *domain
, DOM_SID
*sid
)
204 dyn_sid
= (DOM_SID
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
209 if (size
!= sizeof(DOM_SID
)) {
219 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
223 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
225 return secrets_store(key
, guid
, sizeof(struct GUID
));
228 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
230 struct GUID
*dyn_guid
;
233 struct GUID new_guid
;
235 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
237 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
240 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
241 smb_uuid_generate_random(&new_guid
);
242 if (!secrets_store_domain_guid(domain
, &new_guid
))
244 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
246 if (dyn_guid
== NULL
) {
251 if (size
!= sizeof(struct GUID
)) {
252 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
262 bool secrets_store_local_schannel_key(uint8_t schannel_key
[16])
264 return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY
, schannel_key
, 16);
267 bool secrets_fetch_local_schannel_key(uint8_t schannel_key
[16])
272 key
= (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY
, &size
);
282 memcpy(schannel_key
, key
, 16);
288 * Form a key for fetching the machine trust account sec channel type
290 * @param domain domain name
294 static const char *machine_sec_channel_type_keystr(const char *domain
)
298 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
299 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
301 SMB_ASSERT(keystr
!= NULL
);
306 * Form a key for fetching the machine trust account last change time
308 * @param domain domain name
312 static const char *machine_last_change_time_keystr(const char *domain
)
316 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
317 SECRETS_MACHINE_LAST_CHANGE_TIME
,
319 SMB_ASSERT(keystr
!= NULL
);
325 * Form a key for fetching the machine trust account password
327 * @param domain domain name
331 static const char *machine_password_keystr(const char *domain
)
335 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
336 SECRETS_MACHINE_PASSWORD
, domain
);
337 SMB_ASSERT(keystr
!= NULL
);
342 * Form a key for fetching the machine trust account password
344 * @param domain domain name
346 * @return stored password's key
348 static const char *trust_keystr(const char *domain
)
352 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
353 SECRETS_MACHINE_ACCT_PASS
, domain
);
354 SMB_ASSERT(keystr
!= NULL
);
359 * Form a key for fetching a trusted domain password
361 * @param domain trusted domain name
363 * @return stored password's key
365 static char *trustdom_keystr(const char *domain
)
369 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
370 SECRETS_DOMTRUST_ACCT_PASS
,
372 SMB_ASSERT(keystr
!= NULL
);
376 /************************************************************************
377 Lock the trust password entry.
378 ************************************************************************/
380 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
382 if (!secrets_init()) {
386 return db_ctx
->fetch_locked(
387 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
390 /************************************************************************
391 Routine to get the default secure channel type for trust accounts
392 ************************************************************************/
394 uint32
get_default_sec_channel(void)
396 if (lp_server_role() == ROLE_DOMAIN_BDC
||
397 lp_server_role() == ROLE_DOMAIN_PDC
) {
400 return SEC_CHAN_WKSTA
;
404 /************************************************************************
405 Routine to get the trust account password for a domain.
406 This only tries to get the legacy hashed version of the password.
407 The user of this function must have locked the trust password file using
408 the above secrets_lock_trust_account_password().
409 ************************************************************************/
411 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
413 time_t *pass_last_set_time
,
416 struct machine_acct_pass
*pass
;
419 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
420 trust_keystr(domain
), &size
))) {
421 DEBUG(5, ("secrets_fetch failed!\n"));
425 if (size
!= sizeof(*pass
)) {
426 DEBUG(0, ("secrets were of incorrect size!\n"));
431 if (pass_last_set_time
) {
432 *pass_last_set_time
= pass
->mod_time
;
434 memcpy(ret_pwd
, pass
->hash
, 16);
437 *channel
= get_default_sec_channel();
440 /* Test if machine password has expired and needs to be changed */
441 if (lp_machine_password_timeout()) {
442 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
443 (time_t)lp_machine_password_timeout())) {
444 global_machine_password_needs_changing
= True
;
452 /************************************************************************
453 Routine to get the trust account password for a domain.
454 The user of this function must have locked the trust password file using
455 the above secrets_lock_trust_account_password().
456 ************************************************************************/
458 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
459 time_t *pass_last_set_time
,
464 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
467 DEBUG(4,("Using cleartext machine password\n"));
468 E_md4hash(plaintext
, ret_pwd
);
469 SAFE_FREE(plaintext
);
473 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
479 * Pack SID passed by pointer
481 * @param pack_buf pointer to buffer which is to be filled with packed data
482 * @param bufsize size of packing buffer
483 * @param sid pointer to sid to be packed
485 * @return length of the packed representation of the whole structure
487 static size_t tdb_sid_pack(uint8
*pack_buf
, int bufsize
, DOM_SID
* sid
)
492 int remaining_space
= pack_buf
? bufsize
: 0;
498 len
+= tdb_pack(p
, remaining_space
, "bb", sid
->sid_rev_num
,
502 remaining_space
= bufsize
- len
;
505 for (idx
= 0; idx
< 6; idx
++) {
506 len
+= tdb_pack(p
, remaining_space
, "b",
510 remaining_space
= bufsize
- len
;
514 for (idx
= 0; idx
< MAXSUBAUTHS
; idx
++) {
515 len
+= tdb_pack(p
, remaining_space
, "d",
516 sid
->sub_auths
[idx
]);
519 remaining_space
= bufsize
- len
;
527 * Unpack SID into a pointer
529 * @param pack_buf pointer to buffer with packed representation
530 * @param bufsize size of the buffer
531 * @param sid pointer to sid structure to be filled with unpacked data
533 * @return size of structure unpacked from buffer
535 static size_t tdb_sid_unpack(uint8
*pack_buf
, int bufsize
, DOM_SID
* sid
)
539 if (!sid
|| !pack_buf
) return -1;
541 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "bb",
542 &sid
->sid_rev_num
, &sid
->num_auths
);
544 for (idx
= 0; idx
< 6; idx
++) {
545 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "b",
549 for (idx
= 0; idx
< MAXSUBAUTHS
; idx
++) {
550 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "d",
551 &sid
->sub_auths
[idx
]);
558 * Pack TRUSTED_DOM_PASS passed by pointer
560 * @param pack_buf pointer to buffer which is to be filled with packed data
561 * @param bufsize size of the buffer
562 * @param pass pointer to trusted domain password to be packed
564 * @return length of the packed representation of the whole structure
566 static size_t tdb_trusted_dom_pass_pack(uint8
*pack_buf
, int bufsize
,
567 TRUSTED_DOM_PASS
* pass
)
571 int remaining_space
= pack_buf
? bufsize
: 0;
577 /* packing unicode domain name and password */
578 len
+= tdb_pack(p
, remaining_space
, "d",
582 remaining_space
= bufsize
- len
;
585 for (idx
= 0; idx
< 32; idx
++) {
586 len
+= tdb_pack(p
, remaining_space
, "w",
587 pass
->uni_name
[idx
]);
590 remaining_space
= bufsize
- len
;
594 len
+= tdb_pack(p
, remaining_space
, "dPd", pass
->pass_len
,
595 pass
->pass
, pass
->mod_time
);
598 remaining_space
= bufsize
- len
;
601 /* packing SID structure */
602 len
+= tdb_sid_pack(p
, remaining_space
, &pass
->domain_sid
);
605 remaining_space
= bufsize
- len
;
613 * Unpack TRUSTED_DOM_PASS passed by pointer
615 * @param pack_buf pointer to buffer with packed representation
616 * @param bufsize size of the buffer
617 * @param pass pointer to trusted domain password to be filled with unpacked data
619 * @return size of structure unpacked from buffer
621 static size_t tdb_trusted_dom_pass_unpack(uint8
*pack_buf
, int bufsize
,
622 TRUSTED_DOM_PASS
* pass
)
627 if (!pack_buf
|| !pass
) return -1;
629 /* unpack unicode domain name and plaintext password */
630 len
+= tdb_unpack(pack_buf
, bufsize
- len
, "d", &pass
->uni_name_len
);
632 for (idx
= 0; idx
< 32; idx
++)
633 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "w",
634 &pass
->uni_name
[idx
]);
636 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "dPd",
637 &pass
->pass_len
, &passp
, &pass
->mod_time
);
639 fstrcpy(pass
->pass
, passp
);
643 /* unpack domain sid */
644 len
+= tdb_sid_unpack(pack_buf
+ len
, bufsize
- len
,
650 /************************************************************************
651 Routine to get account password to trusted domain
652 ************************************************************************/
654 bool secrets_fetch_trusted_domain_password(const char *domain
, char** pwd
,
655 DOM_SID
*sid
, time_t *pass_last_set_time
)
657 struct trusted_dom_pass pass
;
660 /* unpacking structures */
666 /* fetching trusted domain password structure */
667 if (!(pass_buf
= (uint8
*)secrets_fetch(trustdom_keystr(domain
),
669 DEBUG(5, ("secrets_fetch failed!\n"));
673 /* unpack trusted domain password */
674 pass_len
= tdb_trusted_dom_pass_unpack(pass_buf
, size
, &pass
);
677 if (pass_len
!= size
) {
678 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
682 /* the trust's password */
684 *pwd
= SMB_STRDUP(pass
.pass
);
690 /* last change time */
691 if (pass_last_set_time
) *pass_last_set_time
= pass
.mod_time
;
694 if (sid
!= NULL
) sid_copy(sid
, &pass
.domain_sid
);
700 * Routine to store the password for trusted domain
702 * @param domain remote domain name
703 * @param pwd plain text password of trust relationship
704 * @param sid remote domain sid
706 * @return true if succeeded
709 bool secrets_store_trusted_domain_password(const char* domain
, const char* pwd
,
712 smb_ucs2_t
*uni_dom_name
;
714 size_t converted_size
;
716 /* packing structures */
717 uint8
*pass_buf
= NULL
;
720 struct trusted_dom_pass pass
;
723 if (!push_ucs2_allocate(&uni_dom_name
, domain
, &converted_size
)) {
724 DEBUG(0, ("Could not convert domain name %s to unicode\n",
729 strncpy_w(pass
.uni_name
, uni_dom_name
, sizeof(pass
.uni_name
) - 1);
730 pass
.uni_name_len
= strlen_w(uni_dom_name
)+1;
731 SAFE_FREE(uni_dom_name
);
733 /* last change time */
734 pass
.mod_time
= time(NULL
);
736 /* password of the trust */
737 pass
.pass_len
= strlen(pwd
);
738 fstrcpy(pass
.pass
, pwd
);
741 sid_copy(&pass
.domain_sid
, sid
);
743 /* Calculate the length. */
744 pass_len
= tdb_trusted_dom_pass_pack(NULL
, 0, &pass
);
745 pass_buf
= SMB_MALLOC_ARRAY(uint8
, pass_len
);
749 pass_len
= tdb_trusted_dom_pass_pack(pass_buf
, pass_len
, &pass
);
750 ret
= secrets_store(trustdom_keystr(domain
), (void *)pass_buf
,
756 /************************************************************************
757 Routine to delete the plaintext machine account password
758 ************************************************************************/
760 bool secrets_delete_machine_password(const char *domain
)
762 return secrets_delete(machine_password_keystr(domain
));
765 /************************************************************************
766 Routine to delete the plaintext machine account password, sec channel type and
767 last change time from secrets database
768 ************************************************************************/
770 bool secrets_delete_machine_password_ex(const char *domain
)
772 if (!secrets_delete(machine_password_keystr(domain
))) {
775 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
778 return secrets_delete(machine_last_change_time_keystr(domain
));
781 /************************************************************************
782 Routine to delete the domain sid
783 ************************************************************************/
785 bool secrets_delete_domain_sid(const char *domain
)
787 return secrets_delete(domain_sid_keystr(domain
));
790 /************************************************************************
791 Routine to set the plaintext machine account password for a realm
792 the password is assumed to be a null terminated ascii string
793 ************************************************************************/
795 bool secrets_store_machine_password(const char *pass
, const char *domain
, uint32 sec_channel
)
798 uint32 last_change_time
;
799 uint32 sec_channel_type
;
801 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
805 SIVAL(&last_change_time
, 0, time(NULL
));
806 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
808 SIVAL(&sec_channel_type
, 0, sec_channel
);
809 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
814 /************************************************************************
815 Routine to fetch the plaintext machine account password for a realm
816 the password is assumed to be a null terminated ascii string.
817 ************************************************************************/
819 char *secrets_fetch_machine_password(const char *domain
,
820 time_t *pass_last_set_time
,
824 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
826 if (pass_last_set_time
) {
828 uint32
*last_set_time
;
829 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
831 *pass_last_set_time
= IVAL(last_set_time
,0);
832 SAFE_FREE(last_set_time
);
834 *pass_last_set_time
= 0;
840 uint32
*channel_type
;
841 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
843 *channel
= IVAL(channel_type
,0);
844 SAFE_FREE(channel_type
);
846 *channel
= get_default_sec_channel();
853 /************************************************************************
854 Routine to delete the password for trusted domain
855 ************************************************************************/
857 bool trusted_domain_password_delete(const char *domain
)
859 return secrets_delete(trustdom_keystr(domain
));
862 bool secrets_store_ldap_pw(const char* dn
, char* pw
)
867 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, dn
) < 0) {
868 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
872 ret
= secrets_store(key
, pw
, strlen(pw
)+1);
878 /*******************************************************************
879 Find the ldap password.
880 ******************************************************************/
882 bool fetch_ldap_pw(char **dn
, char** pw
)
887 *dn
= smb_xstrdup(lp_ldap_admin_dn());
889 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, *dn
) < 0) {
891 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
894 *pw
=(char *)secrets_fetch(key
, &size
);
898 /* Upgrade 2.2 style entry */
900 char* old_style_key
= SMB_STRDUP(*dn
);
902 fstring old_style_pw
;
904 if (!old_style_key
) {
905 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
909 for (p
=old_style_key
; *p
; p
++)
910 if (*p
== ',') *p
= '/';
912 data
=(char *)secrets_fetch(old_style_key
, &size
);
913 if ((data
== NULL
) || (size
< sizeof(old_style_pw
))) {
914 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
915 SAFE_FREE(old_style_key
);
921 size
= MIN(size
, sizeof(fstring
)-1);
922 strncpy(old_style_pw
, data
, size
);
923 old_style_pw
[size
] = 0;
927 if (!secrets_store_ldap_pw(*dn
, old_style_pw
)) {
928 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
929 SAFE_FREE(old_style_key
);
933 if (!secrets_delete(old_style_key
)) {
934 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
937 SAFE_FREE(old_style_key
);
939 *pw
= smb_xstrdup(old_style_pw
);
946 * Get trusted domains info from secrets.tdb.
949 struct list_trusted_domains_state
{
951 struct trustdom_info
**domains
;
954 static int list_trusted_domain(struct db_record
*rec
, void *private_data
)
956 const size_t prefix_len
= strlen(SECRETS_DOMTRUST_ACCT_PASS
);
957 size_t converted_size
, packed_size
= 0;
958 struct trusted_dom_pass pass
;
959 struct trustdom_info
*dom_info
;
961 struct list_trusted_domains_state
*state
=
962 (struct list_trusted_domains_state
*)private_data
;
964 if ((rec
->key
.dsize
< prefix_len
)
965 || (strncmp((char *)rec
->key
.dptr
, SECRETS_DOMTRUST_ACCT_PASS
,
970 packed_size
= tdb_trusted_dom_pass_unpack(
971 rec
->value
.dptr
, rec
->value
.dsize
, &pass
);
973 if (rec
->value
.dsize
!= packed_size
) {
974 DEBUG(2, ("Secrets record is invalid!\n"));
978 if (pass
.domain_sid
.num_auths
!= 4) {
979 DEBUG(0, ("SID %s is not a domain sid, has %d "
980 "auths instead of 4\n",
981 sid_string_dbg(&pass
.domain_sid
),
982 pass
.domain_sid
.num_auths
));
986 if (!(dom_info
= TALLOC_P(state
->domains
, struct trustdom_info
))) {
987 DEBUG(0, ("talloc failed\n"));
991 if (!pull_ucs2_talloc(dom_info
, &dom_info
->name
, pass
.uni_name
,
993 DEBUG(2, ("pull_ucs2_talloc failed\n"));
994 TALLOC_FREE(dom_info
);
998 sid_copy(&dom_info
->sid
, &pass
.domain_sid
);
1000 ADD_TO_ARRAY(state
->domains
, struct trustdom_info
*, dom_info
,
1001 &state
->domains
, &state
->num_domains
);
1003 if (state
->domains
== NULL
) {
1004 state
->num_domains
= 0;
1010 NTSTATUS
secrets_trusted_domains(TALLOC_CTX
*mem_ctx
, uint32
*num_domains
,
1011 struct trustdom_info
***domains
)
1013 struct list_trusted_domains_state state
;
1017 if (db_ctx
== NULL
) {
1018 return NT_STATUS_ACCESS_DENIED
;
1021 state
.num_domains
= 0;
1024 * Make sure that a talloc context for the trustdom_info structs
1028 if (!(state
.domains
= TALLOC_ARRAY(
1029 mem_ctx
, struct trustdom_info
*, 1))) {
1030 return NT_STATUS_NO_MEMORY
;
1033 db_ctx
->traverse_read(db_ctx
, list_trusted_domain
, (void *)&state
);
1035 *num_domains
= state
.num_domains
;
1036 *domains
= state
.domains
;
1037 return NT_STATUS_OK
;
1040 /*******************************************************************************
1041 Store a complete AFS keyfile into secrets.tdb.
1042 *******************************************************************************/
1044 bool secrets_store_afs_keyfile(const char *cell
, const struct afs_keyfile
*keyfile
)
1048 if ((cell
== NULL
) || (keyfile
== NULL
))
1051 if (ntohl(keyfile
->nkeys
) > SECRETS_AFS_MAXKEYS
)
1054 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
1055 return secrets_store(key
, keyfile
, sizeof(struct afs_keyfile
));
1058 /*******************************************************************************
1059 Fetch the current (highest) AFS key from secrets.tdb
1060 *******************************************************************************/
1061 bool secrets_fetch_afs_key(const char *cell
, struct afs_key
*result
)
1064 struct afs_keyfile
*keyfile
;
1068 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
1070 keyfile
= (struct afs_keyfile
*)secrets_fetch(key
, &size
);
1072 if (keyfile
== NULL
)
1075 if (size
!= sizeof(struct afs_keyfile
)) {
1080 i
= ntohl(keyfile
->nkeys
);
1082 if (i
> SECRETS_AFS_MAXKEYS
) {
1087 *result
= keyfile
->entry
[i
-1];
1089 result
->kvno
= ntohl(result
->kvno
);
1096 /******************************************************************************
1097 When kerberos is not available, choose between anonymous or
1098 authenticated connections.
1100 We need to use an authenticated connection if DCs have the
1101 RestrictAnonymous registry entry set > 0, or the "Additional
1102 restrictions for anonymous connections" set in the win2k Local
1105 Caller to free() result in domain, username, password
1106 *******************************************************************************/
1107 void secrets_fetch_ipc_userpass(char **username
, char **domain
, char **password
)
1109 *username
= (char *)secrets_fetch(SECRETS_AUTH_USER
, NULL
);
1110 *domain
= (char *)secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
1111 *password
= (char *)secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
1113 if (*username
&& **username
) {
1115 if (!*domain
|| !**domain
)
1116 *domain
= smb_xstrdup(lp_workgroup());
1118 if (!*password
|| !**password
)
1119 *password
= smb_xstrdup("");
1121 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1122 *domain
, *username
));
1125 DEBUG(3, ("IPC$ connections done anonymously\n"));
1126 *username
= smb_xstrdup("");
1127 *domain
= smb_xstrdup("");
1128 *password
= smb_xstrdup("");
1132 /******************************************************************************
1133 Open or create the schannel session store tdb.
1134 *******************************************************************************/
1136 static TDB_CONTEXT
*open_schannel_session_store(TALLOC_CTX
*mem_ctx
)
1140 TDB_CONTEXT
*tdb_sc
= NULL
;
1141 char *fname
= talloc_asprintf(mem_ctx
, "%s/schannel_store.tdb", lp_private_dir());
1147 tdb_sc
= tdb_open_log(fname
, 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
1150 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname
));
1155 vers
= tdb_fetch_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION");
1156 if (vers
.dptr
== NULL
) {
1157 /* First opener, no version. */
1159 vers
.dptr
= (uint8
*)&ver
;
1161 tdb_store_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION", vers
, TDB_REPLACE
);
1163 } else if (vers
.dsize
== 4) {
1164 ver
= IVAL(vers
.dptr
,0);
1168 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1174 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1175 (int)vers
.dsize
, fname
));
1178 SAFE_FREE(vers
.dptr
);
1184 /******************************************************************************
1185 Store the schannel state after an AUTH2 call.
1186 Note we must be root here.
1187 *******************************************************************************/
1189 bool secrets_store_schannel_session_info(TALLOC_CTX
*mem_ctx
,
1190 const char *remote_machine
,
1191 const struct dcinfo
*pdc
)
1193 TDB_CONTEXT
*tdb_sc
= NULL
;
1196 char *keystr
= talloc_asprintf_strupper_m(mem_ctx
, "%s/%s",
1197 SECRETS_SCHANNEL_STATE
,
1203 /* Work out how large the record is. */
1204 value
.dsize
= tdb_pack(NULL
, 0, "dBBBBBfff",
1206 8, pdc
->seed_chal
.data
,
1207 8, pdc
->clnt_chal
.data
,
1208 8, pdc
->srv_chal
.data
,
1212 pdc
->remote_machine
,
1215 value
.dptr
= TALLOC_ARRAY(mem_ctx
, uint8
, value
.dsize
);
1217 TALLOC_FREE(keystr
);
1221 value
.dsize
= tdb_pack(value
.dptr
, value
.dsize
, "dBBBBBfff",
1223 8, pdc
->seed_chal
.data
,
1224 8, pdc
->clnt_chal
.data
,
1225 8, pdc
->srv_chal
.data
,
1229 pdc
->remote_machine
,
1232 tdb_sc
= open_schannel_session_store(mem_ctx
);
1234 TALLOC_FREE(keystr
);
1235 TALLOC_FREE(value
.dptr
);
1239 ret
= (tdb_store_bystring(tdb_sc
, keystr
, value
, TDB_REPLACE
) == 0 ? True
: False
);
1241 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1245 TALLOC_FREE(keystr
);
1246 TALLOC_FREE(value
.dptr
);
1250 /******************************************************************************
1251 Restore the schannel state on a client reconnect.
1252 Note we must be root here.
1253 *******************************************************************************/
1255 bool secrets_restore_schannel_session_info(TALLOC_CTX
*mem_ctx
,
1256 const char *remote_machine
,
1257 struct dcinfo
**ppdc
)
1259 TDB_CONTEXT
*tdb_sc
= NULL
;
1261 unsigned char *pseed_chal
= NULL
;
1262 unsigned char *pclnt_chal
= NULL
;
1263 unsigned char *psrv_chal
= NULL
;
1264 unsigned char *psess_key
= NULL
;
1265 unsigned char *pmach_pw
= NULL
;
1266 uint32 l1
, l2
, l3
, l4
, l5
;
1268 struct dcinfo
*pdc
= NULL
;
1269 char *keystr
= talloc_asprintf_strupper_m(mem_ctx
, "%s/%s",
1270 SECRETS_SCHANNEL_STATE
,
1279 tdb_sc
= open_schannel_session_store(mem_ctx
);
1281 TALLOC_FREE(keystr
);
1285 value
= tdb_fetch_bystring(tdb_sc
, keystr
);
1287 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1293 pdc
= TALLOC_ZERO_P(mem_ctx
, struct dcinfo
);
1295 /* Retrieve the record. */
1296 ret
= tdb_unpack(value
.dptr
, value
.dsize
, "dBBBBBfff",
1304 &pdc
->remote_machine
,
1307 if (ret
== -1 || l1
!= 8 || l2
!= 8 || l3
!= 8 || l4
!= 16 || l5
!= 16) {
1308 /* Bad record - delete it. */
1309 tdb_delete_bystring(tdb_sc
, keystr
);
1311 TALLOC_FREE(keystr
);
1313 SAFE_FREE(pseed_chal
);
1314 SAFE_FREE(pclnt_chal
);
1315 SAFE_FREE(psrv_chal
);
1316 SAFE_FREE(psess_key
);
1317 SAFE_FREE(pmach_pw
);
1318 SAFE_FREE(value
.dptr
);
1324 memcpy(pdc
->seed_chal
.data
, pseed_chal
, 8);
1325 memcpy(pdc
->clnt_chal
.data
, pclnt_chal
, 8);
1326 memcpy(pdc
->srv_chal
.data
, psrv_chal
, 8);
1327 memcpy(pdc
->sess_key
, psess_key
, 16);
1328 memcpy(pdc
->mach_pw
, pmach_pw
, 16);
1330 /* We know these are true so didn't bother to store them. */
1331 pdc
->challenge_sent
= True
;
1332 pdc
->authenticated
= True
;
1334 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1337 SAFE_FREE(pseed_chal
);
1338 SAFE_FREE(pclnt_chal
);
1339 SAFE_FREE(psrv_chal
);
1340 SAFE_FREE(psess_key
);
1341 SAFE_FREE(pmach_pw
);
1343 TALLOC_FREE(keystr
);
1344 SAFE_FREE(value
.dptr
);
1351 bool secrets_store_generic(const char *owner
, const char *key
, const char *secret
)
1353 char *tdbkey
= NULL
;
1356 if (asprintf(&tdbkey
, "SECRETS/GENERIC/%s/%s", owner
, key
) < 0) {
1357 DEBUG(0, ("asprintf failed!\n"));
1361 ret
= secrets_store(tdbkey
, secret
, strlen(secret
)+1);
1367 /*******************************************************************
1368 Find the ldap password.
1369 ******************************************************************/
1371 char *secrets_fetch_generic(const char *owner
, const char *key
)
1373 char *secret
= NULL
;
1374 char *tdbkey
= NULL
;
1376 if (( ! owner
) || ( ! key
)) {
1377 DEBUG(1, ("Invalid Paramters"));
1381 if (asprintf(&tdbkey
, "SECRETS/GENERIC/%s/%s", owner
, key
) < 0) {
1382 DEBUG(0, ("Out of memory!\n"));
1386 secret
= (char *)secrets_fetch(tdbkey
, NULL
);