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 */
26 #include "../libcli/auth/libcli_auth.h"
29 #define DBGC_CLASS DBGC_PASSDB
31 static struct db_context
*db_ctx
;
33 /* Urrrg. global.... */
34 bool global_machine_password_needs_changing
;
37 * Use a TDB to store an incrementing random seed.
39 * Initialised to the current pid, the very first time Samba starts,
40 * and incremented by one each time it is needed.
42 * @note Not called by systems with a working /dev/urandom.
44 static void get_rand_seed(void *userdata
, int *new_seed
)
46 *new_seed
= sys_getpid();
48 dbwrap_trans_change_int32_atomic(db_ctx
, "INFO/random_seed",
53 /* open up the secrets database */
54 bool secrets_init(void)
62 fname
= talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
68 db_ctx
= db_open(NULL
, fname
, 0,
69 TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
72 DEBUG(0,("Failed to open %s\n", fname
));
80 * Set a reseed function for the crypto random generator
82 * This avoids a problem where systems without /dev/urandom
83 * could send the same challenge to multiple clients
85 set_rand_reseed_callback(get_rand_seed
, NULL
);
87 /* Ensure that the reseed is done now, while we are root, etc */
88 generate_random_buffer(&dummy
, sizeof(dummy
));
93 struct db_context
*secrets_db_ctx(void)
95 if (!secrets_init()) {
105 void secrets_shutdown(void)
110 /* read a entry from the secrets database - the caller must free the result
111 if size is non-null then the size of the entry is put in there
113 void *secrets_fetch(const char *key
, size_t *size
)
118 if (!secrets_init()) {
122 if (db_ctx
->fetch(db_ctx
, talloc_tos(), string_tdb_data(key
),
127 result
= memdup(dbuf
.dptr
, dbuf
.dsize
);
128 if (result
== NULL
) {
131 TALLOC_FREE(dbuf
.dptr
);
140 /* store a secrets entry
142 bool secrets_store(const char *key
, const void *data
, size_t size
)
146 if (!secrets_init()) {
150 status
= dbwrap_trans_store(db_ctx
, string_tdb_data(key
),
151 make_tdb_data((const uint8
*)data
, size
),
153 return NT_STATUS_IS_OK(status
);
157 /* delete a secets database entry
159 bool secrets_delete(const char *key
)
162 if (!secrets_init()) {
166 status
= dbwrap_trans_delete(db_ctx
, string_tdb_data(key
));
168 return NT_STATUS_IS_OK(status
);
172 * Form a key for fetching the domain sid
174 * @param domain domain name
178 static const char *domain_sid_keystr(const char *domain
)
182 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
183 SECRETS_DOMAIN_SID
, domain
);
184 SMB_ASSERT(keystr
!= NULL
);
188 bool secrets_store_domain_sid(const char *domain
, const DOM_SID
*sid
)
192 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(DOM_SID
));
194 /* Force a re-query, in case we modified our domain */
196 reset_global_sam_sid();
200 bool secrets_fetch_domain_sid(const char *domain
, DOM_SID
*sid
)
205 dyn_sid
= (DOM_SID
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
210 if (size
!= sizeof(DOM_SID
)) {
220 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
224 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
226 return secrets_store(key
, guid
, sizeof(struct GUID
));
229 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
231 struct GUID
*dyn_guid
;
234 struct GUID new_guid
;
236 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
238 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
241 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
242 new_guid
= GUID_random();
243 if (!secrets_store_domain_guid(domain
, &new_guid
))
245 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
247 if (dyn_guid
== NULL
) {
252 if (size
!= sizeof(struct GUID
)) {
253 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
263 bool secrets_store_local_schannel_key(uint8_t schannel_key
[16])
265 return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY
, schannel_key
, 16);
268 bool secrets_fetch_local_schannel_key(uint8_t schannel_key
[16])
273 key
= (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY
, &size
);
283 memcpy(schannel_key
, key
, 16);
289 * Form a key for fetching the machine trust account sec channel type
291 * @param domain domain name
295 static const char *machine_sec_channel_type_keystr(const char *domain
)
299 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
300 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
302 SMB_ASSERT(keystr
!= NULL
);
307 * Form a key for fetching the machine trust account last change time
309 * @param domain domain name
313 static const char *machine_last_change_time_keystr(const char *domain
)
317 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
318 SECRETS_MACHINE_LAST_CHANGE_TIME
,
320 SMB_ASSERT(keystr
!= NULL
);
326 * Form a key for fetching the machine trust account password
328 * @param domain domain name
332 static const char *machine_password_keystr(const char *domain
)
336 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
337 SECRETS_MACHINE_PASSWORD
, domain
);
338 SMB_ASSERT(keystr
!= NULL
);
343 * Form a key for fetching the machine trust account password
345 * @param domain domain name
347 * @return stored password's key
349 static const char *trust_keystr(const char *domain
)
353 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
354 SECRETS_MACHINE_ACCT_PASS
, domain
);
355 SMB_ASSERT(keystr
!= NULL
);
360 * Form a key for fetching a trusted domain password
362 * @param domain trusted domain name
364 * @return stored password's key
366 static char *trustdom_keystr(const char *domain
)
370 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
371 SECRETS_DOMTRUST_ACCT_PASS
,
373 SMB_ASSERT(keystr
!= NULL
);
377 /************************************************************************
378 Lock the trust password entry.
379 ************************************************************************/
381 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
383 if (!secrets_init()) {
387 return db_ctx
->fetch_locked(
388 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
391 /************************************************************************
392 Routine to get the default secure channel type for trust accounts
393 ************************************************************************/
395 enum netr_SchannelType
get_default_sec_channel(void)
397 if (lp_server_role() == ROLE_DOMAIN_BDC
||
398 lp_server_role() == ROLE_DOMAIN_PDC
) {
401 return SEC_CHAN_WKSTA
;
405 /************************************************************************
406 Routine to get the trust account password for a domain.
407 This only tries to get the legacy hashed version of the password.
408 The user of this function must have locked the trust password file using
409 the above secrets_lock_trust_account_password().
410 ************************************************************************/
412 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
414 time_t *pass_last_set_time
,
415 enum netr_SchannelType
*channel
)
417 struct machine_acct_pass
*pass
;
420 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
421 trust_keystr(domain
), &size
))) {
422 DEBUG(5, ("secrets_fetch failed!\n"));
426 if (size
!= sizeof(*pass
)) {
427 DEBUG(0, ("secrets were of incorrect size!\n"));
432 if (pass_last_set_time
) {
433 *pass_last_set_time
= pass
->mod_time
;
435 memcpy(ret_pwd
, pass
->hash
, 16);
438 *channel
= get_default_sec_channel();
441 /* Test if machine password has expired and needs to be changed */
442 if (lp_machine_password_timeout()) {
443 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
444 (time_t)lp_machine_password_timeout())) {
445 global_machine_password_needs_changing
= True
;
453 /************************************************************************
454 Routine to get the trust account password for a domain.
455 The user of this function must have locked the trust password file using
456 the above secrets_lock_trust_account_password().
457 ************************************************************************/
459 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
460 time_t *pass_last_set_time
,
461 enum netr_SchannelType
*channel
)
465 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
468 DEBUG(4,("Using cleartext machine password\n"));
469 E_md4hash(plaintext
, ret_pwd
);
470 SAFE_FREE(plaintext
);
474 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
480 * Pack SID passed by pointer
482 * @param pack_buf pointer to buffer which is to be filled with packed data
483 * @param bufsize size of packing buffer
484 * @param sid pointer to sid to be packed
486 * @return length of the packed representation of the whole structure
488 static size_t tdb_sid_pack(uint8
*pack_buf
, int bufsize
, DOM_SID
* sid
)
493 int remaining_space
= pack_buf
? bufsize
: 0;
499 len
+= tdb_pack(p
, remaining_space
, "bb", sid
->sid_rev_num
,
503 remaining_space
= bufsize
- len
;
506 for (idx
= 0; idx
< 6; idx
++) {
507 len
+= tdb_pack(p
, remaining_space
, "b",
511 remaining_space
= bufsize
- len
;
515 for (idx
= 0; idx
< MAXSUBAUTHS
; idx
++) {
516 len
+= tdb_pack(p
, remaining_space
, "d",
517 sid
->sub_auths
[idx
]);
520 remaining_space
= bufsize
- len
;
528 * Unpack SID into a pointer
530 * @param pack_buf pointer to buffer with packed representation
531 * @param bufsize size of the buffer
532 * @param sid pointer to sid structure to be filled with unpacked data
534 * @return size of structure unpacked from buffer
536 static size_t tdb_sid_unpack(uint8
*pack_buf
, int bufsize
, DOM_SID
* sid
)
540 if (!sid
|| !pack_buf
) return -1;
542 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "bb",
543 &sid
->sid_rev_num
, &sid
->num_auths
);
545 for (idx
= 0; idx
< 6; idx
++) {
546 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "b",
550 for (idx
= 0; idx
< MAXSUBAUTHS
; idx
++) {
551 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "d",
552 &sid
->sub_auths
[idx
]);
559 * Pack TRUSTED_DOM_PASS passed by pointer
561 * @param pack_buf pointer to buffer which is to be filled with packed data
562 * @param bufsize size of the buffer
563 * @param pass pointer to trusted domain password to be packed
565 * @return length of the packed representation of the whole structure
567 static size_t tdb_trusted_dom_pass_pack(uint8
*pack_buf
, int bufsize
,
568 TRUSTED_DOM_PASS
* pass
)
572 int remaining_space
= pack_buf
? bufsize
: 0;
578 /* packing unicode domain name and password */
579 len
+= tdb_pack(p
, remaining_space
, "d",
583 remaining_space
= bufsize
- len
;
586 for (idx
= 0; idx
< 32; idx
++) {
587 len
+= tdb_pack(p
, remaining_space
, "w",
588 pass
->uni_name
[idx
]);
591 remaining_space
= bufsize
- len
;
595 len
+= tdb_pack(p
, remaining_space
, "dPd", pass
->pass_len
,
596 pass
->pass
, pass
->mod_time
);
599 remaining_space
= bufsize
- len
;
602 /* packing SID structure */
603 len
+= tdb_sid_pack(p
, remaining_space
, &pass
->domain_sid
);
606 remaining_space
= bufsize
- len
;
614 * Unpack TRUSTED_DOM_PASS passed by pointer
616 * @param pack_buf pointer to buffer with packed representation
617 * @param bufsize size of the buffer
618 * @param pass pointer to trusted domain password to be filled with unpacked data
620 * @return size of structure unpacked from buffer
622 static size_t tdb_trusted_dom_pass_unpack(uint8
*pack_buf
, int bufsize
,
623 TRUSTED_DOM_PASS
* pass
)
628 if (!pack_buf
|| !pass
) return -1;
630 /* unpack unicode domain name and plaintext password */
631 len
+= tdb_unpack(pack_buf
, bufsize
- len
, "d", &pass
->uni_name_len
);
633 for (idx
= 0; idx
< 32; idx
++)
634 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "w",
635 &pass
->uni_name
[idx
]);
637 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "dPd",
638 &pass
->pass_len
, &passp
, &pass
->mod_time
);
640 fstrcpy(pass
->pass
, passp
);
644 /* unpack domain sid */
645 len
+= tdb_sid_unpack(pack_buf
+ len
, bufsize
- len
,
651 /************************************************************************
652 Routine to get account password to trusted domain
653 ************************************************************************/
655 bool secrets_fetch_trusted_domain_password(const char *domain
, char** pwd
,
656 DOM_SID
*sid
, time_t *pass_last_set_time
)
658 struct trusted_dom_pass pass
;
661 /* unpacking structures */
667 /* fetching trusted domain password structure */
668 if (!(pass_buf
= (uint8
*)secrets_fetch(trustdom_keystr(domain
),
670 DEBUG(5, ("secrets_fetch failed!\n"));
674 /* unpack trusted domain password */
675 pass_len
= tdb_trusted_dom_pass_unpack(pass_buf
, size
, &pass
);
678 if (pass_len
!= size
) {
679 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
683 /* the trust's password */
685 *pwd
= SMB_STRDUP(pass
.pass
);
691 /* last change time */
692 if (pass_last_set_time
) *pass_last_set_time
= pass
.mod_time
;
695 if (sid
!= NULL
) sid_copy(sid
, &pass
.domain_sid
);
701 * Routine to store the password for trusted domain
703 * @param domain remote domain name
704 * @param pwd plain text password of trust relationship
705 * @param sid remote domain sid
707 * @return true if succeeded
710 bool secrets_store_trusted_domain_password(const char* domain
, const char* pwd
,
713 smb_ucs2_t
*uni_dom_name
;
715 size_t converted_size
;
717 /* packing structures */
718 uint8
*pass_buf
= NULL
;
721 struct trusted_dom_pass pass
;
724 if (!push_ucs2_talloc(talloc_tos(), &uni_dom_name
, domain
, &converted_size
)) {
725 DEBUG(0, ("Could not convert domain name %s to unicode\n",
730 strncpy_w(pass
.uni_name
, uni_dom_name
, sizeof(pass
.uni_name
) - 1);
731 pass
.uni_name_len
= strlen_w(uni_dom_name
)+1;
732 TALLOC_FREE(uni_dom_name
);
734 /* last change time */
735 pass
.mod_time
= time(NULL
);
737 /* password of the trust */
738 pass
.pass_len
= strlen(pwd
);
739 fstrcpy(pass
.pass
, pwd
);
742 sid_copy(&pass
.domain_sid
, sid
);
744 /* Calculate the length. */
745 pass_len
= tdb_trusted_dom_pass_pack(NULL
, 0, &pass
);
746 pass_buf
= talloc_array(talloc_tos(), uint8
, pass_len
);
750 pass_len
= tdb_trusted_dom_pass_pack(pass_buf
, pass_len
, &pass
);
751 ret
= secrets_store(trustdom_keystr(domain
), (void *)pass_buf
,
753 TALLOC_FREE(pass_buf
);
757 /************************************************************************
758 Routine to delete the plaintext machine account password
759 ************************************************************************/
761 bool secrets_delete_machine_password(const char *domain
)
763 return secrets_delete(machine_password_keystr(domain
));
766 /************************************************************************
767 Routine to delete the plaintext machine account password, sec channel type and
768 last change time from secrets database
769 ************************************************************************/
771 bool secrets_delete_machine_password_ex(const char *domain
)
773 if (!secrets_delete(machine_password_keystr(domain
))) {
776 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
779 return secrets_delete(machine_last_change_time_keystr(domain
));
782 /************************************************************************
783 Routine to delete the domain sid
784 ************************************************************************/
786 bool secrets_delete_domain_sid(const char *domain
)
788 return secrets_delete(domain_sid_keystr(domain
));
791 /************************************************************************
792 Routine to set the plaintext machine account password for a realm
793 the password is assumed to be a null terminated ascii string
794 ************************************************************************/
796 bool secrets_store_machine_password(const char *pass
, const char *domain
,
797 enum netr_SchannelType sec_channel
)
800 uint32 last_change_time
;
801 uint32 sec_channel_type
;
803 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
807 SIVAL(&last_change_time
, 0, time(NULL
));
808 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
810 SIVAL(&sec_channel_type
, 0, sec_channel
);
811 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
816 /************************************************************************
817 Routine to fetch the plaintext machine account password for a realm
818 the password is assumed to be a null terminated ascii string.
819 ************************************************************************/
821 char *secrets_fetch_machine_password(const char *domain
,
822 time_t *pass_last_set_time
,
823 enum netr_SchannelType
*channel
)
826 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
828 if (pass_last_set_time
) {
830 uint32
*last_set_time
;
831 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
833 *pass_last_set_time
= IVAL(last_set_time
,0);
834 SAFE_FREE(last_set_time
);
836 *pass_last_set_time
= 0;
842 uint32
*channel_type
;
843 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
845 *channel
= IVAL(channel_type
,0);
846 SAFE_FREE(channel_type
);
848 *channel
= get_default_sec_channel();
855 /************************************************************************
856 Routine to delete the password for trusted domain
857 ************************************************************************/
859 bool trusted_domain_password_delete(const char *domain
)
861 return secrets_delete(trustdom_keystr(domain
));
864 bool secrets_store_ldap_pw(const char* dn
, char* pw
)
869 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, dn
) < 0) {
870 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
874 ret
= secrets_store(key
, pw
, strlen(pw
)+1);
880 /*******************************************************************
881 Find the ldap password.
882 ******************************************************************/
884 bool fetch_ldap_pw(char **dn
, char** pw
)
889 *dn
= smb_xstrdup(lp_ldap_admin_dn());
891 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, *dn
) < 0) {
893 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
896 *pw
=(char *)secrets_fetch(key
, &size
);
900 /* Upgrade 2.2 style entry */
902 char* old_style_key
= SMB_STRDUP(*dn
);
904 fstring old_style_pw
;
906 if (!old_style_key
) {
907 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
911 for (p
=old_style_key
; *p
; p
++)
912 if (*p
== ',') *p
= '/';
914 data
=(char *)secrets_fetch(old_style_key
, &size
);
915 if ((data
== NULL
) || (size
< sizeof(old_style_pw
))) {
916 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
917 SAFE_FREE(old_style_key
);
923 size
= MIN(size
, sizeof(fstring
)-1);
924 strncpy(old_style_pw
, data
, size
);
925 old_style_pw
[size
] = 0;
929 if (!secrets_store_ldap_pw(*dn
, old_style_pw
)) {
930 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
931 SAFE_FREE(old_style_key
);
935 if (!secrets_delete(old_style_key
)) {
936 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
939 SAFE_FREE(old_style_key
);
941 *pw
= smb_xstrdup(old_style_pw
);
948 * Get trusted domains info from secrets.tdb.
951 struct list_trusted_domains_state
{
953 struct trustdom_info
**domains
;
956 static int list_trusted_domain(struct db_record
*rec
, void *private_data
)
958 const size_t prefix_len
= strlen(SECRETS_DOMTRUST_ACCT_PASS
);
959 size_t converted_size
, packed_size
= 0;
960 struct trusted_dom_pass pass
;
961 struct trustdom_info
*dom_info
;
963 struct list_trusted_domains_state
*state
=
964 (struct list_trusted_domains_state
*)private_data
;
966 if ((rec
->key
.dsize
< prefix_len
)
967 || (strncmp((char *)rec
->key
.dptr
, SECRETS_DOMTRUST_ACCT_PASS
,
972 packed_size
= tdb_trusted_dom_pass_unpack(
973 rec
->value
.dptr
, rec
->value
.dsize
, &pass
);
975 if (rec
->value
.dsize
!= packed_size
) {
976 DEBUG(2, ("Secrets record is invalid!\n"));
980 if (pass
.domain_sid
.num_auths
!= 4) {
981 DEBUG(0, ("SID %s is not a domain sid, has %d "
982 "auths instead of 4\n",
983 sid_string_dbg(&pass
.domain_sid
),
984 pass
.domain_sid
.num_auths
));
988 if (!(dom_info
= TALLOC_P(state
->domains
, struct trustdom_info
))) {
989 DEBUG(0, ("talloc failed\n"));
993 if (!pull_ucs2_talloc(dom_info
, &dom_info
->name
, pass
.uni_name
,
995 DEBUG(2, ("pull_ucs2_talloc failed\n"));
996 TALLOC_FREE(dom_info
);
1000 sid_copy(&dom_info
->sid
, &pass
.domain_sid
);
1002 ADD_TO_ARRAY(state
->domains
, struct trustdom_info
*, dom_info
,
1003 &state
->domains
, &state
->num_domains
);
1005 if (state
->domains
== NULL
) {
1006 state
->num_domains
= 0;
1012 NTSTATUS
secrets_trusted_domains(TALLOC_CTX
*mem_ctx
, uint32
*num_domains
,
1013 struct trustdom_info
***domains
)
1015 struct list_trusted_domains_state state
;
1019 if (db_ctx
== NULL
) {
1020 return NT_STATUS_ACCESS_DENIED
;
1023 state
.num_domains
= 0;
1026 * Make sure that a talloc context for the trustdom_info structs
1030 if (!(state
.domains
= TALLOC_ARRAY(
1031 mem_ctx
, struct trustdom_info
*, 1))) {
1032 return NT_STATUS_NO_MEMORY
;
1035 db_ctx
->traverse_read(db_ctx
, list_trusted_domain
, (void *)&state
);
1037 *num_domains
= state
.num_domains
;
1038 *domains
= state
.domains
;
1039 return NT_STATUS_OK
;
1042 /*******************************************************************************
1043 Store a complete AFS keyfile into secrets.tdb.
1044 *******************************************************************************/
1046 bool secrets_store_afs_keyfile(const char *cell
, const struct afs_keyfile
*keyfile
)
1050 if ((cell
== NULL
) || (keyfile
== NULL
))
1053 if (ntohl(keyfile
->nkeys
) > SECRETS_AFS_MAXKEYS
)
1056 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
1057 return secrets_store(key
, keyfile
, sizeof(struct afs_keyfile
));
1060 /*******************************************************************************
1061 Fetch the current (highest) AFS key from secrets.tdb
1062 *******************************************************************************/
1063 bool secrets_fetch_afs_key(const char *cell
, struct afs_key
*result
)
1066 struct afs_keyfile
*keyfile
;
1070 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
1072 keyfile
= (struct afs_keyfile
*)secrets_fetch(key
, &size
);
1074 if (keyfile
== NULL
)
1077 if (size
!= sizeof(struct afs_keyfile
)) {
1082 i
= ntohl(keyfile
->nkeys
);
1084 if (i
> SECRETS_AFS_MAXKEYS
) {
1089 *result
= keyfile
->entry
[i
-1];
1091 result
->kvno
= ntohl(result
->kvno
);
1098 /******************************************************************************
1099 When kerberos is not available, choose between anonymous or
1100 authenticated connections.
1102 We need to use an authenticated connection if DCs have the
1103 RestrictAnonymous registry entry set > 0, or the "Additional
1104 restrictions for anonymous connections" set in the win2k Local
1107 Caller to free() result in domain, username, password
1108 *******************************************************************************/
1109 void secrets_fetch_ipc_userpass(char **username
, char **domain
, char **password
)
1111 *username
= (char *)secrets_fetch(SECRETS_AUTH_USER
, NULL
);
1112 *domain
= (char *)secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
1113 *password
= (char *)secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
1115 if (*username
&& **username
) {
1117 if (!*domain
|| !**domain
)
1118 *domain
= smb_xstrdup(lp_workgroup());
1120 if (!*password
|| !**password
)
1121 *password
= smb_xstrdup("");
1123 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1124 *domain
, *username
));
1127 DEBUG(3, ("IPC$ connections done anonymously\n"));
1128 *username
= smb_xstrdup("");
1129 *domain
= smb_xstrdup("");
1130 *password
= smb_xstrdup("");
1134 /******************************************************************************
1135 Open or create the schannel session store tdb.
1136 *******************************************************************************/
1138 #define SCHANNEL_STORE_VERSION_1 1
1139 #define SCHANNEL_STORE_VERSION_2 2 /* should not be used */
1140 #define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1
1142 TDB_CONTEXT
*open_schannel_session_store(TALLOC_CTX
*mem_ctx
)
1146 TDB_CONTEXT
*tdb_sc
= NULL
;
1147 char *fname
= talloc_asprintf(mem_ctx
, "%s/schannel_store.tdb", lp_private_dir());
1153 tdb_sc
= tdb_open_log(fname
, 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
1156 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname
));
1162 vers
= tdb_fetch_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION");
1163 if (vers
.dptr
== NULL
) {
1164 /* First opener, no version. */
1165 SIVAL(&ver
,0,SCHANNEL_STORE_VERSION_CURRENT
);
1166 vers
.dptr
= (uint8
*)&ver
;
1168 tdb_store_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION", vers
, TDB_REPLACE
);
1170 } else if (vers
.dsize
== 4) {
1171 ver
= IVAL(vers
.dptr
,0);
1172 if (ver
== SCHANNEL_STORE_VERSION_2
) {
1173 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1175 tdb_wipe_all(tdb_sc
);
1178 if (ver
!= SCHANNEL_STORE_VERSION_CURRENT
) {
1179 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1187 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1188 (int)vers
.dsize
, fname
));
1191 SAFE_FREE(vers
.dptr
);
1197 bool secrets_store_generic(const char *owner
, const char *key
, const char *secret
)
1199 char *tdbkey
= NULL
;
1202 if (asprintf(&tdbkey
, "SECRETS/GENERIC/%s/%s", owner
, key
) < 0) {
1203 DEBUG(0, ("asprintf failed!\n"));
1207 ret
= secrets_store(tdbkey
, secret
, strlen(secret
)+1);
1213 /*******************************************************************
1214 Find the ldap password.
1215 ******************************************************************/
1217 char *secrets_fetch_generic(const char *owner
, const char *key
)
1219 char *secret
= NULL
;
1220 char *tdbkey
= NULL
;
1222 if (( ! owner
) || ( ! key
)) {
1223 DEBUG(1, ("Invalid Paramters"));
1227 if (asprintf(&tdbkey
, "SECRETS/GENERIC/%s/%s", owner
, key
) < 0) {
1228 DEBUG(0, ("Out of memory!\n"));
1232 secret
= (char *)secrets_fetch(tdbkey
, NULL
);