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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* the Samba secrets database stores any generated, private information
24 such as the local SID and machine trust password */
29 #define DBGC_CLASS DBGC_PASSDB
31 static TDB_CONTEXT
*tdb
;
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(int *new_seed
)
46 *new_seed
= sys_getpid();
48 tdb_change_int32_atomic(tdb
, "INFO/random_seed", new_seed
, 1);
52 /* open up the secrets database */
53 BOOL
secrets_init(void)
61 pstrcpy(fname
, lp_private_dir());
62 pstrcat(fname
,"/secrets.tdb");
64 tdb
= tdb_open_log(fname
, 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
67 DEBUG(0,("Failed to open %s\n", fname
));
72 * Set a reseed function for the crypto random generator
74 * This avoids a problem where systems without /dev/urandom
75 * could send the same challenge to multiple clients
77 set_rand_reseed_callback(get_rand_seed
);
79 /* Ensure that the reseed is done now, while we are root, etc */
80 generate_random_buffer(&dummy
, sizeof(dummy
));
85 /* read a entry from the secrets database - the caller must free the result
86 if size is non-null then the size of the entry is put in there
88 void *secrets_fetch(const char *key
, size_t *size
)
94 dbuf
= tdb_fetch(tdb
, string_tdb_data(key
));
100 /* store a secrets entry
102 BOOL
secrets_store(const char *key
, const void *data
, size_t size
)
107 return tdb_store(tdb
, string_tdb_data(key
), make_tdb_data(data
, size
),
112 /* delete a secets database entry
114 BOOL
secrets_delete(const char *key
)
119 return tdb_delete(tdb
, string_tdb_data(key
)) == 0;
122 BOOL
secrets_store_domain_sid(const char *domain
, const DOM_SID
*sid
)
127 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_SID
, domain
);
129 ret
= secrets_store(key
, sid
, sizeof(DOM_SID
));
131 /* Force a re-query, in case we modified our domain */
133 reset_global_sam_sid();
137 BOOL
secrets_fetch_domain_sid(const char *domain
, DOM_SID
*sid
)
143 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_SID
, domain
);
145 dyn_sid
= (DOM_SID
*)secrets_fetch(key
, &size
);
150 if (size
!= sizeof(DOM_SID
))
161 BOOL
secrets_store_domain_guid(const char *domain
, struct uuid
*guid
)
165 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
167 return secrets_store(key
, guid
, sizeof(struct uuid
));
170 BOOL
secrets_fetch_domain_guid(const char *domain
, struct uuid
*guid
)
172 struct uuid
*dyn_guid
;
175 struct uuid new_guid
;
177 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_DOMAIN_GUID
, domain
);
179 dyn_guid
= (struct uuid
*)secrets_fetch(key
, &size
);
181 if ((!dyn_guid
) && (lp_server_role() == ROLE_DOMAIN_PDC
)) {
182 smb_uuid_generate_random(&new_guid
);
183 if (!secrets_store_domain_guid(domain
, &new_guid
))
185 dyn_guid
= (struct uuid
*)secrets_fetch(key
, &size
);
186 if (dyn_guid
== NULL
)
190 if (size
!= sizeof(struct uuid
))
192 DEBUG(1,("UUID size %d is wrong!\n", (int)size
));
203 * Form a key for fetching the machine trust account password
205 * @param domain domain name
207 * @return stored password's key
209 const char *trust_keystr(const char *domain
)
211 static fstring keystr
;
213 slprintf(keystr
,sizeof(keystr
)-1,"%s/%s",
214 SECRETS_MACHINE_ACCT_PASS
, domain
);
221 * Form a key for fetching a trusted domain password
223 * @param domain trusted domain name
225 * @return stored password's key
227 static char *trustdom_keystr(const char *domain
)
229 static pstring keystr
;
231 pstr_sprintf(keystr
, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS
, domain
);
237 /************************************************************************
238 Lock the trust password entry.
239 ************************************************************************/
241 BOOL
secrets_lock_trust_account_password(const char *domain
, BOOL dolock
)
247 return (tdb_lock_bystring(tdb
, trust_keystr(domain
),0) == 0);
249 tdb_unlock_bystring(tdb
, trust_keystr(domain
));
253 /************************************************************************
254 Routine to get the default secure channel type for trust accounts
255 ************************************************************************/
257 uint32
get_default_sec_channel(void)
259 if (lp_server_role() == ROLE_DOMAIN_BDC
||
260 lp_server_role() == ROLE_DOMAIN_PDC
) {
263 return SEC_CHAN_WKSTA
;
267 /************************************************************************
268 Routine to get the trust account password for a domain.
269 The user of this function must have locked the trust password file using
270 the above secrets_lock_trust_account_password().
271 ************************************************************************/
273 BOOL
secrets_fetch_trust_account_password(const char *domain
, uint8 ret_pwd
[16],
274 time_t *pass_last_set_time
,
277 struct machine_acct_pass
*pass
;
281 plaintext
= secrets_fetch_machine_password(domain
, pass_last_set_time
,
284 DEBUG(4,("Using cleartext machine password\n"));
285 E_md4hash(plaintext
, ret_pwd
);
286 SAFE_FREE(plaintext
);
290 if (!(pass
= secrets_fetch(trust_keystr(domain
), &size
))) {
291 DEBUG(5, ("secrets_fetch failed!\n"));
295 if (size
!= sizeof(*pass
)) {
296 DEBUG(0, ("secrets were of incorrect size!\n"));
300 if (pass_last_set_time
) {
301 *pass_last_set_time
= pass
->mod_time
;
303 memcpy(ret_pwd
, pass
->hash
, 16);
307 *channel
= get_default_sec_channel();
310 /* Test if machine password has expired and needs to be changed */
311 if (lp_machine_password_timeout()) {
312 if (pass
->mod_time
> 0 && time(NULL
) > (pass
->mod_time
+
313 lp_machine_password_timeout())) {
314 global_machine_password_needs_changing
= True
;
321 /************************************************************************
322 Routine to get account password to trusted domain
323 ************************************************************************/
325 BOOL
secrets_fetch_trusted_domain_password(const char *domain
, char** pwd
,
326 DOM_SID
*sid
, time_t *pass_last_set_time
)
328 struct trusted_dom_pass pass
;
331 /* unpacking structures */
337 /* fetching trusted domain password structure */
338 if (!(pass_buf
= secrets_fetch(trustdom_keystr(domain
), &size
))) {
339 DEBUG(5, ("secrets_fetch failed!\n"));
343 /* unpack trusted domain password */
344 pass_len
= tdb_trusted_dom_pass_unpack(pass_buf
, size
, &pass
);
347 if (pass_len
!= size
) {
348 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
352 /* the trust's password */
354 *pwd
= SMB_STRDUP(pass
.pass
);
360 /* last change time */
361 if (pass_last_set_time
) *pass_last_set_time
= pass
.mod_time
;
364 sid_copy(sid
, &pass
.domain_sid
);
369 /************************************************************************
370 Routine to set the trust account password for a domain.
371 ************************************************************************/
373 BOOL
secrets_store_trust_account_password(const char *domain
, uint8 new_pwd
[16])
375 struct machine_acct_pass pass
;
377 pass
.mod_time
= time(NULL
);
378 memcpy(pass
.hash
, new_pwd
, 16);
380 return secrets_store(trust_keystr(domain
), (void *)&pass
, sizeof(pass
));
384 * Routine to store the password for trusted domain
386 * @param domain remote domain name
387 * @param pwd plain text password of trust relationship
388 * @param sid remote domain sid
390 * @return true if succeeded
393 BOOL
secrets_store_trusted_domain_password(const char* domain
, smb_ucs2_t
*uni_dom_name
,
394 size_t uni_name_len
, const char* pwd
,
397 /* packing structures */
400 int pass_buf_len
= sizeof(pass_buf
);
402 struct trusted_dom_pass pass
;
405 /* unicode domain name and its length */
409 strncpy_w(pass
.uni_name
, uni_dom_name
, sizeof(pass
.uni_name
) - 1);
410 pass
.uni_name_len
= uni_name_len
;
412 /* last change time */
413 pass
.mod_time
= time(NULL
);
415 /* password of the trust */
416 pass
.pass_len
= strlen(pwd
);
417 fstrcpy(pass
.pass
, pwd
);
420 sid_copy(&pass
.domain_sid
, &sid
);
422 pass_len
= tdb_trusted_dom_pass_pack(pass_buf
, pass_buf_len
, &pass
);
424 return secrets_store(trustdom_keystr(domain
), (void *)&pass_buf
, pass_len
);
427 /************************************************************************
428 Routine to set the plaintext machine account password for a realm
429 the password is assumed to be a null terminated ascii string
430 ************************************************************************/
432 BOOL
secrets_store_machine_password(const char *pass
, const char *domain
, uint32 sec_channel
)
436 uint32 last_change_time
;
437 uint32 sec_channel_type
;
439 asprintf(&key
, "%s/%s", SECRETS_MACHINE_PASSWORD
, domain
);
444 ret
= secrets_store(key
, pass
, strlen(pass
)+1);
450 asprintf(&key
, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME
, domain
);
455 SIVAL(&last_change_time
, 0, time(NULL
));
456 ret
= secrets_store(key
, &last_change_time
, sizeof(last_change_time
));
459 asprintf(&key
, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE
, domain
);
464 SIVAL(&sec_channel_type
, 0, sec_channel
);
465 ret
= secrets_store(key
, &sec_channel_type
, sizeof(sec_channel_type
));
471 /************************************************************************
472 Routine to fetch the plaintext machine account password for a realm
473 the password is assumed to be a null terminated ascii string.
474 ************************************************************************/
476 char *secrets_fetch_machine_password(const char *domain
,
477 time_t *pass_last_set_time
,
482 asprintf(&key
, "%s/%s", SECRETS_MACHINE_PASSWORD
, domain
);
484 ret
= (char *)secrets_fetch(key
, NULL
);
487 if (pass_last_set_time
) {
489 uint32
*last_set_time
;
490 asprintf(&key
, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME
, domain
);
492 last_set_time
= secrets_fetch(key
, &size
);
494 *pass_last_set_time
= IVAL(last_set_time
,0);
495 SAFE_FREE(last_set_time
);
497 *pass_last_set_time
= 0;
504 uint32
*channel_type
;
505 asprintf(&key
, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE
, domain
);
507 channel_type
= secrets_fetch(key
, &size
);
509 *channel
= IVAL(channel_type
,0);
510 SAFE_FREE(channel_type
);
512 *channel
= get_default_sec_channel();
520 /*******************************************************************
521 Wrapper around retrieving the trust account password
522 *******************************************************************/
524 BOOL
get_trust_pw(const char *domain
, uint8 ret_pwd
[16], uint32
*channel
)
528 time_t last_set_time
;
530 /* if we are a DC and this is not our domain, then lookup an account
531 for the domain trust */
533 if ( IS_DC
&& !strequal(domain
, lp_workgroup()) && lp_allow_trusted_domains() ) {
534 if (!secrets_fetch_trusted_domain_password(domain
, &pwd
, &sid
,
536 DEBUG(0, ("get_trust_pw: could not fetch trust "
537 "account password for trusted domain %s\n",
542 *channel
= SEC_CHAN_DOMAIN
;
543 E_md4hash(pwd
, ret_pwd
);
549 /* Just get the account for the requested domain. In the future this
550 * might also cover to be member of more than one domain. */
552 if (secrets_fetch_trust_account_password(domain
, ret_pwd
,
553 &last_set_time
, channel
))
556 DEBUG(5, ("get_trust_pw: could not fetch trust account "
557 "password for domain %s\n", domain
));
561 /************************************************************************
562 Routine to delete the machine trust account password file for a domain.
563 ************************************************************************/
565 BOOL
trust_password_delete(const char *domain
)
567 return secrets_delete(trust_keystr(domain
));
570 /************************************************************************
571 Routine to delete the password for trusted domain
572 ************************************************************************/
574 BOOL
trusted_domain_password_delete(const char *domain
)
576 return secrets_delete(trustdom_keystr(domain
));
579 BOOL
secrets_store_ldap_pw(const char* dn
, char* pw
)
584 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, dn
) < 0) {
585 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
589 ret
= secrets_store(key
, pw
, strlen(pw
)+1);
595 /*******************************************************************
596 Find the ldap password.
597 ******************************************************************/
599 BOOL
fetch_ldap_pw(char **dn
, char** pw
)
604 *dn
= smb_xstrdup(lp_ldap_admin_dn());
606 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, *dn
) < 0) {
608 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
611 *pw
=secrets_fetch(key
, &size
);
615 /* Upgrade 2.2 style entry */
617 char* old_style_key
= SMB_STRDUP(*dn
);
619 fstring old_style_pw
;
621 if (!old_style_key
) {
622 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
626 for (p
=old_style_key
; *p
; p
++)
627 if (*p
== ',') *p
= '/';
629 data
=secrets_fetch(old_style_key
, &size
);
630 if (!size
&& size
< sizeof(old_style_pw
)) {
631 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
632 SAFE_FREE(old_style_key
);
637 size
= MIN(size
, sizeof(fstring
)-1);
638 strncpy(old_style_pw
, data
, size
);
639 old_style_pw
[size
] = 0;
643 if (!secrets_store_ldap_pw(*dn
, old_style_pw
)) {
644 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
645 SAFE_FREE(old_style_key
);
649 if (!secrets_delete(old_style_key
)) {
650 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
653 SAFE_FREE(old_style_key
);
655 *pw
= smb_xstrdup(old_style_pw
);
662 * Get trusted domains info from secrets.tdb.
664 * The linked list is allocated on the supplied talloc context, caller gets to destroy
667 * @param ctx Allocation context
668 * @param enum_ctx Starting index, eg. we can start fetching at third
669 * or sixth trusted domain entry. Zero is the first index.
670 * Value it is set to is the enum context for the next enumeration.
671 * @param num_domains Number of domain entries to fetch at one call
672 * @param domains Pointer to array of trusted domain structs to be filled up
674 * @return nt status code of rpc response
677 NTSTATUS
secrets_get_trusted_domains(TALLOC_CTX
* ctx
, int* enum_ctx
, unsigned int max_num_domains
,
678 int *num_domains
, TRUSTDOM
***domains
)
680 TDB_LIST_NODE
*keys
, *k
;
681 TRUSTDOM
*dom
= NULL
;
683 unsigned int start_idx
;
685 size_t size
, packed_size
= 0;
688 struct trusted_dom_pass
*pass
= TALLOC_ZERO_P(ctx
, struct trusted_dom_pass
);
691 if (!secrets_init()) return NT_STATUS_ACCESS_DENIED
;
694 DEBUG(0, ("talloc_zero failed!\n"));
695 return NT_STATUS_NO_MEMORY
;
699 start_idx
= *enum_ctx
;
701 /* generate searching pattern */
702 if (!(pattern
= talloc_asprintf(ctx
, "%s/*", SECRETS_DOMTRUST_ACCT_PASS
))) {
703 DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n"));
704 return NT_STATUS_NO_MEMORY
;
707 DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n",
708 max_num_domains
, *enum_ctx
));
710 *domains
= TALLOC_ZERO_ARRAY(ctx
, TRUSTDOM
*, max_num_domains
);
712 /* fetching trusted domains' data and collecting them in a list */
713 keys
= tdb_search_keys(tdb
, pattern
);
716 * if there's no keys returned ie. no trusted domain,
717 * return "no more entries" code
719 status
= NT_STATUS_NO_MORE_ENTRIES
;
721 /* searching for keys in secrets db -- way to go ... */
722 for (k
= keys
; k
; k
= k
->next
) {
725 /* important: ensure null-termination of the key string */
726 secrets_key
= SMB_STRNDUP(k
->node_key
.dptr
, k
->node_key
.dsize
);
728 DEBUG(0, ("strndup failed!\n"));
729 return NT_STATUS_NO_MEMORY
;
732 packed_pass
= secrets_fetch(secrets_key
, &size
);
733 packed_size
= tdb_trusted_dom_pass_unpack(packed_pass
, size
, pass
);
734 /* packed representation isn't needed anymore */
735 SAFE_FREE(packed_pass
);
737 if (size
!= packed_size
) {
738 DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key
));
742 pull_ucs2_fstring(dom_name
, pass
->uni_name
);
743 DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
744 idx
, dom_name
, sid_string_static(&pass
->domain_sid
)));
746 SAFE_FREE(secrets_key
);
748 if (idx
>= start_idx
&& idx
< start_idx
+ max_num_domains
) {
749 dom
= TALLOC_ZERO_P(ctx
, TRUSTDOM
);
751 /* free returned tdb record */
752 return NT_STATUS_NO_MEMORY
;
755 /* copy domain sid */
756 SMB_ASSERT(sizeof(dom
->sid
) == sizeof(pass
->domain_sid
));
757 memcpy(&(dom
->sid
), &(pass
->domain_sid
), sizeof(dom
->sid
));
759 /* copy unicode domain name */
760 dom
->name
= TALLOC_MEMDUP(ctx
, pass
->uni_name
,
761 (strlen_w(pass
->uni_name
) + 1) * sizeof(smb_ucs2_t
));
763 (*domains
)[idx
- start_idx
] = dom
;
765 DEBUG(18, ("Secret record is in required range.\n \
766 start_idx = %d, max_num_domains = %d. Added to returned array.\n",
767 start_idx
, max_num_domains
));
772 /* set proper status code to return */
774 /* there are yet some entries to enumerate */
775 status
= STATUS_MORE_ENTRIES
;
777 /* this is the last entry in the whole enumeration */
778 status
= NT_STATUS_OK
;
781 DEBUG(18, ("Secret is outside the required range.\n \
782 start_idx = %d, max_num_domains = %d. Not added to returned array\n",
783 start_idx
, max_num_domains
));
789 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains
));
791 /* free the results of searching the keys */
792 tdb_search_list_free(keys
);
797 /*******************************************************************************
798 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
799 between smbd instances.
800 *******************************************************************************/
802 BOOL
secrets_named_mutex(const char *name
, unsigned int timeout
)
809 ret
= tdb_lock_bystring(tdb
, name
, timeout
);
811 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name
));
816 /*******************************************************************************
817 Unlock a named mutex.
818 *******************************************************************************/
820 void secrets_named_mutex_release(const char *name
)
822 tdb_unlock_bystring(tdb
, name
);
823 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name
));
826 /*********************************************************
827 Check to see if we must talk to the PDC to avoid sam
829 ********************************************************/
831 BOOL
must_use_pdc( const char *domain
)
833 time_t now
= time(NULL
);
834 time_t last_change_time
;
835 unsigned char passwd
[16];
837 if ( !secrets_fetch_trust_account_password(domain
, passwd
, &last_change_time
, NULL
) )
841 * If the time the machine password has changed
842 * was less than about 15 minutes then we need to contact
843 * the PDC only, as we cannot be sure domain replication
844 * has yet taken place. Bug found by Gerald (way to go
848 if ( now
- last_change_time
< SAM_SYNC_WINDOW
)
855 /*******************************************************************************
856 Store a complete AFS keyfile into secrets.tdb.
857 *******************************************************************************/
859 BOOL
secrets_store_afs_keyfile(const char *cell
, const struct afs_keyfile
*keyfile
)
863 if ((cell
== NULL
) || (keyfile
== NULL
))
866 if (ntohl(keyfile
->nkeys
) > SECRETS_AFS_MAXKEYS
)
869 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
870 return secrets_store(key
, keyfile
, sizeof(struct afs_keyfile
));
873 /*******************************************************************************
874 Fetch the current (highest) AFS key from secrets.tdb
875 *******************************************************************************/
876 BOOL
secrets_fetch_afs_key(const char *cell
, struct afs_key
*result
)
879 struct afs_keyfile
*keyfile
;
883 slprintf(key
, sizeof(key
)-1, "%s/%s", SECRETS_AFS_KEYFILE
, cell
);
885 keyfile
= (struct afs_keyfile
*)secrets_fetch(key
, &size
);
890 if (size
!= sizeof(struct afs_keyfile
)) {
895 i
= ntohl(keyfile
->nkeys
);
897 if (i
> SECRETS_AFS_MAXKEYS
) {
902 *result
= keyfile
->entry
[i
-1];
904 result
->kvno
= ntohl(result
->kvno
);
909 /******************************************************************************
910 When kerberos is not available, choose between anonymous or
911 authenticated connections.
913 We need to use an authenticated connection if DCs have the
914 RestrictAnonymous registry entry set > 0, or the "Additional
915 restrictions for anonymous connections" set in the win2k Local
918 Caller to free() result in domain, username, password
919 *******************************************************************************/
920 void secrets_fetch_ipc_userpass(char **username
, char **domain
, char **password
)
922 *username
= secrets_fetch(SECRETS_AUTH_USER
, NULL
);
923 *domain
= secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
924 *password
= secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
926 if (*username
&& **username
) {
928 if (!*domain
|| !**domain
)
929 *domain
= smb_xstrdup(lp_workgroup());
931 if (!*password
|| !**password
)
932 *password
= smb_xstrdup("");
934 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
935 *domain
, *username
));
938 DEBUG(3, ("IPC$ connections done anonymously\n"));
939 *username
= smb_xstrdup("");
940 *domain
= smb_xstrdup("");
941 *password
= smb_xstrdup("");
945 /******************************************************************************
946 Open or create the schannel session store tdb.
947 *******************************************************************************/
949 static TDB_CONTEXT
*open_schannel_session_store(TALLOC_CTX
*mem_ctx
)
953 TDB_CONTEXT
*tdb_sc
= NULL
;
954 char *fname
= talloc_asprintf(mem_ctx
, "%s/schannel_store.tdb", lp_private_dir());
960 tdb_sc
= tdb_open_log(fname
, 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
963 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname
));
968 vers
= tdb_fetch_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION");
969 if (vers
.dptr
== NULL
) {
970 /* First opener, no version. */
972 vers
.dptr
= (char *)&ver
;
974 tdb_store_bystring(tdb_sc
, "SCHANNEL_STORE_VERSION", vers
, TDB_REPLACE
);
976 } else if (vers
.dsize
== 4) {
977 ver
= IVAL(vers
.dptr
,0);
981 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
987 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
988 (int)vers
.dsize
, fname
));
991 SAFE_FREE(vers
.dptr
);
997 /******************************************************************************
998 Store the schannel state after an AUTH2 call.
999 Note we must be root here.
1000 *******************************************************************************/
1002 BOOL
secrets_store_schannel_session_info(TALLOC_CTX
*mem_ctx
, const struct dcinfo
*pdc
)
1004 TDB_CONTEXT
*tdb_sc
= NULL
;
1007 char *keystr
= talloc_asprintf(mem_ctx
, "%s/%s", SECRETS_SCHANNEL_STATE
,
1008 pdc
->remote_machine
);
1015 /* Work out how large the record is. */
1016 value
.dsize
= tdb_pack(NULL
, 0, "dBBBBBfff",
1018 8, pdc
->seed_chal
.data
,
1019 8, pdc
->clnt_chal
.data
,
1020 8, pdc
->srv_chal
.data
,
1024 pdc
->remote_machine
,
1027 value
.dptr
= TALLOC(mem_ctx
, value
.dsize
);
1029 talloc_free(keystr
);
1033 value
.dsize
= tdb_pack(value
.dptr
, value
.dsize
, "dBBBBBfff",
1035 8, pdc
->seed_chal
.data
,
1036 8, pdc
->clnt_chal
.data
,
1037 8, pdc
->srv_chal
.data
,
1041 pdc
->remote_machine
,
1044 tdb_sc
= open_schannel_session_store(mem_ctx
);
1046 talloc_free(keystr
);
1047 talloc_free(value
.dptr
);
1051 ret
= (tdb_store_bystring(tdb_sc
, keystr
, value
, TDB_REPLACE
) == 0 ? True
: False
);
1053 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1057 talloc_free(keystr
);
1058 talloc_free(value
.dptr
);
1062 /******************************************************************************
1063 Restore the schannel state on a client reconnect.
1064 Note we must be root here.
1065 *******************************************************************************/
1067 BOOL
secrets_restore_schannel_session_info(TALLOC_CTX
*mem_ctx
,
1068 const char *remote_machine
,
1071 TDB_CONTEXT
*tdb_sc
= NULL
;
1073 unsigned char *pseed_chal
= NULL
;
1074 unsigned char *pclnt_chal
= NULL
;
1075 unsigned char *psrv_chal
= NULL
;
1076 unsigned char *psess_key
= NULL
;
1077 unsigned char *pmach_pw
= NULL
;
1078 uint32 l1
, l2
, l3
, l4
, l5
;
1080 char *keystr
= talloc_asprintf(mem_ctx
, "%s/%s", SECRETS_SCHANNEL_STATE
,
1091 tdb_sc
= open_schannel_session_store(mem_ctx
);
1093 talloc_free(keystr
);
1097 value
= tdb_fetch_bystring(tdb_sc
, keystr
);
1099 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1107 /* Retrieve the record. */
1108 ret
= tdb_unpack(value
.dptr
, value
.dsize
, "dBBBBBfff",
1116 &pdc
->remote_machine
,
1119 if (ret
== -1 || l1
!= 8 || l2
!= 8 || l3
!= 8 || l4
!= 8 || l5
!= 16) {
1120 talloc_free(keystr
);
1121 SAFE_FREE(pseed_chal
);
1122 SAFE_FREE(pclnt_chal
);
1123 SAFE_FREE(psrv_chal
);
1124 SAFE_FREE(psess_key
);
1125 SAFE_FREE(pmach_pw
);
1126 SAFE_FREE(value
.dptr
);
1131 memcpy(pdc
->seed_chal
.data
, pseed_chal
, 8);
1132 memcpy(pdc
->clnt_chal
.data
, pclnt_chal
, 8);
1133 memcpy(pdc
->srv_chal
.data
, psrv_chal
, 8);
1134 memcpy(pdc
->sess_key
, psess_key
, 8);
1135 memcpy(pdc
->mach_pw
, pmach_pw
, 16);
1137 /* We know these are true so didn't bother to store them. */
1138 pdc
->challenge_sent
= True
;
1139 pdc
->authenticated
= True
;
1141 DEBUG(3,("secrets_store_schannel_session_info: restored schannel info key %s\n",
1144 SAFE_FREE(pseed_chal
);
1145 SAFE_FREE(pclnt_chal
);
1146 SAFE_FREE(psrv_chal
);
1147 SAFE_FREE(psess_key
);
1148 SAFE_FREE(pmach_pw
);
1150 talloc_free(keystr
);
1151 SAFE_FREE(value
.dptr
);