• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/passdb/
1/*
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
7
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.
12
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.
17
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/>.
20*/
21
22/* the Samba secrets database stores any generated, private information
23   such as the local SID and machine trust password */
24
25#include "includes.h"
26#include "../libcli/auth/libcli_auth.h"
27#include "librpc/gen_ndr/ndr_secrets.h"
28
29#undef DBGC_CLASS
30#define DBGC_CLASS DBGC_PASSDB
31
32static struct db_context *db_ctx;
33
34/* Urrrg. global.... */
35bool global_machine_password_needs_changing;
36
37/**
38 * Use a TDB to store an incrementing random seed.
39 *
40 * Initialised to the current pid, the very first time Samba starts,
41 * and incremented by one each time it is needed.
42 *
43 * @note Not called by systems with a working /dev/urandom.
44 */
45static void get_rand_seed(void *userdata, int *new_seed)
46{
47	*new_seed = sys_getpid();
48	if (db_ctx) {
49		dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed",
50						 new_seed, 1);
51	}
52}
53
54/* open up the secrets database */
55bool secrets_init(void)
56{
57	char *fname = NULL;
58	unsigned char dummy;
59
60	if (db_ctx != NULL)
61		return True;
62
63	fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
64				lp_private_dir());
65	if (fname == NULL) {
66		return false;
67	}
68
69	db_ctx = db_open(NULL, fname, 0,
70			 TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
71
72	if (db_ctx == NULL) {
73		DEBUG(0,("Failed to open %s\n", fname));
74		TALLOC_FREE(fname);
75		return False;
76	}
77
78	TALLOC_FREE(fname);
79
80	/**
81	 * Set a reseed function for the crypto random generator
82	 *
83	 * This avoids a problem where systems without /dev/urandom
84	 * could send the same challenge to multiple clients
85	 */
86	set_rand_reseed_callback(get_rand_seed, NULL);
87
88	/* Ensure that the reseed is done now, while we are root, etc */
89	generate_random_buffer(&dummy, sizeof(dummy));
90
91	return True;
92}
93
94struct db_context *secrets_db_ctx(void)
95{
96	if (!secrets_init()) {
97		return NULL;
98	}
99
100	return db_ctx;
101}
102
103/*
104 * close secrets.tdb
105 */
106void secrets_shutdown(void)
107{
108	TALLOC_FREE(db_ctx);
109}
110
111/* read a entry from the secrets database - the caller must free the result
112   if size is non-null then the size of the entry is put in there
113 */
114void *secrets_fetch(const char *key, size_t *size)
115{
116	TDB_DATA dbuf;
117	void *result;
118
119	if (!secrets_init()) {
120		return NULL;
121	}
122
123	if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
124			  &dbuf) != 0) {
125		return NULL;
126	}
127
128	result = memdup(dbuf.dptr, dbuf.dsize);
129	if (result == NULL) {
130		return NULL;
131	}
132	TALLOC_FREE(dbuf.dptr);
133
134	if (size) {
135		*size = dbuf.dsize;
136	}
137
138	return result;
139}
140
141/* store a secrets entry
142 */
143bool secrets_store(const char *key, const void *data, size_t size)
144{
145	NTSTATUS status;
146
147	if (!secrets_init()) {
148		return false;
149	}
150
151	status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
152				    make_tdb_data((const uint8 *)data, size),
153				    TDB_REPLACE);
154	return NT_STATUS_IS_OK(status);
155}
156
157
158/* delete a secets database entry
159 */
160bool secrets_delete(const char *key)
161{
162	NTSTATUS status;
163	if (!secrets_init()) {
164		return false;
165	}
166
167	status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
168
169	return NT_STATUS_IS_OK(status);
170}
171
172/**
173 * Form a key for fetching the domain sid
174 *
175 * @param domain domain name
176 *
177 * @return keystring
178 **/
179static const char *domain_sid_keystr(const char *domain)
180{
181	char *keystr;
182
183	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
184					    SECRETS_DOMAIN_SID, domain);
185	SMB_ASSERT(keystr != NULL);
186	return keystr;
187}
188
189bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
190{
191	bool ret;
192
193	ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
194
195	/* Force a re-query, in case we modified our domain */
196	if (ret)
197		reset_global_sam_sid();
198	return ret;
199}
200
201bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
202{
203	DOM_SID *dyn_sid;
204	size_t size = 0;
205
206	dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
207
208	if (dyn_sid == NULL)
209		return False;
210
211	if (size != sizeof(DOM_SID)) {
212		SAFE_FREE(dyn_sid);
213		return False;
214	}
215
216	*sid = *dyn_sid;
217	SAFE_FREE(dyn_sid);
218	return True;
219}
220
221bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
222{
223	fstring key;
224
225	slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
226	strupper_m(key);
227	return secrets_store(key, guid, sizeof(struct GUID));
228}
229
230bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
231{
232	struct GUID *dyn_guid;
233	fstring key;
234	size_t size = 0;
235	struct GUID new_guid;
236
237	slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
238	strupper_m(key);
239	dyn_guid = (struct GUID *)secrets_fetch(key, &size);
240
241	if (!dyn_guid) {
242		if (lp_server_role() == ROLE_DOMAIN_PDC) {
243			new_guid = GUID_random();
244			if (!secrets_store_domain_guid(domain, &new_guid))
245				return False;
246			dyn_guid = (struct GUID *)secrets_fetch(key, &size);
247		}
248		if (dyn_guid == NULL) {
249			return False;
250		}
251	}
252
253	if (size != sizeof(struct GUID)) {
254		DEBUG(1,("UUID size %d is wrong!\n", (int)size));
255		SAFE_FREE(dyn_guid);
256		return False;
257	}
258
259	*guid = *dyn_guid;
260	SAFE_FREE(dyn_guid);
261	return True;
262}
263
264bool secrets_store_local_schannel_key(uint8_t schannel_key[16])
265{
266	return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16);
267}
268
269bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16])
270{
271	size_t size = 0;
272	uint8_t *key;
273
274	key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size);
275	if (key == NULL) {
276		return false;
277	}
278
279	if (size != 16) {
280		SAFE_FREE(key);
281		return false;
282	}
283
284	memcpy(schannel_key, key, 16);
285	SAFE_FREE(key);
286	return true;
287}
288
289/**
290 * Form a key for fetching the machine trust account sec channel type
291 *
292 * @param domain domain name
293 *
294 * @return keystring
295 **/
296static const char *machine_sec_channel_type_keystr(const char *domain)
297{
298	char *keystr;
299
300	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
301					    SECRETS_MACHINE_SEC_CHANNEL_TYPE,
302					    domain);
303	SMB_ASSERT(keystr != NULL);
304	return keystr;
305}
306
307/**
308 * Form a key for fetching the machine trust account last change time
309 *
310 * @param domain domain name
311 *
312 * @return keystring
313 **/
314static const char *machine_last_change_time_keystr(const char *domain)
315{
316	char *keystr;
317
318	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
319					    SECRETS_MACHINE_LAST_CHANGE_TIME,
320					    domain);
321	SMB_ASSERT(keystr != NULL);
322	return keystr;
323}
324
325
326/**
327 * Form a key for fetching the machine previous trust account password
328 *
329 * @param domain domain name
330 *
331 * @return keystring
332 **/
333static const char *machine_prev_password_keystr(const char *domain)
334{
335	char *keystr;
336
337	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
338					    SECRETS_MACHINE_PASSWORD_PREV, domain);
339	SMB_ASSERT(keystr != NULL);
340	return keystr;
341}
342
343/**
344 * Form a key for fetching the machine trust account password
345 *
346 * @param domain domain name
347 *
348 * @return keystring
349 **/
350static const char *machine_password_keystr(const char *domain)
351{
352	char *keystr;
353
354	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
355					    SECRETS_MACHINE_PASSWORD, domain);
356	SMB_ASSERT(keystr != NULL);
357	return keystr;
358}
359
360/**
361 * Form a key for fetching the machine trust account password
362 *
363 * @param domain domain name
364 *
365 * @return stored password's key
366 **/
367static const char *trust_keystr(const char *domain)
368{
369	char *keystr;
370
371	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
372					    SECRETS_MACHINE_ACCT_PASS, domain);
373	SMB_ASSERT(keystr != NULL);
374	return keystr;
375}
376
377/**
378 * Form a key for fetching a trusted domain password
379 *
380 * @param domain trusted domain name
381 *
382 * @return stored password's key
383 **/
384static char *trustdom_keystr(const char *domain)
385{
386	char *keystr;
387
388	keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
389					    SECRETS_DOMTRUST_ACCT_PASS,
390					    domain);
391	SMB_ASSERT(keystr != NULL);
392	return keystr;
393}
394
395/************************************************************************
396 Lock the trust password entry.
397************************************************************************/
398
399void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
400{
401	if (!secrets_init()) {
402		return NULL;
403	}
404
405	return db_ctx->fetch_locked(
406		db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
407}
408
409/************************************************************************
410 Routine to get the default secure channel type for trust accounts
411************************************************************************/
412
413enum netr_SchannelType get_default_sec_channel(void)
414{
415	if (lp_server_role() == ROLE_DOMAIN_BDC ||
416	    lp_server_role() == ROLE_DOMAIN_PDC) {
417		return SEC_CHAN_BDC;
418	} else {
419		return SEC_CHAN_WKSTA;
420	}
421}
422
423/************************************************************************
424 Routine to get the trust account password for a domain.
425 This only tries to get the legacy hashed version of the password.
426 The user of this function must have locked the trust password file using
427 the above secrets_lock_trust_account_password().
428************************************************************************/
429
430bool secrets_fetch_trust_account_password_legacy(const char *domain,
431						 uint8 ret_pwd[16],
432						 time_t *pass_last_set_time,
433						 enum netr_SchannelType *channel)
434{
435	struct machine_acct_pass *pass;
436	size_t size = 0;
437
438	if (!(pass = (struct machine_acct_pass *)secrets_fetch(
439		      trust_keystr(domain), &size))) {
440		DEBUG(5, ("secrets_fetch failed!\n"));
441		return False;
442	}
443
444	if (size != sizeof(*pass)) {
445		DEBUG(0, ("secrets were of incorrect size!\n"));
446		SAFE_FREE(pass);
447		return False;
448	}
449
450	if (pass_last_set_time) {
451		*pass_last_set_time = pass->mod_time;
452	}
453	memcpy(ret_pwd, pass->hash, 16);
454
455	if (channel) {
456		*channel = get_default_sec_channel();
457	}
458
459	/* Test if machine password has expired and needs to be changed */
460	if (lp_machine_password_timeout()) {
461		if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
462				(time_t)lp_machine_password_timeout())) {
463			global_machine_password_needs_changing = True;
464		}
465	}
466
467	SAFE_FREE(pass);
468	return True;
469}
470
471/************************************************************************
472 Routine to get the trust account password for a domain.
473 The user of this function must have locked the trust password file using
474 the above secrets_lock_trust_account_password().
475************************************************************************/
476
477bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
478					  time_t *pass_last_set_time,
479					  enum netr_SchannelType *channel)
480{
481	char *plaintext;
482
483	plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
484						   channel);
485	if (plaintext) {
486		DEBUG(4,("Using cleartext machine password\n"));
487		E_md4hash(plaintext, ret_pwd);
488		SAFE_FREE(plaintext);
489		return True;
490	}
491
492	return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
493							   pass_last_set_time,
494							   channel);
495}
496
497/************************************************************************
498 Routine to get account password to trusted domain
499************************************************************************/
500
501bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
502                                           DOM_SID *sid, time_t *pass_last_set_time)
503{
504	struct TRUSTED_DOM_PASS pass;
505	enum ndr_err_code ndr_err;
506
507	/* unpacking structures */
508	DATA_BLOB blob;
509
510	/* fetching trusted domain password structure */
511	if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
512						   &blob.length))) {
513		DEBUG(5, ("secrets_fetch failed!\n"));
514		return False;
515	}
516
517	/* unpack trusted domain password */
518	ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass,
519			(ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
520	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
521		return false;
522	}
523
524	SAFE_FREE(blob.data);
525
526	/* the trust's password */
527	if (pwd) {
528		*pwd = SMB_STRDUP(pass.pass);
529		if (!*pwd) {
530			return False;
531		}
532	}
533
534	/* last change time */
535	if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
536
537	/* domain sid */
538	if (sid != NULL) sid_copy(sid, &pass.domain_sid);
539
540	return True;
541}
542
543/**
544 * Routine to store the password for trusted domain
545 *
546 * @param domain remote domain name
547 * @param pwd plain text password of trust relationship
548 * @param sid remote domain sid
549 *
550 * @return true if succeeded
551 **/
552
553bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
554                                           const DOM_SID *sid)
555{
556	bool ret;
557
558	/* packing structures */
559	DATA_BLOB blob;
560	enum ndr_err_code ndr_err;
561	struct TRUSTED_DOM_PASS pass;
562	ZERO_STRUCT(pass);
563
564	pass.uni_name = domain;
565	pass.uni_name_len = strlen(domain)+1;
566
567	/* last change time */
568	pass.mod_time = time(NULL);
569
570	/* password of the trust */
571	pass.pass_len = strlen(pwd);
572	pass.pass = pwd;
573
574	/* domain sid */
575	sid_copy(&pass.domain_sid, sid);
576
577	ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &pass,
578			(ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
579	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
580		return false;
581	}
582
583	ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
584
585	data_blob_free(&blob);
586
587	return ret;
588}
589
590/************************************************************************
591 Routine to delete the old plaintext machine account password if any
592************************************************************************/
593
594static bool secrets_delete_prev_machine_password(const char *domain)
595{
596	char *oldpass = (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
597	if (oldpass == NULL) {
598		return true;
599	}
600	SAFE_FREE(oldpass);
601	return secrets_delete(machine_prev_password_keystr(domain));
602}
603
604/************************************************************************
605 Routine to delete the plaintext machine account password and old
606 password if any
607************************************************************************/
608
609bool secrets_delete_machine_password(const char *domain)
610{
611	if (!secrets_delete_prev_machine_password(domain)) {
612		return false;
613	}
614	return secrets_delete(machine_password_keystr(domain));
615}
616
617/************************************************************************
618 Routine to delete the plaintext machine account password, old password,
619 sec channel type and last change time from secrets database
620************************************************************************/
621
622bool secrets_delete_machine_password_ex(const char *domain)
623{
624	if (!secrets_delete_prev_machine_password(domain)) {
625		return false;
626	}
627	if (!secrets_delete(machine_password_keystr(domain))) {
628		return false;
629	}
630	if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
631		return false;
632	}
633	return secrets_delete(machine_last_change_time_keystr(domain));
634}
635
636/************************************************************************
637 Routine to delete the domain sid
638************************************************************************/
639
640bool secrets_delete_domain_sid(const char *domain)
641{
642	return secrets_delete(domain_sid_keystr(domain));
643}
644
645/************************************************************************
646 Routine to store the previous machine password (by storing the current password
647 as the old)
648************************************************************************/
649
650static bool secrets_store_prev_machine_password(const char *domain)
651{
652	char *oldpass;
653	bool ret;
654
655	oldpass = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
656	if (oldpass == NULL) {
657		return true;
658	}
659	ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
660	SAFE_FREE(oldpass);
661	return ret;
662}
663
664/************************************************************************
665 Routine to set the plaintext machine account password for a realm
666 the password is assumed to be a null terminated ascii string.
667 Before storing
668************************************************************************/
669
670bool secrets_store_machine_password(const char *pass, const char *domain,
671				    enum netr_SchannelType sec_channel)
672{
673	bool ret;
674	uint32 last_change_time;
675	uint32 sec_channel_type;
676
677	if (!secrets_store_prev_machine_password(domain)) {
678		return false;
679	}
680
681	ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
682	if (!ret)
683		return ret;
684
685	SIVAL(&last_change_time, 0, time(NULL));
686	ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
687
688	SIVAL(&sec_channel_type, 0, sec_channel);
689	ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
690
691	return ret;
692}
693
694
695/************************************************************************
696 Routine to fetch the previous plaintext machine account password for a realm
697 the password is assumed to be a null terminated ascii string.
698************************************************************************/
699
700char *secrets_fetch_prev_machine_password(const char *domain)
701{
702	return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
703}
704
705/************************************************************************
706 Routine to fetch the plaintext machine account password for a realm
707 the password is assumed to be a null terminated ascii string.
708************************************************************************/
709
710char *secrets_fetch_machine_password(const char *domain,
711				     time_t *pass_last_set_time,
712				     enum netr_SchannelType *channel)
713{
714	char *ret;
715	ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
716
717	if (pass_last_set_time) {
718		size_t size;
719		uint32 *last_set_time;
720		last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
721		if (last_set_time) {
722			*pass_last_set_time = IVAL(last_set_time,0);
723			SAFE_FREE(last_set_time);
724		} else {
725			*pass_last_set_time = 0;
726		}
727	}
728
729	if (channel) {
730		size_t size;
731		uint32 *channel_type;
732		channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
733		if (channel_type) {
734			*channel = IVAL(channel_type,0);
735			SAFE_FREE(channel_type);
736		} else {
737			*channel = get_default_sec_channel();
738		}
739	}
740
741	return ret;
742}
743
744/************************************************************************
745 Routine to delete the password for trusted domain
746************************************************************************/
747
748bool trusted_domain_password_delete(const char *domain)
749{
750	return secrets_delete(trustdom_keystr(domain));
751}
752
753bool secrets_store_ldap_pw(const char* dn, char* pw)
754{
755	char *key = NULL;
756	bool ret;
757
758	if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
759		DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
760		return False;
761	}
762
763	ret = secrets_store(key, pw, strlen(pw)+1);
764
765	SAFE_FREE(key);
766	return ret;
767}
768
769/*******************************************************************
770 Find the ldap password.
771******************************************************************/
772
773bool fetch_ldap_pw(char **dn, char** pw)
774{
775	char *key = NULL;
776	size_t size = 0;
777
778	*dn = smb_xstrdup(lp_ldap_admin_dn());
779
780	if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
781		SAFE_FREE(*dn);
782		DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
783		return false;
784	}
785
786	*pw=(char *)secrets_fetch(key, &size);
787	SAFE_FREE(key);
788
789	if (!size) {
790		/* Upgrade 2.2 style entry */
791		char *p;
792	        char* old_style_key = SMB_STRDUP(*dn);
793		char *data;
794		fstring old_style_pw;
795
796		if (!old_style_key) {
797			DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
798			return False;
799		}
800
801		for (p=old_style_key; *p; p++)
802			if (*p == ',') *p = '/';
803
804		data=(char *)secrets_fetch(old_style_key, &size);
805		if ((data == NULL) || (size < sizeof(old_style_pw))) {
806			DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
807			SAFE_FREE(old_style_key);
808			SAFE_FREE(*dn);
809			SAFE_FREE(data);
810			return False;
811		}
812
813		size = MIN(size, sizeof(fstring)-1);
814		strncpy(old_style_pw, data, size);
815		old_style_pw[size] = 0;
816
817		SAFE_FREE(data);
818
819		if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
820			DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
821			SAFE_FREE(old_style_key);
822			SAFE_FREE(*dn);
823			return False;
824		}
825		if (!secrets_delete(old_style_key)) {
826			DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
827		}
828
829		SAFE_FREE(old_style_key);
830
831		*pw = smb_xstrdup(old_style_pw);
832	}
833
834	return True;
835}
836
837/**
838 * Get trusted domains info from secrets.tdb.
839 **/
840
841struct list_trusted_domains_state {
842	uint32 num_domains;
843	struct trustdom_info **domains;
844};
845
846static int list_trusted_domain(struct db_record *rec, void *private_data)
847{
848	const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
849	struct TRUSTED_DOM_PASS pass;
850	enum ndr_err_code ndr_err;
851	DATA_BLOB blob;
852	struct trustdom_info *dom_info;
853
854	struct list_trusted_domains_state *state =
855		(struct list_trusted_domains_state *)private_data;
856
857	if ((rec->key.dsize < prefix_len)
858	    || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
859			prefix_len) != 0)) {
860		return 0;
861	}
862
863	blob = data_blob_const(rec->value.dptr, rec->value.dsize);
864
865	ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass,
866			(ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
867	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
868		return false;
869	}
870
871	if (pass.domain_sid.num_auths != 4) {
872		DEBUG(0, ("SID %s is not a domain sid, has %d "
873			  "auths instead of 4\n",
874			  sid_string_dbg(&pass.domain_sid),
875			  pass.domain_sid.num_auths));
876		return 0;
877	}
878
879	if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
880		DEBUG(0, ("talloc failed\n"));
881		return 0;
882	}
883
884	dom_info->name = talloc_strdup(dom_info, pass.uni_name);
885	if (!dom_info->name) {
886		TALLOC_FREE(dom_info);
887		return 0;
888	}
889
890	sid_copy(&dom_info->sid, &pass.domain_sid);
891
892	ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
893		     &state->domains, &state->num_domains);
894
895	if (state->domains == NULL) {
896		state->num_domains = 0;
897		return -1;
898	}
899	return 0;
900}
901
902NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
903				 struct trustdom_info ***domains)
904{
905	struct list_trusted_domains_state state;
906
907	secrets_init();
908
909	if (db_ctx == NULL) {
910		return NT_STATUS_ACCESS_DENIED;
911	}
912
913	state.num_domains = 0;
914
915	/*
916	 * Make sure that a talloc context for the trustdom_info structs
917	 * exists
918	 */
919
920	if (!(state.domains = TALLOC_ARRAY(
921		      mem_ctx, struct trustdom_info *, 1))) {
922		return NT_STATUS_NO_MEMORY;
923	}
924
925	db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
926
927	*num_domains = state.num_domains;
928	*domains = state.domains;
929	return NT_STATUS_OK;
930}
931
932/*******************************************************************************
933 Store a complete AFS keyfile into secrets.tdb.
934*******************************************************************************/
935
936bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
937{
938	fstring key;
939
940	if ((cell == NULL) || (keyfile == NULL))
941		return False;
942
943	if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
944		return False;
945
946	slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
947	return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
948}
949
950/*******************************************************************************
951 Fetch the current (highest) AFS key from secrets.tdb
952*******************************************************************************/
953bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
954{
955	fstring key;
956	struct afs_keyfile *keyfile;
957	size_t size = 0;
958	uint32 i;
959
960	slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
961
962	keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
963
964	if (keyfile == NULL)
965		return False;
966
967	if (size != sizeof(struct afs_keyfile)) {
968		SAFE_FREE(keyfile);
969		return False;
970	}
971
972	i = ntohl(keyfile->nkeys);
973
974	if (i > SECRETS_AFS_MAXKEYS) {
975		SAFE_FREE(keyfile);
976		return False;
977	}
978
979	*result = keyfile->entry[i-1];
980
981	result->kvno = ntohl(result->kvno);
982
983	SAFE_FREE(keyfile);
984
985	return True;
986}
987
988/******************************************************************************
989  When kerberos is not available, choose between anonymous or
990  authenticated connections.
991
992  We need to use an authenticated connection if DCs have the
993  RestrictAnonymous registry entry set > 0, or the "Additional
994  restrictions for anonymous connections" set in the win2k Local
995  Security Policy.
996
997  Caller to free() result in domain, username, password
998*******************************************************************************/
999void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1000{
1001	*username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1002	*domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1003	*password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1004
1005	if (*username && **username) {
1006
1007		if (!*domain || !**domain)
1008			*domain = smb_xstrdup(lp_workgroup());
1009
1010		if (!*password || !**password)
1011			*password = smb_xstrdup("");
1012
1013		DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1014			  *domain, *username));
1015
1016	} else {
1017		DEBUG(3, ("IPC$ connections done anonymously\n"));
1018		*username = smb_xstrdup("");
1019		*domain = smb_xstrdup("");
1020		*password = smb_xstrdup("");
1021	}
1022}
1023
1024bool secrets_store_generic(const char *owner, const char *key, const char *secret)
1025{
1026	char *tdbkey = NULL;
1027	bool ret;
1028
1029	if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1030		DEBUG(0, ("asprintf failed!\n"));
1031		return False;
1032	}
1033
1034	ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1035
1036	SAFE_FREE(tdbkey);
1037	return ret;
1038}
1039
1040bool secrets_delete_generic(const char *owner, const char *key)
1041{
1042	char *tdbkey = NULL;
1043	bool ret;
1044
1045	if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1046		DEBUG(0, ("asprintf failed!\n"));
1047		return False;
1048	}
1049
1050	ret = secrets_delete(tdbkey);
1051
1052	SAFE_FREE(tdbkey);
1053	return ret;
1054}
1055
1056/*******************************************************************
1057 Find the ldap password.
1058******************************************************************/
1059
1060char *secrets_fetch_generic(const char *owner, const char *key)
1061{
1062	char *secret = NULL;
1063	char *tdbkey = NULL;
1064
1065	if (( ! owner) || ( ! key)) {
1066		DEBUG(1, ("Invalid Paramters"));
1067		return NULL;
1068	}
1069
1070	if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1071		DEBUG(0, ("Out of memory!\n"));
1072		return NULL;
1073	}
1074
1075	secret = (char *)secrets_fetch(tdbkey, NULL);
1076	SAFE_FREE(tdbkey);
1077
1078	return secret;
1079}
1080
1081