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, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
70 DEBUG(0,("Failed to open %s\n", fname
));
78 * Set a reseed function for the crypto random generator
80 * This avoids a problem where systems without /dev/urandom
81 * could send the same challenge to multiple clients
83 set_rand_reseed_callback(get_rand_seed
);
85 /* Ensure that the reseed is done now, while we are root, etc */
86 generate_random_buffer(&dummy
, sizeof(dummy
));
94 void secrets_shutdown(void)
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
102 void *secrets_fetch(const char *key
, size_t *size
)
107 if (!secrets_init()) {
111 if (db_ctx
->fetch(db_ctx
, talloc_tos(), string_tdb_data(key
),
116 result
= memdup(dbuf
.dptr
, dbuf
.dsize
);
117 if (result
== NULL
) {
120 TALLOC_FREE(dbuf
.dptr
);
129 /* store a secrets entry
131 bool secrets_store(const char *key
, const void *data
, size_t size
)
133 if (!secrets_init()) {
137 return dbwrap_trans_store(db_ctx
, string_tdb_data(key
),
138 make_tdb_data((const uint8
*)data
, size
),
143 /* delete a secets database entry
145 bool secrets_delete(const char *key
)
147 if (!secrets_init()) {
151 return dbwrap_trans_delete(db_ctx
, string_tdb_data(key
)) == 0;
155 * Form a key for fetching the domain sid
157 * @param domain domain name
161 static const char *domain_sid_keystr(const char *domain
)
165 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
166 SECRETS_DOMAIN_SID
, domain
);
167 SMB_ASSERT(keystr
!= NULL
);
171 bool secrets_store_domain_sid(const char *domain
, const DOM_SID
*sid
)
175 ret
= secrets_store(domain_sid_keystr(domain
), sid
, sizeof(DOM_SID
));
177 /* Force a re-query, in case we modified our domain */
179 reset_global_sam_sid();
183 bool secrets_fetch_domain_sid(const char *domain
, DOM_SID
*sid
)
188 dyn_sid
= (DOM_SID
*)secrets_fetch(domain_sid_keystr(domain
), &size
);
193 if (size
!= sizeof(DOM_SID
)) {
203 bool secrets_store_domain_guid(const char *domain
, struct GUID
*guid
)
207 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
209 return secrets_store(key
, guid
, sizeof(struct GUID
));
212 bool secrets_fetch_domain_guid(const char *domain
, struct GUID
*guid
)
214 struct GUID
*dyn_guid
;
217 struct GUID new_guid
;
219 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
221 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
224 if (lp_server_role() == ROLE_DOMAIN_PDC
) {
225 smb_uuid_generate_random(&new_guid
);
226 if (!secrets_store_domain_guid(domain
, &new_guid
))
228 dyn_guid
= (struct GUID
*)secrets_fetch(key
, &size
);
230 if (dyn_guid
== NULL
) {
235 if (size
!= sizeof(struct GUID
)) {
236 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
247 * Form a key for fetching the machine trust account sec channel type
249 * @param domain domain name
253 static const char *machine_sec_channel_type_keystr(const char *domain
)
257 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
258 SECRETS_MACHINE_SEC_CHANNEL_TYPE
,
260 SMB_ASSERT(keystr
!= NULL
);
265 * Form a key for fetching the machine trust account last change time
267 * @param domain domain name
271 static const char *machine_last_change_time_keystr(const char *domain
)
275 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
276 SECRETS_MACHINE_LAST_CHANGE_TIME
,
278 SMB_ASSERT(keystr
!= NULL
);
284 * Form a key for fetching the machine trust account password
286 * @param domain domain name
290 static const char *machine_password_keystr(const char *domain
)
294 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
295 SECRETS_MACHINE_PASSWORD
, domain
);
296 SMB_ASSERT(keystr
!= NULL
);
301 * Form a key for fetching the machine trust account password
303 * @param domain domain name
305 * @return stored password's key
307 static const char *trust_keystr(const char *domain
)
311 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
312 SECRETS_MACHINE_ACCT_PASS
, domain
);
313 SMB_ASSERT(keystr
!= NULL
);
318 * Form a key for fetching a trusted domain password
320 * @param domain trusted domain name
322 * @return stored password's key
324 static char *trustdom_keystr(const char *domain
)
328 keystr
= talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
329 SECRETS_DOMTRUST_ACCT_PASS
,
331 SMB_ASSERT(keystr
!= NULL
);
335 /************************************************************************
336 Lock the trust password entry.
337 ************************************************************************/
339 void *secrets_get_trust_account_lock(TALLOC_CTX
*mem_ctx
, const char *domain
)
341 if (!secrets_init()) {
345 return db_ctx
->fetch_locked(
346 db_ctx
, mem_ctx
, string_term_tdb_data(trust_keystr(domain
)));
349 /************************************************************************
350 Routine to get the default secure channel type for trust accounts
351 ************************************************************************/
353 uint32
get_default_sec_channel(void)
355 if (lp_server_role() == ROLE_DOMAIN_BDC
||
356 lp_server_role() == ROLE_DOMAIN_PDC
) {
359 return SEC_CHAN_WKSTA
;
363 /************************************************************************
364 Routine to get the trust account password for a domain.
365 This only tries to get the legacy hashed version of the password.
366 The user of this function must have locked the trust password file using
367 the above secrets_lock_trust_account_password().
368 ************************************************************************/
370 bool secrets_fetch_trust_account_password_legacy(const char *domain
,
372 time_t *pass_last_set_time
,
375 struct machine_acct_pass
*pass
;
378 if (!(pass
= (struct machine_acct_pass
*)secrets_fetch(
379 trust_keystr(domain
), &size
))) {
380 DEBUG(5, ("secrets_fetch failed!\n"));
384 if (size
!= sizeof(*pass
)) {
385 DEBUG(0, ("secrets were of incorrect size!\n"));
389 if (pass_last_set_time
) {
390 *pass_last_set_time
= pass
->mod_time
;
392 memcpy(ret_pwd
, pass
->hash
, 16);
395 *channel
= get_default_sec_channel();
398 /* Test if machine password has expired and needs to be changed */
399 if (lp_machine_password_timeout()) {
400 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
401 (time_t)lp_machine_password_timeout())) {
402 global_machine_password_needs_changing
= True
;
410 /************************************************************************
411 Routine to get the trust account password for a domain.
412 The user of this function must have locked the trust password file using
413 the above secrets_lock_trust_account_password().
414 ************************************************************************/
416 bool secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
417 time_t *pass_last_set_time
,
422 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
425 DEBUG(4,("Using cleartext machine password\n"));
426 E_md4hash(plaintext
, ret_pwd
);
427 SAFE_FREE(plaintext
);
431 return secrets_fetch_trust_account_password_legacy(domain
, ret_pwd
,
437 * Pack SID passed by pointer
439 * @param pack_buf pointer to buffer which is to be filled with packed data
440 * @param bufsize size of packing buffer
441 * @param sid pointer to sid to be packed
443 * @return length of the packed representation of the whole structure
445 static size_t tdb_sid_pack(uint8
*pack_buf
, int bufsize
, DOM_SID
* sid
)
450 int remaining_space
= pack_buf
? bufsize
: 0;
456 len
+= tdb_pack(p
, remaining_space
, "bb", sid
->sid_rev_num
,
460 remaining_space
= bufsize
- len
;
463 for (idx
= 0; idx
< 6; idx
++) {
464 len
+= tdb_pack(p
, remaining_space
, "b",
468 remaining_space
= bufsize
- len
;
472 for (idx
= 0; idx
< MAXSUBAUTHS
; idx
++) {
473 len
+= tdb_pack(p
, remaining_space
, "d",
474 sid
->sub_auths
[idx
]);
477 remaining_space
= bufsize
- len
;
485 * Unpack SID into a pointer
487 * @param pack_buf pointer to buffer with packed representation
488 * @param bufsize size of the buffer
489 * @param sid pointer to sid structure to be filled with unpacked data
491 * @return size of structure unpacked from buffer
493 static size_t tdb_sid_unpack(uint8
*pack_buf
, int bufsize
, DOM_SID
* sid
)
497 if (!sid
|| !pack_buf
) return -1;
499 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "bb",
500 &sid
->sid_rev_num
, &sid
->num_auths
);
502 for (idx
= 0; idx
< 6; idx
++) {
503 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "b",
507 for (idx
= 0; idx
< MAXSUBAUTHS
; idx
++) {
508 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "d",
509 &sid
->sub_auths
[idx
]);
516 * Pack TRUSTED_DOM_PASS passed by pointer
518 * @param pack_buf pointer to buffer which is to be filled with packed data
519 * @param bufsize size of the buffer
520 * @param pass pointer to trusted domain password to be packed
522 * @return length of the packed representation of the whole structure
524 static size_t tdb_trusted_dom_pass_pack(uint8
*pack_buf
, int bufsize
,
525 TRUSTED_DOM_PASS
* pass
)
529 int remaining_space
= pack_buf
? bufsize
: 0;
535 /* packing unicode domain name and password */
536 len
+= tdb_pack(p
, remaining_space
, "d",
540 remaining_space
= bufsize
- len
;
543 for (idx
= 0; idx
< 32; idx
++) {
544 len
+= tdb_pack(p
, remaining_space
, "w",
545 pass
->uni_name
[idx
]);
548 remaining_space
= bufsize
- len
;
552 len
+= tdb_pack(p
, remaining_space
, "dPd", pass
->pass_len
,
553 pass
->pass
, pass
->mod_time
);
556 remaining_space
= bufsize
- len
;
559 /* packing SID structure */
560 len
+= tdb_sid_pack(p
, remaining_space
, &pass
->domain_sid
);
563 remaining_space
= bufsize
- len
;
571 * Unpack TRUSTED_DOM_PASS passed by pointer
573 * @param pack_buf pointer to buffer with packed representation
574 * @param bufsize size of the buffer
575 * @param pass pointer to trusted domain password to be filled with unpacked data
577 * @return size of structure unpacked from buffer
579 static size_t tdb_trusted_dom_pass_unpack(uint8
*pack_buf
, int bufsize
,
580 TRUSTED_DOM_PASS
* pass
)
585 if (!pack_buf
|| !pass
) return -1;
587 /* unpack unicode domain name and plaintext password */
588 len
+= tdb_unpack(pack_buf
, bufsize
- len
, "d", &pass
->uni_name_len
);
590 for (idx
= 0; idx
< 32; idx
++)
591 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "w",
592 &pass
->uni_name
[idx
]);
594 len
+= tdb_unpack(pack_buf
+ len
, bufsize
- len
, "dPd",
595 &pass
->pass_len
, &passp
, &pass
->mod_time
);
597 fstrcpy(pass
->pass
, passp
);
601 /* unpack domain sid */
602 len
+= tdb_sid_unpack(pack_buf
+ len
, bufsize
- len
,
608 /************************************************************************
609 Routine to get account password to trusted domain
610 ************************************************************************/
612 bool secrets_fetch_trusted_domain_password(const char *domain
, char** pwd
,
613 DOM_SID
*sid
, time_t *pass_last_set_time
)
615 struct trusted_dom_pass pass
;
618 /* unpacking structures */
624 /* fetching trusted domain password structure */
625 if (!(pass_buf
= (uint8
*)secrets_fetch(trustdom_keystr(domain
),
627 DEBUG(5, ("secrets_fetch failed!\n"));
631 /* unpack trusted domain password */
632 pass_len
= tdb_trusted_dom_pass_unpack(pass_buf
, size
, &pass
);
635 if (pass_len
!= size
) {
636 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
640 /* the trust's password */
642 *pwd
= SMB_STRDUP(pass
.pass
);
648 /* last change time */
649 if (pass_last_set_time
) *pass_last_set_time
= pass
.mod_time
;
652 if (sid
!= NULL
) sid_copy(sid
, &pass
.domain_sid
);
658 * Routine to store the password for trusted domain
660 * @param domain remote domain name
661 * @param pwd plain text password of trust relationship
662 * @param sid remote domain sid
664 * @return true if succeeded
667 bool secrets_store_trusted_domain_password(const char* domain
, const char* pwd
,
670 smb_ucs2_t
*uni_dom_name
;
673 /* packing structures */
674 uint8
*pass_buf
= NULL
;
677 struct trusted_dom_pass pass
;
680 if (push_ucs2_allocate(&uni_dom_name
, domain
) == (size_t)-1) {
681 DEBUG(0, ("Could not convert domain name %s to unicode\n",
686 strncpy_w(pass
.uni_name
, uni_dom_name
, sizeof(pass
.uni_name
) - 1);
687 pass
.uni_name_len
= strlen_w(uni_dom_name
)+1;
688 SAFE_FREE(uni_dom_name
);
690 /* last change time */
691 pass
.mod_time
= time(NULL
);
693 /* password of the trust */
694 pass
.pass_len
= strlen(pwd
);
695 fstrcpy(pass
.pass
, pwd
);
698 sid_copy(&pass
.domain_sid
, sid
);
700 /* Calculate the length. */
701 pass_len
= tdb_trusted_dom_pass_pack(NULL
, 0, &pass
);
702 pass_buf
= SMB_MALLOC_ARRAY(uint8
, pass_len
);
706 pass_len
= tdb_trusted_dom_pass_pack(pass_buf
, pass_len
, &pass
);
707 ret
= secrets_store(trustdom_keystr(domain
), (void *)pass_buf
,
713 /************************************************************************
714 Routine to delete the plaintext machine account password
715 ************************************************************************/
717 bool secrets_delete_machine_password(const char *domain
)
719 return secrets_delete(machine_password_keystr(domain
));
722 /************************************************************************
723 Routine to delete the plaintext machine account password, sec channel type and
724 last change time from secrets database
725 ************************************************************************/
727 bool secrets_delete_machine_password_ex(const char *domain
)
729 if (!secrets_delete(machine_password_keystr(domain
))) {
732 if (!secrets_delete(machine_sec_channel_type_keystr(domain
))) {
735 return secrets_delete(machine_last_change_time_keystr(domain
));
738 /************************************************************************
739 Routine to delete the domain sid
740 ************************************************************************/
742 bool secrets_delete_domain_sid(const char *domain
)
744 return secrets_delete(domain_sid_keystr(domain
));
747 /************************************************************************
748 Routine to set the plaintext machine account password for a realm
749 the password is assumed to be a null terminated ascii string
750 ************************************************************************/
752 bool secrets_store_machine_password(const char *pass
, const char *domain
, uint32 sec_channel
)
755 uint32 last_change_time
;
756 uint32 sec_channel_type
;
758 ret
= secrets_store(machine_password_keystr(domain
), pass
, strlen(pass
)+1);
762 SIVAL(&last_change_time
, 0, time(NULL
));
763 ret
= secrets_store(machine_last_change_time_keystr(domain
), &last_change_time
, sizeof(last_change_time
));
765 SIVAL(&sec_channel_type
, 0, sec_channel
);
766 ret
= secrets_store(machine_sec_channel_type_keystr(domain
), &sec_channel_type
, sizeof(sec_channel_type
));
771 /************************************************************************
772 Routine to fetch the plaintext machine account password for a realm
773 the password is assumed to be a null terminated ascii string.
774 ************************************************************************/
776 char *secrets_fetch_machine_password(const char *domain
,
777 time_t *pass_last_set_time
,
781 ret
= (char *)secrets_fetch(machine_password_keystr(domain
), NULL
);
783 if (pass_last_set_time
) {
785 uint32
*last_set_time
;
786 last_set_time
= (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain
), &size
);
788 *pass_last_set_time
= IVAL(last_set_time
,0);
789 SAFE_FREE(last_set_time
);
791 *pass_last_set_time
= 0;
797 uint32
*channel_type
;
798 channel_type
= (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain
), &size
);
800 *channel
= IVAL(channel_type
,0);
801 SAFE_FREE(channel_type
);
803 *channel
= get_default_sec_channel();
810 /************************************************************************
811 Routine to delete the password for trusted domain
812 ************************************************************************/
814 bool trusted_domain_password_delete(const char *domain
)
816 return secrets_delete(trustdom_keystr(domain
));
819 bool secrets_store_ldap_pw(const char* dn
, char* pw
)
824 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, dn
) < 0) {
825 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
829 ret
= secrets_store(key
, pw
, strlen(pw
)+1);
835 /*******************************************************************
836 Find the ldap password.
837 ******************************************************************/
839 bool fetch_ldap_pw(char **dn
, char** pw
)
844 *dn
= smb_xstrdup(lp_ldap_admin_dn());
846 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, *dn
) < 0) {
848 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
851 *pw
=(char *)secrets_fetch(key
, &size
);
855 /* Upgrade 2.2 style entry */
857 char* old_style_key
= SMB_STRDUP(*dn
);
859 fstring old_style_pw
;
861 if (!old_style_key
) {
862 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
866 for (p
=old_style_key
; *p
; p
++)
867 if (*p
== ',') *p
= '/';
869 data
=(char *)secrets_fetch(old_style_key
, &size
);
870 if (!size
&& size
< sizeof(old_style_pw
)) {
871 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
872 SAFE_FREE(old_style_key
);
877 size
= MIN(size
, sizeof(fstring
)-1);
878 strncpy(old_style_pw
, data
, size
);
879 old_style_pw
[size
] = 0;
883 if (!secrets_store_ldap_pw(*dn
, old_style_pw
)) {
884 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
885 SAFE_FREE(old_style_key
);
889 if (!secrets_delete(old_style_key
)) {
890 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
893 SAFE_FREE(old_style_key
);
895 *pw
= smb_xstrdup(old_style_pw
);
902 * Get trusted domains info from secrets.tdb.
905 struct list_trusted_domains_state
{
907 struct trustdom_info
**domains
;
910 static int list_trusted_domain(struct db_record
*rec
, void *private_data
)
912 const size_t prefix_len
= strlen(SECRETS_DOMTRUST_ACCT_PASS
);
913 size_t packed_size
= 0;
914 struct trusted_dom_pass pass
;
915 struct trustdom_info
*dom_info
;
917 struct list_trusted_domains_state
*state
=
918 (struct list_trusted_domains_state
*)private_data
;
920 if ((rec
->key
.dsize
< prefix_len
)
921 || (strncmp((char *)rec
->key
.dptr
, SECRETS_DOMTRUST_ACCT_PASS
,
926 packed_size
= tdb_trusted_dom_pass_unpack(
927 rec
->value
.dptr
, rec
->value
.dsize
, &pass
);
929 if (rec
->value
.dsize
!= packed_size
) {
930 DEBUG(2, ("Secrets record is invalid!\n"));
934 if (pass
.domain_sid
.num_auths
!= 4) {
935 DEBUG(0, ("SID %s is not a domain sid, has %d "
936 "auths instead of 4\n",
937 sid_string_dbg(&pass
.domain_sid
),
938 pass
.domain_sid
.num_auths
));
942 if (!(dom_info
= TALLOC_P(state
->domains
, struct trustdom_info
))) {
943 DEBUG(0, ("talloc failed\n"));
947 if (pull_ucs2_talloc(dom_info
, &dom_info
->name
,
948 pass
.uni_name
) == (size_t)-1) {
949 DEBUG(2, ("pull_ucs2_talloc failed\n"));
950 TALLOC_FREE(dom_info
);
954 sid_copy(&dom_info
->sid
, &pass
.domain_sid
);
956 ADD_TO_ARRAY(state
->domains
, struct trustdom_info
*, dom_info
,
957 &state
->domains
, &state
->num_domains
);
959 if (state
->domains
== NULL
) {
960 state
->num_domains
= 0;
966 NTSTATUS
secrets_trusted_domains(TALLOC_CTX
*mem_ctx
, uint32
*num_domains
,
967 struct trustdom_info
***domains
)
969 struct list_trusted_domains_state state
;
973 if (db_ctx
== NULL
) {
974 return NT_STATUS_ACCESS_DENIED
;
977 state
.num_domains
= 0;
980 * Make sure that a talloc context for the trustdom_info structs
984 if (!(state
.domains
= TALLOC_ARRAY(
985 mem_ctx
, struct trustdom_info
*, 1))) {
986 return NT_STATUS_NO_MEMORY
;
989 db_ctx
->traverse(db_ctx
, list_trusted_domain
, (void *)&state
);
991 *num_domains
= state
.num_domains
;
992 *domains
= state
.domains
;
996 /*******************************************************************************
997 Store a complete AFS keyfile into secrets.tdb.
998 *******************************************************************************/
1000 bool secrets_store_afs_keyfile(const char *cell
, const struct afs_keyfile
*keyfile
)
1004 if ((cell
== NULL
) || (keyfile
== NULL
))
1007 if (ntohl(keyfile
->nkeys
) > SECRETS_AFS_MAXKEYS
)
1010 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
1011 return secrets_store(key
, keyfile
, sizeof(struct afs_keyfile
));
1014 /*******************************************************************************
1015 Fetch the current (highest) AFS key from secrets.tdb
1016 *******************************************************************************/
1017 bool secrets_fetch_afs_key(const char *cell
, struct afs_key
*result
)
1020 struct afs_keyfile
*keyfile
;
1024 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
1026 keyfile
= (struct afs_keyfile
*)secrets_fetch(key
, &size
);
1028 if (keyfile
== NULL
)
1031 if (size
!= sizeof(struct afs_keyfile
)) {
1036 i
= ntohl(keyfile
->nkeys
);
1038 if (i
> SECRETS_AFS_MAXKEYS
) {
1043 *result
= keyfile
->entry
[i
-1];
1045 result
->kvno
= ntohl(result
->kvno
);
1050 /******************************************************************************
1051 When kerberos is not available, choose between anonymous or
1052 authenticated connections.
1054 We need to use an authenticated connection if DCs have the
1055 RestrictAnonymous registry entry set > 0, or the "Additional
1056 restrictions for anonymous connections" set in the win2k Local
1059 Caller to free() result in domain, username, password
1060 *******************************************************************************/
1061 void secrets_fetch_ipc_userpass(char **username
, char **domain
, char **password
)
1063 *username
= (char *)secrets_fetch(SECRETS_AUTH_USER
, NULL
);
1064 *domain
= (char *)secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
1065 *password
= (char *)secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
1067 if (*username
&& **username
) {
1069 if (!*domain
|| !**domain
)
1070 *domain
= smb_xstrdup(lp_workgroup());
1072 if (!*password
|| !**password
)
1073 *password
= smb_xstrdup("");
1075 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1076 *domain
, *username
));
1079 DEBUG(3, ("IPC$ connections done anonymously\n"));
1080 *username
= smb_xstrdup("");
1081 *domain
= smb_xstrdup("");
1082 *password
= smb_xstrdup("");
1086 /******************************************************************************
1087 Open or create the schannel session store tdb.
1088 *******************************************************************************/
1090 static TDB_CONTEXT
*open_schannel_session_store(TALLOC_CTX
*mem_ctx
)
1094 TDB_CONTEXT
*tdb_sc
= NULL
;
1095 char *fname
= talloc_asprintf(mem_ctx
, "%s/schannel_store.tdb", lp_private_dir());
1101 tdb_sc
= tdb_open_log(fname
, 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
1104 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname
));
1109 vers
= tdb_fetch_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION");
1110 if (vers
.dptr
== NULL
) {
1111 /* First opener, no version. */
1113 vers
.dptr
= (uint8
*)&ver
;
1115 tdb_store_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION", vers
, TDB_REPLACE
);
1117 } else if (vers
.dsize
== 4) {
1118 ver
= IVAL(vers
.dptr
,0);
1122 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1128 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1129 (int)vers
.dsize
, fname
));
1132 SAFE_FREE(vers
.dptr
);
1138 /******************************************************************************
1139 Store the schannel state after an AUTH2 call.
1140 Note we must be root here.
1141 *******************************************************************************/
1143 bool secrets_store_schannel_session_info(TALLOC_CTX
*mem_ctx
,
1144 const char *remote_machine
,
1145 const struct dcinfo
*pdc
)
1147 TDB_CONTEXT
*tdb_sc
= NULL
;
1150 char *keystr
= talloc_asprintf_strupper_m(mem_ctx
, "%s/%s",
1151 SECRETS_SCHANNEL_STATE
,
1157 /* Work out how large the record is. */
1158 value
.dsize
= tdb_pack(NULL
, 0, "dBBBBBfff",
1160 8, pdc
->seed_chal
.data
,
1161 8, pdc
->clnt_chal
.data
,
1162 8, pdc
->srv_chal
.data
,
1166 pdc
->remote_machine
,
1169 value
.dptr
= TALLOC_ARRAY(mem_ctx
, uint8
, value
.dsize
);
1171 TALLOC_FREE(keystr
);
1175 value
.dsize
= tdb_pack(value
.dptr
, value
.dsize
, "dBBBBBfff",
1177 8, pdc
->seed_chal
.data
,
1178 8, pdc
->clnt_chal
.data
,
1179 8, pdc
->srv_chal
.data
,
1183 pdc
->remote_machine
,
1186 tdb_sc
= open_schannel_session_store(mem_ctx
);
1188 TALLOC_FREE(keystr
);
1189 TALLOC_FREE(value
.dptr
);
1193 ret
= (tdb_store_bystring(tdb_sc
, keystr
, value
, TDB_REPLACE
) == 0 ? True
: False
);
1195 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1199 TALLOC_FREE(keystr
);
1200 TALLOC_FREE(value
.dptr
);
1204 /******************************************************************************
1205 Restore the schannel state on a client reconnect.
1206 Note we must be root here.
1207 *******************************************************************************/
1209 bool secrets_restore_schannel_session_info(TALLOC_CTX
*mem_ctx
,
1210 const char *remote_machine
,
1211 struct dcinfo
**ppdc
)
1213 TDB_CONTEXT
*tdb_sc
= NULL
;
1215 unsigned char *pseed_chal
= NULL
;
1216 unsigned char *pclnt_chal
= NULL
;
1217 unsigned char *psrv_chal
= NULL
;
1218 unsigned char *psess_key
= NULL
;
1219 unsigned char *pmach_pw
= NULL
;
1220 uint32 l1
, l2
, l3
, l4
, l5
;
1222 struct dcinfo
*pdc
= NULL
;
1223 char *keystr
= talloc_asprintf_strupper_m(mem_ctx
, "%s/%s",
1224 SECRETS_SCHANNEL_STATE
,
1233 tdb_sc
= open_schannel_session_store(mem_ctx
);
1235 TALLOC_FREE(keystr
);
1239 value
= tdb_fetch_bystring(tdb_sc
, keystr
);
1241 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1247 pdc
= TALLOC_ZERO_P(mem_ctx
, struct dcinfo
);
1249 /* Retrieve the record. */
1250 ret
= tdb_unpack(value
.dptr
, value
.dsize
, "dBBBBBfff",
1258 &pdc
->remote_machine
,
1261 if (ret
== -1 || l1
!= 8 || l2
!= 8 || l3
!= 8 || l4
!= 16 || l5
!= 16) {
1262 /* Bad record - delete it. */
1263 tdb_delete_bystring(tdb_sc
, keystr
);
1265 TALLOC_FREE(keystr
);
1267 SAFE_FREE(pseed_chal
);
1268 SAFE_FREE(pclnt_chal
);
1269 SAFE_FREE(psrv_chal
);
1270 SAFE_FREE(psess_key
);
1271 SAFE_FREE(pmach_pw
);
1272 SAFE_FREE(value
.dptr
);
1278 memcpy(pdc
->seed_chal
.data
, pseed_chal
, 8);
1279 memcpy(pdc
->clnt_chal
.data
, pclnt_chal
, 8);
1280 memcpy(pdc
->srv_chal
.data
, psrv_chal
, 8);
1281 memcpy(pdc
->sess_key
, psess_key
, 16);
1282 memcpy(pdc
->mach_pw
, pmach_pw
, 16);
1284 /* We know these are true so didn't bother to store them. */
1285 pdc
->challenge_sent
= True
;
1286 pdc
->authenticated
= True
;
1288 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1291 SAFE_FREE(pseed_chal
);
1292 SAFE_FREE(pclnt_chal
);
1293 SAFE_FREE(psrv_chal
);
1294 SAFE_FREE(psess_key
);
1295 SAFE_FREE(pmach_pw
);
1297 TALLOC_FREE(keystr
);
1298 SAFE_FREE(value
.dptr
);
1305 bool secrets_store_generic(const char *owner
, const char *key
, const char *secret
)
1307 char *tdbkey
= NULL
;
1310 if (asprintf(&tdbkey
, "SECRETS/GENERIC/%s/%s", owner
, key
) < 0) {
1311 DEBUG(0, ("asprintf failed!\n"));
1315 ret
= secrets_store(tdbkey
, secret
, strlen(secret
)+1);
1321 /*******************************************************************
1322 Find the ldap password.
1323 ******************************************************************/
1325 char *secrets_fetch_generic(const char *owner
, const char *key
)
1327 char *secret
= NULL
;
1328 char *tdbkey
= NULL
;
1330 if (( ! owner
) || ( ! key
)) {
1331 DEBUG(1, ("Invalid Paramters"));
1335 if (asprintf(&tdbkey
, "SECRETS/GENERIC/%s/%s", owner
, key
) < 0) {
1336 DEBUG(0, ("Out of memory!\n"));
1340 secret
= (char *)secrets_fetch(tdbkey
, NULL
);