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_trans(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));
95 void secrets_shutdown(void)
100 /* read a entry from the secrets database - the caller must free the result
101 if size is non-null then the size of the entry is put in there
103 void *secrets_fetch(const char *key, size_t *size)
108 if (!secrets_init()) {
112 if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
117 result = memdup(dbuf.dptr, dbuf.dsize);
118 if (result == NULL) {
121 TALLOC_FREE(dbuf.dptr);
130 /* store a secrets entry
132 bool secrets_store(const char *key, const void *data, size_t size)
134 if (!secrets_init()) {
138 return dbwrap_trans_store(db_ctx, string_tdb_data(key),
139 make_tdb_data((const uint8 *)data, size),
144 /* delete a secets database entry
146 bool secrets_delete(const char *key)
148 if (!secrets_init()) {
152 return dbwrap_trans_delete(db_ctx, string_tdb_data(key)) == 0;
156 * Form a key for fetching the domain sid
158 * @param domain domain name
162 static const char *domain_sid_keystr(const char *domain)
166 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
167 SECRETS_DOMAIN_SID, domain);
168 SMB_ASSERT(keystr != NULL);
172 bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
176 ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
178 /* Force a re-query, in case we modified our domain */
180 reset_global_sam_sid();
184 bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
189 dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
194 if (size != sizeof(DOM_SID)) {
204 bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
208 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
210 return secrets_store(key, guid, sizeof(struct GUID));
213 bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
215 struct GUID *dyn_guid;
218 struct GUID new_guid;
220 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
222 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
225 if (lp_server_role() == ROLE_DOMAIN_PDC) {
226 smb_uuid_generate_random(&new_guid);
227 if (!secrets_store_domain_guid(domain, &new_guid))
229 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
231 if (dyn_guid == NULL) {
236 if (size != sizeof(struct GUID)) {
237 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
248 * Form a key for fetching the machine trust account sec channel type
250 * @param domain domain name
254 static const char *machine_sec_channel_type_keystr(const char *domain)
258 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
259 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
261 SMB_ASSERT(keystr != NULL);
266 * Form a key for fetching the machine trust account last change time
268 * @param domain domain name
272 static const char *machine_last_change_time_keystr(const char *domain)
276 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
277 SECRETS_MACHINE_LAST_CHANGE_TIME,
279 SMB_ASSERT(keystr != NULL);
285 * Form a key for fetching the machine trust account password
287 * @param domain domain name
291 static const char *machine_password_keystr(const char *domain)
295 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
296 SECRETS_MACHINE_PASSWORD, domain);
297 SMB_ASSERT(keystr != NULL);
302 * Form a key for fetching the machine trust account password
304 * @param domain domain name
306 * @return stored password's key
308 static const char *trust_keystr(const char *domain)
312 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
313 SECRETS_MACHINE_ACCT_PASS, domain);
314 SMB_ASSERT(keystr != NULL);
319 * Form a key for fetching a trusted domain password
321 * @param domain trusted domain name
323 * @return stored password's key
325 static char *trustdom_keystr(const char *domain)
329 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
330 SECRETS_DOMTRUST_ACCT_PASS,
332 SMB_ASSERT(keystr != NULL);
336 /************************************************************************
337 Lock the trust password entry.
338 ************************************************************************/
340 void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
342 if (!secrets_init()) {
346 return db_ctx->fetch_locked(
347 db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
350 /************************************************************************
351 Routine to get the default secure channel type for trust accounts
352 ************************************************************************/
354 uint32 get_default_sec_channel(void)
356 if (lp_server_role() == ROLE_DOMAIN_BDC ||
357 lp_server_role() == ROLE_DOMAIN_PDC) {
360 return SEC_CHAN_WKSTA;
364 /************************************************************************
365 Routine to get the trust account password for a domain.
366 This only tries to get the legacy hashed version of the password.
367 The user of this function must have locked the trust password file using
368 the above secrets_lock_trust_account_password().
369 ************************************************************************/
371 bool secrets_fetch_trust_account_password_legacy(const char *domain,
373 time_t *pass_last_set_time,
376 struct machine_acct_pass *pass;
379 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
380 trust_keystr(domain), &size))) {
381 DEBUG(5, ("secrets_fetch failed!\n"));
385 if (size != sizeof(*pass)) {
386 DEBUG(0, ("secrets were of incorrect size!\n"));
390 if (pass_last_set_time) {
391 *pass_last_set_time = pass->mod_time;
393 memcpy(ret_pwd, pass->hash, 16);
396 *channel = get_default_sec_channel();
399 /* Test if machine password has expired and needs to be changed */
400 if (lp_machine_password_timeout()) {
401 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
402 (time_t)lp_machine_password_timeout())) {
403 global_machine_password_needs_changing = True;
411 /************************************************************************
412 Routine to get the trust account password for a domain.
413 The user of this function must have locked the trust password file using
414 the above secrets_lock_trust_account_password().
415 ************************************************************************/
417 bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
418 time_t *pass_last_set_time,
423 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
426 DEBUG(4,("Using cleartext machine password\n"));
427 E_md4hash(plaintext, ret_pwd);
428 SAFE_FREE(plaintext);
432 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
438 * Pack SID passed by pointer
440 * @param pack_buf pointer to buffer which is to be filled with packed data
441 * @param bufsize size of packing buffer
442 * @param sid pointer to sid to be packed
444 * @return length of the packed representation of the whole structure
446 static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
451 int remaining_space = pack_buf ? bufsize : 0;
457 len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
461 remaining_space = bufsize - len;
464 for (idx = 0; idx < 6; idx++) {
465 len += tdb_pack(p, remaining_space, "b",
469 remaining_space = bufsize - len;
473 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
474 len += tdb_pack(p, remaining_space, "d",
475 sid->sub_auths[idx]);
478 remaining_space = bufsize - len;
486 * Unpack SID into a pointer
488 * @param pack_buf pointer to buffer with packed representation
489 * @param bufsize size of the buffer
490 * @param sid pointer to sid structure to be filled with unpacked data
492 * @return size of structure unpacked from buffer
494 static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
498 if (!sid || !pack_buf) return -1;
500 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
501 &sid->sid_rev_num, &sid->num_auths);
503 for (idx = 0; idx < 6; idx++) {
504 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
508 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
509 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
510 &sid->sub_auths[idx]);
517 * Pack TRUSTED_DOM_PASS passed by pointer
519 * @param pack_buf pointer to buffer which is to be filled with packed data
520 * @param bufsize size of the buffer
521 * @param pass pointer to trusted domain password to be packed
523 * @return length of the packed representation of the whole structure
525 static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
526 TRUSTED_DOM_PASS* pass)
530 int remaining_space = pack_buf ? bufsize : 0;
536 /* packing unicode domain name and password */
537 len += tdb_pack(p, remaining_space, "d",
541 remaining_space = bufsize - len;
544 for (idx = 0; idx < 32; idx++) {
545 len += tdb_pack(p, remaining_space, "w",
546 pass->uni_name[idx]);
549 remaining_space = bufsize - len;
553 len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
554 pass->pass, pass->mod_time);
557 remaining_space = bufsize - len;
560 /* packing SID structure */
561 len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
564 remaining_space = bufsize - len;
572 * Unpack TRUSTED_DOM_PASS passed by pointer
574 * @param pack_buf pointer to buffer with packed representation
575 * @param bufsize size of the buffer
576 * @param pass pointer to trusted domain password to be filled with unpacked data
578 * @return size of structure unpacked from buffer
580 static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
581 TRUSTED_DOM_PASS* pass)
586 if (!pack_buf || !pass) return -1;
588 /* unpack unicode domain name and plaintext password */
589 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
591 for (idx = 0; idx < 32; idx++)
592 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
593 &pass->uni_name[idx]);
595 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
596 &pass->pass_len, &passp, &pass->mod_time);
598 fstrcpy(pass->pass, passp);
602 /* unpack domain sid */
603 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
609 /************************************************************************
610 Routine to get account password to trusted domain
611 ************************************************************************/
613 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
614 DOM_SID *sid, time_t *pass_last_set_time)
616 struct trusted_dom_pass pass;
619 /* unpacking structures */
625 /* fetching trusted domain password structure */
626 if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
628 DEBUG(5, ("secrets_fetch failed!\n"));
632 /* unpack trusted domain password */
633 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
636 if (pass_len != size) {
637 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
641 /* the trust's password */
643 *pwd = SMB_STRDUP(pass.pass);
649 /* last change time */
650 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
653 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
659 * Routine to store the password for trusted domain
661 * @param domain remote domain name
662 * @param pwd plain text password of trust relationship
663 * @param sid remote domain sid
665 * @return true if succeeded
668 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
671 smb_ucs2_t *uni_dom_name;
674 /* packing structures */
675 uint8 *pass_buf = NULL;
678 struct trusted_dom_pass pass;
681 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
682 DEBUG(0, ("Could not convert domain name %s to unicode\n",
687 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
688 pass.uni_name_len = strlen_w(uni_dom_name)+1;
689 SAFE_FREE(uni_dom_name);
691 /* last change time */
692 pass.mod_time = time(NULL);
694 /* password of the trust */
695 pass.pass_len = strlen(pwd);
696 fstrcpy(pass.pass, pwd);
699 sid_copy(&pass.domain_sid, sid);
701 /* Calculate the length. */
702 pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
703 pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
707 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
708 ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
714 /************************************************************************
715 Routine to delete the plaintext machine account password
716 ************************************************************************/
718 bool secrets_delete_machine_password(const char *domain)
720 return secrets_delete(machine_password_keystr(domain));
723 /************************************************************************
724 Routine to delete the plaintext machine account password, sec channel type and
725 last change time from secrets database
726 ************************************************************************/
728 bool secrets_delete_machine_password_ex(const char *domain)
730 if (!secrets_delete(machine_password_keystr(domain))) {
733 if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
736 return secrets_delete(machine_last_change_time_keystr(domain));
739 /************************************************************************
740 Routine to delete the domain sid
741 ************************************************************************/
743 bool secrets_delete_domain_sid(const char *domain)
745 return secrets_delete(domain_sid_keystr(domain));
748 /************************************************************************
749 Routine to set the plaintext machine account password for a realm
750 the password is assumed to be a null terminated ascii string
751 ************************************************************************/
753 bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
756 uint32 last_change_time;
757 uint32 sec_channel_type;
759 ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
763 SIVAL(&last_change_time, 0, time(NULL));
764 ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
766 SIVAL(&sec_channel_type, 0, sec_channel);
767 ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
772 /************************************************************************
773 Routine to fetch the plaintext machine account password for a realm
774 the password is assumed to be a null terminated ascii string.
775 ************************************************************************/
777 char *secrets_fetch_machine_password(const char *domain,
778 time_t *pass_last_set_time,
782 ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
784 if (pass_last_set_time) {
786 uint32 *last_set_time;
787 last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
789 *pass_last_set_time = IVAL(last_set_time,0);
790 SAFE_FREE(last_set_time);
792 *pass_last_set_time = 0;
798 uint32 *channel_type;
799 channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
801 *channel = IVAL(channel_type,0);
802 SAFE_FREE(channel_type);
804 *channel = get_default_sec_channel();
811 /************************************************************************
812 Routine to delete the password for trusted domain
813 ************************************************************************/
815 bool trusted_domain_password_delete(const char *domain)
817 return secrets_delete(trustdom_keystr(domain));
820 bool secrets_store_ldap_pw(const char* dn, char* pw)
825 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
826 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
830 ret = secrets_store(key, pw, strlen(pw)+1);
836 /*******************************************************************
837 Find the ldap password.
838 ******************************************************************/
840 bool fetch_ldap_pw(char **dn, char** pw)
845 *dn = smb_xstrdup(lp_ldap_admin_dn());
847 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
849 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
852 *pw=(char *)secrets_fetch(key, &size);
856 /* Upgrade 2.2 style entry */
858 char* old_style_key = SMB_STRDUP(*dn);
860 fstring old_style_pw;
862 if (!old_style_key) {
863 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
867 for (p=old_style_key; *p; p++)
868 if (*p == ',') *p = '/';
870 data=(char *)secrets_fetch(old_style_key, &size);
871 if (!size && size < sizeof(old_style_pw)) {
872 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
873 SAFE_FREE(old_style_key);
878 size = MIN(size, sizeof(fstring)-1);
879 strncpy(old_style_pw, data, size);
880 old_style_pw[size] = 0;
884 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
885 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
886 SAFE_FREE(old_style_key);
890 if (!secrets_delete(old_style_key)) {
891 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
894 SAFE_FREE(old_style_key);
896 *pw = smb_xstrdup(old_style_pw);
903 * Get trusted domains info from secrets.tdb.
906 struct list_trusted_domains_state {
908 struct trustdom_info **domains;
911 static int list_trusted_domain(struct db_record *rec, void *private_data)
913 const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
914 size_t packed_size = 0;
915 struct trusted_dom_pass pass;
916 struct trustdom_info *dom_info;
918 struct list_trusted_domains_state *state =
919 (struct list_trusted_domains_state *)private_data;
921 if ((rec->key.dsize < prefix_len)
922 || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
927 packed_size = tdb_trusted_dom_pass_unpack(
928 rec->value.dptr, rec->value.dsize, &pass);
930 if (rec->value.dsize != packed_size) {
931 DEBUG(2, ("Secrets record is invalid!\n"));
935 if (pass.domain_sid.num_auths != 4) {
936 DEBUG(0, ("SID %s is not a domain sid, has %d "
937 "auths instead of 4\n",
938 sid_string_dbg(&pass.domain_sid),
939 pass.domain_sid.num_auths));
943 if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
944 DEBUG(0, ("talloc failed\n"));
948 if (pull_ucs2_talloc(dom_info, &dom_info->name,
949 pass.uni_name) == (size_t)-1) {
950 DEBUG(2, ("pull_ucs2_talloc failed\n"));
951 TALLOC_FREE(dom_info);
955 sid_copy(&dom_info->sid, &pass.domain_sid);
957 ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
958 &state->domains, &state->num_domains);
960 if (state->domains == NULL) {
961 state->num_domains = 0;
967 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
968 struct trustdom_info ***domains)
970 struct list_trusted_domains_state state;
974 if (db_ctx == NULL) {
975 return NT_STATUS_ACCESS_DENIED;
978 state.num_domains = 0;
981 * Make sure that a talloc context for the trustdom_info structs
985 if (!(state.domains = TALLOC_ARRAY(
986 mem_ctx, struct trustdom_info *, 1))) {
987 return NT_STATUS_NO_MEMORY;
990 db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
992 *num_domains = state.num_domains;
993 *domains = state.domains;
997 /*******************************************************************************
998 Store a complete AFS keyfile into secrets.tdb.
999 *******************************************************************************/
1001 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1005 if ((cell == NULL) || (keyfile == NULL))
1008 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1011 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1012 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1015 /*******************************************************************************
1016 Fetch the current (highest) AFS key from secrets.tdb
1017 *******************************************************************************/
1018 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1021 struct afs_keyfile *keyfile;
1025 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1027 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1029 if (keyfile == NULL)
1032 if (size != sizeof(struct afs_keyfile)) {
1037 i = ntohl(keyfile->nkeys);
1039 if (i > SECRETS_AFS_MAXKEYS) {
1044 *result = keyfile->entry[i-1];
1046 result->kvno = ntohl(result->kvno);
1051 /******************************************************************************
1052 When kerberos is not available, choose between anonymous or
1053 authenticated connections.
1055 We need to use an authenticated connection if DCs have the
1056 RestrictAnonymous registry entry set > 0, or the "Additional
1057 restrictions for anonymous connections" set in the win2k Local
1060 Caller to free() result in domain, username, password
1061 *******************************************************************************/
1062 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1064 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1065 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1066 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1068 if (*username && **username) {
1070 if (!*domain || !**domain)
1071 *domain = smb_xstrdup(lp_workgroup());
1073 if (!*password || !**password)
1074 *password = smb_xstrdup("");
1076 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1077 *domain, *username));
1080 DEBUG(3, ("IPC$ connections done anonymously\n"));
1081 *username = smb_xstrdup("");
1082 *domain = smb_xstrdup("");
1083 *password = smb_xstrdup("");
1087 /******************************************************************************
1088 Open or create the schannel session store tdb.
1089 *******************************************************************************/
1091 static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1095 TDB_CONTEXT *tdb_sc = NULL;
1096 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1102 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1105 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1110 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1111 if (vers.dptr == NULL) {
1112 /* First opener, no version. */
1114 vers.dptr = (uint8 *)&ver;
1116 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1118 } else if (vers.dsize == 4) {
1119 ver = IVAL(vers.dptr,0);
1123 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1129 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1130 (int)vers.dsize, fname ));
1133 SAFE_FREE(vers.dptr);
1139 /******************************************************************************
1140 Store the schannel state after an AUTH2 call.
1141 Note we must be root here.
1142 *******************************************************************************/
1144 bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1145 const char *remote_machine,
1146 const struct dcinfo *pdc)
1148 TDB_CONTEXT *tdb_sc = NULL;
1151 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1152 SECRETS_SCHANNEL_STATE,
1158 /* Work out how large the record is. */
1159 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1161 8, pdc->seed_chal.data,
1162 8, pdc->clnt_chal.data,
1163 8, pdc->srv_chal.data,
1167 pdc->remote_machine,
1170 value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
1172 TALLOC_FREE(keystr);
1176 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1178 8, pdc->seed_chal.data,
1179 8, pdc->clnt_chal.data,
1180 8, pdc->srv_chal.data,
1184 pdc->remote_machine,
1187 tdb_sc = open_schannel_session_store(mem_ctx);
1189 TALLOC_FREE(keystr);
1190 TALLOC_FREE(value.dptr);
1194 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1196 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1200 TALLOC_FREE(keystr);
1201 TALLOC_FREE(value.dptr);
1205 /******************************************************************************
1206 Restore the schannel state on a client reconnect.
1207 Note we must be root here.
1208 *******************************************************************************/
1210 bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1211 const char *remote_machine,
1212 struct dcinfo **ppdc)
1214 TDB_CONTEXT *tdb_sc = NULL;
1216 unsigned char *pseed_chal = NULL;
1217 unsigned char *pclnt_chal = NULL;
1218 unsigned char *psrv_chal = NULL;
1219 unsigned char *psess_key = NULL;
1220 unsigned char *pmach_pw = NULL;
1221 uint32 l1, l2, l3, l4, l5;
1223 struct dcinfo *pdc = NULL;
1224 char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
1225 SECRETS_SCHANNEL_STATE,
1234 tdb_sc = open_schannel_session_store(mem_ctx);
1236 TALLOC_FREE(keystr);
1240 value = tdb_fetch_bystring(tdb_sc, keystr);
1242 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1248 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1250 /* Retrieve the record. */
1251 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1259 &pdc->remote_machine,
1262 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1263 /* Bad record - delete it. */
1264 tdb_delete_bystring(tdb_sc, keystr);
1266 TALLOC_FREE(keystr);
1268 SAFE_FREE(pseed_chal);
1269 SAFE_FREE(pclnt_chal);
1270 SAFE_FREE(psrv_chal);
1271 SAFE_FREE(psess_key);
1272 SAFE_FREE(pmach_pw);
1273 SAFE_FREE(value.dptr);
1279 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1280 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1281 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1282 memcpy(pdc->sess_key, psess_key, 16);
1283 memcpy(pdc->mach_pw, pmach_pw, 16);
1285 /* We know these are true so didn't bother to store them. */
1286 pdc->challenge_sent = True;
1287 pdc->authenticated = True;
1289 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1292 SAFE_FREE(pseed_chal);
1293 SAFE_FREE(pclnt_chal);
1294 SAFE_FREE(psrv_chal);
1295 SAFE_FREE(psess_key);
1296 SAFE_FREE(pmach_pw);
1298 TALLOC_FREE(keystr);
1299 SAFE_FREE(value.dptr);
1306 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1308 char *tdbkey = NULL;
1311 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1312 DEBUG(0, ("asprintf failed!\n"));
1316 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1322 /*******************************************************************
1323 Find the ldap password.
1324 ******************************************************************/
1326 char *secrets_fetch_generic(const char *owner, const char *key)
1328 char *secret = NULL;
1329 char *tdbkey = NULL;
1331 if (( ! owner) || ( ! key)) {
1332 DEBUG(1, ("Invalid Paramters"));
1336 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1337 DEBUG(0, ("Out of memory!\n"));
1341 secret = (char *)secrets_fetch(tdbkey, NULL);