source: branches/samba-3.0/source/passdb/secrets.c@ 223

Last change on this file since 223 was 140, checked in by Paul Smedley, 17 years ago

Update branch to 3.0.31 release

File size: 35.2 KB
Line 
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23/* the Samba secrets database stores any generated, private information
24 such as the local SID and machine trust password */
25
26#include "includes.h"
27
28#undef DBGC_CLASS
29#define DBGC_CLASS DBGC_PASSDB
30
31static TDB_CONTEXT *tdb;
32
33/* Urrrg. global.... */
34BOOL global_machine_password_needs_changing;
35
36/**
37 * Use a TDB to store an incrementing random seed.
38 *
39 * Initialised to the current pid, the very first time Samba starts,
40 * and incremented by one each time it is needed.
41 *
42 * @note Not called by systems with a working /dev/urandom.
43 */
44static void get_rand_seed(int *new_seed)
45{
46 *new_seed = sys_getpid();
47 if (tdb) {
48 tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
49 }
50}
51
52/* open up the secrets database */
53BOOL secrets_init(void)
54{
55 pstring fname;
56 unsigned char dummy;
57
58 if (tdb)
59 return True;
60
61 pstrcpy(fname, lp_private_dir());
62 pstrcat(fname,"/secrets.tdb");
63
64 tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
65
66 if (!tdb) {
67 DEBUG(0,("Failed to open %s\n", fname));
68 return False;
69 }
70
71 /**
72 * Set a reseed function for the crypto random generator
73 *
74 * This avoids a problem where systems without /dev/urandom
75 * could send the same challenge to multiple clients
76 */
77 set_rand_reseed_callback(get_rand_seed);
78
79 /* Ensure that the reseed is done now, while we are root, etc */
80 generate_random_buffer(&dummy, sizeof(dummy));
81
82 return True;
83}
84
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
87 */
88void *secrets_fetch(const char *key, size_t *size)
89{
90 TDB_DATA dbuf;
91 secrets_init();
92 if (!tdb)
93 return NULL;
94 dbuf = tdb_fetch(tdb, string_tdb_data(key));
95 if (size)
96 *size = dbuf.dsize;
97 return dbuf.dptr;
98}
99
100/* store a secrets entry
101 */
102BOOL secrets_store(const char *key, const void *data, size_t size)
103{
104 secrets_init();
105 if (!tdb)
106 return False;
107 return tdb_trans_store(tdb, string_tdb_data(key),
108 make_tdb_data((const char *)data, size),
109 TDB_REPLACE) == 0;
110}
111
112
113/* delete a secets database entry
114 */
115BOOL secrets_delete(const char *key)
116{
117 secrets_init();
118 if (!tdb)
119 return False;
120 return tdb_delete(tdb, string_tdb_data(key)) == 0;
121}
122
123BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
124{
125 fstring key;
126 BOOL ret;
127
128 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
129 strupper_m(key);
130 ret = secrets_store(key, sid, sizeof(DOM_SID));
131
132 /* Force a re-query, in case we modified our domain */
133 if (ret)
134 reset_global_sam_sid();
135 return ret;
136}
137
138BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
139{
140 DOM_SID *dyn_sid;
141 fstring key;
142 size_t size = 0;
143
144 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
145 strupper_m(key);
146 dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
147
148 if (dyn_sid == NULL)
149 return False;
150
151 if (size != sizeof(DOM_SID)) {
152 SAFE_FREE(dyn_sid);
153 return False;
154 }
155
156 *sid = *dyn_sid;
157 SAFE_FREE(dyn_sid);
158 return True;
159}
160
161BOOL secrets_store_domain_guid(const char *domain, struct GUID *guid)
162{
163 fstring key;
164
165 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
166 strupper_m(key);
167 return secrets_store(key, guid, sizeof(struct GUID));
168}
169
170BOOL secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
171{
172 struct GUID *dyn_guid;
173 fstring key;
174 size_t size = 0;
175 struct GUID new_guid;
176
177 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
178 strupper_m(key);
179 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
180
181 if (!dyn_guid) {
182 if (lp_server_role() == ROLE_DOMAIN_PDC) {
183 smb_uuid_generate_random(&new_guid);
184 if (!secrets_store_domain_guid(domain, &new_guid))
185 return False;
186 dyn_guid = (struct GUID *)secrets_fetch(key, &size);
187 }
188 if (dyn_guid == NULL) {
189 return False;
190 }
191 }
192
193 if (size != sizeof(struct GUID)) {
194 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
195 SAFE_FREE(dyn_guid);
196 return False;
197 }
198
199 *guid = *dyn_guid;
200 SAFE_FREE(dyn_guid);
201 return True;
202}
203
204/**
205 * Form a key for fetching the machine trust account password
206 *
207 * @param domain domain name
208 *
209 * @return stored password's key
210 **/
211static const char *trust_keystr(const char *domain)
212{
213 static fstring keystr;
214
215 slprintf(keystr,sizeof(keystr)-1,"%s/%s",
216 SECRETS_MACHINE_ACCT_PASS, domain);
217 strupper_m(keystr);
218
219 return keystr;
220}
221
222/**
223 * Form a key for fetching a trusted domain password
224 *
225 * @param domain trusted domain name
226 *
227 * @return stored password's key
228 **/
229static char *trustdom_keystr(const char *domain)
230{
231 static pstring keystr;
232
233 pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
234 strupper_m(keystr);
235
236 return keystr;
237}
238
239/************************************************************************
240 Lock the trust password entry.
241************************************************************************/
242
243BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
244{
245 if (!tdb)
246 return False;
247
248 if (dolock)
249 return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
250 else
251 tdb_unlock_bystring(tdb, trust_keystr(domain));
252 return True;
253}
254
255/************************************************************************
256 Routine to get the default secure channel type for trust accounts
257************************************************************************/
258
259uint32 get_default_sec_channel(void)
260{
261 if (lp_server_role() == ROLE_DOMAIN_BDC ||
262 lp_server_role() == ROLE_DOMAIN_PDC) {
263 return SEC_CHAN_BDC;
264 } else {
265 return SEC_CHAN_WKSTA;
266 }
267}
268
269/************************************************************************
270 Routine to get the trust account password for a domain.
271 This only tries to get the legacy hashed version of the password.
272 The user of this function must have locked the trust password file using
273 the above secrets_lock_trust_account_password().
274************************************************************************/
275
276BOOL secrets_fetch_trust_account_password_legacy(const char *domain,
277 uint8 ret_pwd[16],
278 time_t *pass_last_set_time,
279 uint32 *channel)
280{
281 struct machine_acct_pass *pass;
282 size_t size = 0;
283
284 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
285 trust_keystr(domain), &size))) {
286 DEBUG(5, ("secrets_fetch failed!\n"));
287 return False;
288 }
289
290 if (size != sizeof(*pass)) {
291 DEBUG(0, ("secrets were of incorrect size!\n"));
292 return False;
293 }
294
295 if (pass_last_set_time) {
296 *pass_last_set_time = pass->mod_time;
297 }
298 memcpy(ret_pwd, pass->hash, 16);
299
300 if (channel) {
301 *channel = get_default_sec_channel();
302 }
303
304 /* Test if machine password has expired and needs to be changed */
305 if (lp_machine_password_timeout()) {
306 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
307 (time_t)lp_machine_password_timeout())) {
308 global_machine_password_needs_changing = True;
309 }
310 }
311
312 SAFE_FREE(pass);
313 return True;
314}
315
316/************************************************************************
317 Routine to get the trust account password for a domain.
318 The user of this function must have locked the trust password file using
319 the above secrets_lock_trust_account_password().
320************************************************************************/
321
322BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
323 time_t *pass_last_set_time,
324 uint32 *channel)
325{
326 char *plaintext;
327
328 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
329 channel);
330 if (plaintext) {
331 DEBUG(4,("Using cleartext machine password\n"));
332 E_md4hash(plaintext, ret_pwd);
333 SAFE_FREE(plaintext);
334 return True;
335 }
336
337 return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
338 pass_last_set_time,
339 channel);
340}
341
342/**
343 * Pack SID passed by pointer
344 *
345 * @param pack_buf pointer to buffer which is to be filled with packed data
346 * @param bufsize size of packing buffer
347 * @param sid pointer to sid to be packed
348 *
349 * @return length of the packed representation of the whole structure
350 **/
351static size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid)
352{
353 int idx;
354 size_t len = 0;
355
356 if (!sid || !pack_buf) return -1;
357
358 len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
359 sid->num_auths);
360
361 for (idx = 0; idx < 6; idx++) {
362 len += tdb_pack(pack_buf + len, bufsize - len, "b",
363 sid->id_auth[idx]);
364 }
365
366 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
367 len += tdb_pack(pack_buf + len, bufsize - len, "d",
368 sid->sub_auths[idx]);
369 }
370
371 return len;
372}
373
374/**
375 * Unpack SID into a pointer
376 *
377 * @param pack_buf pointer to buffer with packed representation
378 * @param bufsize size of the buffer
379 * @param sid pointer to sid structure to be filled with unpacked data
380 *
381 * @return size of structure unpacked from buffer
382 **/
383static size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid)
384{
385 int idx, len = 0;
386
387 if (!sid || !pack_buf) return -1;
388
389 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
390 &sid->sid_rev_num, &sid->num_auths);
391
392 for (idx = 0; idx < 6; idx++) {
393 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
394 &sid->id_auth[idx]);
395 }
396
397 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
398 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
399 &sid->sub_auths[idx]);
400 }
401
402 return len;
403}
404
405/**
406 * Pack TRUSTED_DOM_PASS passed by pointer
407 *
408 * @param pack_buf pointer to buffer which is to be filled with packed data
409 * @param bufsize size of the buffer
410 * @param pass pointer to trusted domain password to be packed
411 *
412 * @return length of the packed representation of the whole structure
413 **/
414static size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize,
415 TRUSTED_DOM_PASS* pass)
416{
417 int idx, len = 0;
418
419 if (!pack_buf || !pass) return -1;
420
421 /* packing unicode domain name and password */
422 len += tdb_pack(pack_buf + len, bufsize - len, "d",
423 pass->uni_name_len);
424
425 for (idx = 0; idx < 32; idx++)
426 len += tdb_pack(pack_buf + len, bufsize - len, "w",
427 pass->uni_name[idx]);
428
429 len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len,
430 pass->pass, pass->mod_time);
431
432 /* packing SID structure */
433 len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid);
434
435 return len;
436}
437
438
439/**
440 * Unpack TRUSTED_DOM_PASS passed by pointer
441 *
442 * @param pack_buf pointer to buffer with packed representation
443 * @param bufsize size of the buffer
444 * @param pass pointer to trusted domain password to be filled with unpacked data
445 *
446 * @return size of structure unpacked from buffer
447 **/
448static size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize,
449 TRUSTED_DOM_PASS* pass)
450{
451 int idx, len = 0;
452
453 if (!pack_buf || !pass) return -1;
454
455 /* unpack unicode domain name and plaintext password */
456 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
457
458 for (idx = 0; idx < 32; idx++)
459 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
460 &pass->uni_name[idx]);
461
462 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
463 &pass->pass_len, &pass->pass, &pass->mod_time);
464
465 /* unpack domain sid */
466 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
467 &pass->domain_sid);
468
469 return len;
470}
471
472/************************************************************************
473 Routine to get account password to trusted domain
474************************************************************************/
475
476BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
477 DOM_SID *sid, time_t *pass_last_set_time)
478{
479 struct trusted_dom_pass pass;
480 size_t size = 0;
481
482 /* unpacking structures */
483 char* pass_buf;
484 int pass_len = 0;
485
486 ZERO_STRUCT(pass);
487
488 /* fetching trusted domain password structure */
489 if (!(pass_buf = (char *)secrets_fetch(trustdom_keystr(domain),
490 &size))) {
491 DEBUG(5, ("secrets_fetch failed!\n"));
492 return False;
493 }
494
495 /* unpack trusted domain password */
496 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
497 SAFE_FREE(pass_buf);
498
499 if (pass_len != size) {
500 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
501 return False;
502 }
503
504 /* the trust's password */
505 if (pwd) {
506 *pwd = SMB_STRDUP(pass.pass);
507 if (!*pwd) {
508 return False;
509 }
510 }
511
512 /* last change time */
513 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
514
515 /* domain sid */
516 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
517
518 return True;
519}
520
521/**
522 * Routine to store the password for trusted domain
523 *
524 * @param domain remote domain name
525 * @param pwd plain text password of trust relationship
526 * @param sid remote domain sid
527 *
528 * @return true if succeeded
529 **/
530
531BOOL secrets_store_trusted_domain_password(const char* domain, const char* pwd,
532 const DOM_SID *sid)
533{
534 smb_ucs2_t *uni_dom_name;
535
536 /* packing structures */
537 pstring pass_buf;
538 int pass_len = 0;
539 int pass_buf_len = sizeof(pass_buf);
540
541 struct trusted_dom_pass pass;
542 ZERO_STRUCT(pass);
543
544 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
545 DEBUG(0, ("Could not convert domain name %s to unicode\n",
546 domain));
547 return False;
548 }
549
550 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
551 pass.uni_name_len = strlen_w(uni_dom_name)+1;
552 SAFE_FREE(uni_dom_name);
553
554 /* last change time */
555 pass.mod_time = time(NULL);
556
557 /* password of the trust */
558 pass.pass_len = strlen(pwd);
559 fstrcpy(pass.pass, pwd);
560
561 /* domain sid */
562 sid_copy(&pass.domain_sid, sid);
563
564 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
565
566 return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
567}
568
569/************************************************************************
570 Routine to set the plaintext machine account password for a realm
571the password is assumed to be a null terminated ascii string
572************************************************************************/
573
574BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
575{
576 char *key = NULL;
577 BOOL ret;
578 uint32 last_change_time;
579 uint32 sec_channel_type;
580
581 asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
582 if (!key)
583 return False;
584 strupper_m(key);
585
586 ret = secrets_store(key, pass, strlen(pass)+1);
587 SAFE_FREE(key);
588
589 if (!ret)
590 return ret;
591
592 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
593 if (!key)
594 return False;
595 strupper_m(key);
596
597 SIVAL(&last_change_time, 0, time(NULL));
598 ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
599 SAFE_FREE(key);
600
601 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
602 if (!key)
603 return False;
604 strupper_m(key);
605
606 SIVAL(&sec_channel_type, 0, sec_channel);
607 ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
608 SAFE_FREE(key);
609
610 return ret;
611}
612
613/************************************************************************
614 Routine to fetch the plaintext machine account password for a realm
615 the password is assumed to be a null terminated ascii string.
616************************************************************************/
617
618char *secrets_fetch_machine_password(const char *domain,
619 time_t *pass_last_set_time,
620 uint32 *channel)
621{
622 char *key = NULL;
623 char *ret;
624 asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
625 strupper_m(key);
626 ret = (char *)secrets_fetch(key, NULL);
627 SAFE_FREE(key);
628
629 if (pass_last_set_time) {
630 size_t size;
631 uint32 *last_set_time;
632 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
633 strupper_m(key);
634 last_set_time = (unsigned int *)secrets_fetch(key, &size);
635 if (last_set_time) {
636 *pass_last_set_time = IVAL(last_set_time,0);
637 SAFE_FREE(last_set_time);
638 } else {
639 *pass_last_set_time = 0;
640 }
641 SAFE_FREE(key);
642 }
643
644 if (channel) {
645 size_t size;
646 uint32 *channel_type;
647 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
648 strupper_m(key);
649 channel_type = (unsigned int *)secrets_fetch(key, &size);
650 if (channel_type) {
651 *channel = IVAL(channel_type,0);
652 SAFE_FREE(channel_type);
653 } else {
654 *channel = get_default_sec_channel();
655 }
656 SAFE_FREE(key);
657 }
658
659 return ret;
660}
661
662BOOL is_trusted_domain_situation(const char *domain_name)
663{
664 return IS_DC &&
665 lp_allow_trusted_domains() &&
666 !strequal(domain_name, lp_workgroup());
667}
668
669/*******************************************************************
670 Wrapper around retrieving the clear text trust account password.
671 appropriate account name is stored in account_name.
672 Caller must free password, but not account_name.
673*******************************************************************/
674
675BOOL get_trust_pw_clear(const char *domain, char **ret_pwd,
676 const char **account_name, uint32 *channel)
677{
678 char *pwd;
679 time_t last_set_time;
680
681 /* if we are a DC and this is not our domain, then lookup an account
682 * for the domain trust */
683
684 if (is_trusted_domain_situation(domain)) {
685 if (!secrets_fetch_trusted_domain_password(domain, ret_pwd,
686 NULL, &last_set_time))
687 {
688 DEBUG(0, ("get_trust_pw: could not fetch trust "
689 "account password for trusted domain %s\n",
690 domain));
691 return False;
692 }
693
694 if (channel != NULL) {
695 *channel = SEC_CHAN_DOMAIN;
696 }
697
698 if (account_name != NULL) {
699 *account_name = lp_workgroup();
700 }
701
702 return True;
703 }
704
705 /* Here we are a domain member server. We can only be a member
706 of one domain so ignore the request domain and assume our own */
707
708 pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time,
709 channel);
710
711 if (pwd != NULL) {
712 *ret_pwd = pwd;
713 if (account_name != NULL) {
714 *account_name = global_myname();
715 }
716
717 return True;
718 }
719
720 DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
721 "account password for domain %s\n", domain));
722 return False;
723}
724
725/*******************************************************************
726 Wrapper around retrieving the trust account password.
727 appropriate account name is stored in account_name.
728*******************************************************************/
729
730BOOL get_trust_pw_hash(const char *domain, uint8 ret_pwd[16],
731 const char **account_name, uint32 *channel)
732{
733 char *pwd = NULL;
734 time_t last_set_time;
735
736 if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
737 E_md4hash(pwd, ret_pwd);
738 SAFE_FREE(pwd);
739 return True;
740 } else if (is_trusted_domain_situation(domain)) {
741 return False;
742 }
743
744 /* as a fallback, try to get the hashed pwd directly from the tdb... */
745
746 if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
747 &last_set_time,
748 channel))
749 {
750 if (account_name != NULL) {
751 *account_name = global_myname();
752 }
753
754 return True;
755 }
756
757 DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
758 "password for domain %s\n", domain));
759 return False;
760}
761
762/************************************************************************
763 Routine to delete the password for trusted domain
764************************************************************************/
765
766BOOL trusted_domain_password_delete(const char *domain)
767{
768 return secrets_delete(trustdom_keystr(domain));
769}
770
771BOOL secrets_store_ldap_pw(const char* dn, char* pw)
772{
773 char *key = NULL;
774 BOOL ret;
775
776 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
777 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
778 return False;
779 }
780
781 ret = secrets_store(key, pw, strlen(pw)+1);
782
783 SAFE_FREE(key);
784 return ret;
785}
786
787/*******************************************************************
788 Find the ldap password.
789******************************************************************/
790
791BOOL fetch_ldap_pw(char **dn, char** pw)
792{
793 char *key = NULL;
794 size_t size = 0;
795
796 *dn = smb_xstrdup(lp_ldap_admin_dn());
797
798 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
799 SAFE_FREE(*dn);
800 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
801 }
802
803 *pw=(char *)secrets_fetch(key, &size);
804 SAFE_FREE(key);
805
806 if (!size) {
807 /* Upgrade 2.2 style entry */
808 char *p;
809 char* old_style_key = SMB_STRDUP(*dn);
810 char *data;
811 fstring old_style_pw;
812
813 if (!old_style_key) {
814 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
815 return False;
816 }
817
818 for (p=old_style_key; *p; p++)
819 if (*p == ',') *p = '/';
820
821 data=(char *)secrets_fetch(old_style_key, &size);
822 if (!size && size < sizeof(old_style_pw)) {
823 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
824 SAFE_FREE(old_style_key);
825 SAFE_FREE(*dn);
826 return False;
827 }
828
829 size = MIN(size, sizeof(fstring)-1);
830 strncpy(old_style_pw, data, size);
831 old_style_pw[size] = 0;
832
833 SAFE_FREE(data);
834
835 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
836 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
837 SAFE_FREE(old_style_key);
838 SAFE_FREE(*dn);
839 return False;
840 }
841 if (!secrets_delete(old_style_key)) {
842 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
843 }
844
845 SAFE_FREE(old_style_key);
846
847 *pw = smb_xstrdup(old_style_pw);
848 }
849
850 return True;
851}
852
853/**
854 * Get trusted domains info from secrets.tdb.
855 **/
856
857NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
858 struct trustdom_info ***domains)
859{
860 TDB_LIST_NODE *keys, *k;
861 char *pattern;
862 TALLOC_CTX *tmp_ctx;
863
864 if (!(tmp_ctx = talloc_new(mem_ctx))) {
865 return NT_STATUS_NO_MEMORY;
866 }
867
868 if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
869
870 /* generate searching pattern */
871 pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
872 if (pattern == NULL) {
873 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
874 "failed!\n"));
875 TALLOC_FREE(tmp_ctx);
876 return NT_STATUS_NO_MEMORY;
877 }
878
879 *num_domains = 0;
880
881 /*
882 * Make sure that a talloc context for the trustdom_info structs
883 * exists
884 */
885
886 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
887 TALLOC_FREE(tmp_ctx);
888 return NT_STATUS_NO_MEMORY;
889 }
890
891 /* fetching trusted domains' data and collecting them in a list */
892 keys = tdb_search_keys(tdb, pattern);
893
894 /* searching for keys in secrets db -- way to go ... */
895 for (k = keys; k; k = k->next) {
896 char *packed_pass;
897 size_t size = 0, packed_size = 0;
898 struct trusted_dom_pass pass;
899 char *secrets_key;
900 struct trustdom_info *dom_info;
901
902 /* important: ensure null-termination of the key string */
903 secrets_key = talloc_strndup(tmp_ctx,
904 k->node_key.dptr,
905 k->node_key.dsize);
906 if (!secrets_key) {
907 DEBUG(0, ("strndup failed!\n"));
908 tdb_search_list_free(keys);
909 TALLOC_FREE(tmp_ctx);
910 return NT_STATUS_NO_MEMORY;
911 }
912
913 packed_pass = (char *)secrets_fetch(secrets_key, &size);
914 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
915 &pass);
916 /* packed representation isn't needed anymore */
917 SAFE_FREE(packed_pass);
918
919 if (size != packed_size) {
920 DEBUG(2, ("Secrets record %s is invalid!\n",
921 secrets_key));
922 continue;
923 }
924
925 if (pass.domain_sid.num_auths != 4) {
926 DEBUG(0, ("SID %s is not a domain sid, has %d "
927 "auths instead of 4\n",
928 sid_string_static(&pass.domain_sid),
929 pass.domain_sid.num_auths));
930 continue;
931 }
932
933 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
934 DEBUG(0, ("talloc failed\n"));
935 tdb_search_list_free(keys);
936 TALLOC_FREE(tmp_ctx);
937 return NT_STATUS_NO_MEMORY;
938 }
939
940 if (pull_ucs2_talloc(dom_info, &dom_info->name,
941 pass.uni_name) == (size_t)-1) {
942 DEBUG(2, ("pull_ucs2_talloc failed\n"));
943 tdb_search_list_free(keys);
944 TALLOC_FREE(tmp_ctx);
945 return NT_STATUS_NO_MEMORY;
946 }
947
948 sid_copy(&dom_info->sid, &pass.domain_sid);
949
950 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
951 domains, num_domains);
952
953 if (*domains == NULL) {
954 tdb_search_list_free(keys);
955 TALLOC_FREE(tmp_ctx);
956 return NT_STATUS_NO_MEMORY;
957 }
958 }
959
960 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
961 *num_domains));
962
963 /* free the results of searching the keys */
964 tdb_search_list_free(keys);
965 TALLOC_FREE(tmp_ctx);
966
967 return NT_STATUS_OK;
968}
969
970/*******************************************************************************
971 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
972 between smbd instances.
973*******************************************************************************/
974
975BOOL secrets_named_mutex(const char *name, unsigned int timeout)
976{
977 int ret = 0;
978
979 if (!secrets_init())
980 return False;
981
982 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
983 if (ret == 0)
984 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
985
986 return (ret == 0);
987}
988
989/*******************************************************************************
990 Unlock a named mutex.
991*******************************************************************************/
992
993void secrets_named_mutex_release(const char *name)
994{
995 tdb_unlock_bystring(tdb, name);
996 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
997}
998
999/*******************************************************************************
1000 Store a complete AFS keyfile into secrets.tdb.
1001*******************************************************************************/
1002
1003BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
1004{
1005 fstring key;
1006
1007 if ((cell == NULL) || (keyfile == NULL))
1008 return False;
1009
1010 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
1011 return False;
1012
1013 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1014 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
1015}
1016
1017/*******************************************************************************
1018 Fetch the current (highest) AFS key from secrets.tdb
1019*******************************************************************************/
1020BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
1021{
1022 fstring key;
1023 struct afs_keyfile *keyfile;
1024 size_t size = 0;
1025 uint32 i;
1026
1027 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
1028
1029 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
1030
1031 if (keyfile == NULL)
1032 return False;
1033
1034 if (size != sizeof(struct afs_keyfile)) {
1035 SAFE_FREE(keyfile);
1036 return False;
1037 }
1038
1039 i = ntohl(keyfile->nkeys);
1040
1041 if (i > SECRETS_AFS_MAXKEYS) {
1042 SAFE_FREE(keyfile);
1043 return False;
1044 }
1045
1046 *result = keyfile->entry[i-1];
1047
1048 result->kvno = ntohl(result->kvno);
1049
1050 return True;
1051}
1052
1053/******************************************************************************
1054 When kerberos is not available, choose between anonymous or
1055 authenticated connections.
1056
1057 We need to use an authenticated connection if DCs have the
1058 RestrictAnonymous registry entry set > 0, or the "Additional
1059 restrictions for anonymous connections" set in the win2k Local
1060 Security Policy.
1061
1062 Caller to free() result in domain, username, password
1063*******************************************************************************/
1064void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1065{
1066 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1067 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1068 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1069
1070 if (*username && **username) {
1071
1072 if (!*domain || !**domain)
1073 *domain = smb_xstrdup(lp_workgroup());
1074
1075 if (!*password || !**password)
1076 *password = smb_xstrdup("");
1077
1078 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1079 *domain, *username));
1080
1081 } else {
1082 DEBUG(3, ("IPC$ connections done anonymously\n"));
1083 *username = smb_xstrdup("");
1084 *domain = smb_xstrdup("");
1085 *password = smb_xstrdup("");
1086 }
1087}
1088
1089/******************************************************************************
1090 Open or create the schannel session store tdb.
1091*******************************************************************************/
1092
1093static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1094{
1095 TDB_DATA vers;
1096 uint32 ver;
1097 TDB_CONTEXT *tdb_sc = NULL;
1098 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1099
1100 if (!fname) {
1101 return NULL;
1102 }
1103
1104 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1105
1106 if (!tdb_sc) {
1107 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1108 TALLOC_FREE(fname);
1109 return NULL;
1110 }
1111
1112 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1113 if (vers.dptr == NULL) {
1114 /* First opener, no version. */
1115 SIVAL(&ver,0,1);
1116 vers.dptr = (char *)&ver;
1117 vers.dsize = 4;
1118 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1119 vers.dptr = NULL;
1120 } else if (vers.dsize == 4) {
1121 ver = IVAL(vers.dptr,0);
1122 if (ver != 1) {
1123 tdb_close(tdb_sc);
1124 tdb_sc = NULL;
1125 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1126 (int)ver, fname ));
1127 }
1128 } else {
1129 tdb_close(tdb_sc);
1130 tdb_sc = NULL;
1131 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1132 (int)vers.dsize, fname ));
1133 }
1134
1135 SAFE_FREE(vers.dptr);
1136 TALLOC_FREE(fname);
1137
1138 return tdb_sc;
1139}
1140
1141/******************************************************************************
1142 Store the schannel state after an AUTH2 call.
1143 Note we must be root here.
1144*******************************************************************************/
1145
1146BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1147 const char *remote_machine,
1148 const struct dcinfo *pdc)
1149{
1150 TDB_CONTEXT *tdb_sc = NULL;
1151 TDB_DATA value;
1152 BOOL ret;
1153 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1154 remote_machine);
1155 if (!keystr) {
1156 return False;
1157 }
1158
1159 strupper_m(keystr);
1160
1161 /* Work out how large the record is. */
1162 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1163 pdc->sequence,
1164 8, pdc->seed_chal.data,
1165 8, pdc->clnt_chal.data,
1166 8, pdc->srv_chal.data,
1167 16, pdc->sess_key,
1168 16, pdc->mach_pw,
1169 pdc->mach_acct,
1170 pdc->remote_machine,
1171 pdc->domain);
1172
1173 value.dptr = (char *)TALLOC(mem_ctx, value.dsize);
1174 if (!value.dptr) {
1175 TALLOC_FREE(keystr);
1176 return False;
1177 }
1178
1179 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1180 pdc->sequence,
1181 8, pdc->seed_chal.data,
1182 8, pdc->clnt_chal.data,
1183 8, pdc->srv_chal.data,
1184 16, pdc->sess_key,
1185 16, pdc->mach_pw,
1186 pdc->mach_acct,
1187 pdc->remote_machine,
1188 pdc->domain);
1189
1190 tdb_sc = open_schannel_session_store(mem_ctx);
1191 if (!tdb_sc) {
1192 TALLOC_FREE(keystr);
1193 TALLOC_FREE(value.dptr);
1194 return False;
1195 }
1196
1197 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1198
1199 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1200 keystr ));
1201
1202 tdb_close(tdb_sc);
1203 TALLOC_FREE(keystr);
1204 TALLOC_FREE(value.dptr);
1205 return ret;
1206}
1207
1208/******************************************************************************
1209 Restore the schannel state on a client reconnect.
1210 Note we must be root here.
1211*******************************************************************************/
1212
1213BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1214 const char *remote_machine,
1215 struct dcinfo **ppdc)
1216{
1217 TDB_CONTEXT *tdb_sc = NULL;
1218 TDB_DATA value;
1219 unsigned char *pseed_chal = NULL;
1220 unsigned char *pclnt_chal = NULL;
1221 unsigned char *psrv_chal = NULL;
1222 unsigned char *psess_key = NULL;
1223 unsigned char *pmach_pw = NULL;
1224 uint32 l1, l2, l3, l4, l5;
1225 int ret;
1226 struct dcinfo *pdc = NULL;
1227 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1228 remote_machine);
1229
1230 *ppdc = NULL;
1231
1232 if (!keystr) {
1233 return False;
1234 }
1235
1236 strupper_m(keystr);
1237
1238 tdb_sc = open_schannel_session_store(mem_ctx);
1239 if (!tdb_sc) {
1240 TALLOC_FREE(keystr);
1241 return False;
1242 }
1243
1244 value = tdb_fetch_bystring(tdb_sc, keystr);
1245 if (!value.dptr) {
1246 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1247 keystr ));
1248 tdb_close(tdb_sc);
1249 return False;
1250 }
1251
1252 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1253
1254 /* Retrieve the record. */
1255 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1256 &pdc->sequence,
1257 &l1, &pseed_chal,
1258 &l2, &pclnt_chal,
1259 &l3, &psrv_chal,
1260 &l4, &psess_key,
1261 &l5, &pmach_pw,
1262 &pdc->mach_acct,
1263 &pdc->remote_machine,
1264 &pdc->domain);
1265
1266 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1267 /* Bad record - delete it. */
1268 tdb_delete_bystring(tdb_sc, keystr);
1269 tdb_close(tdb_sc);
1270 TALLOC_FREE(keystr);
1271 TALLOC_FREE(pdc);
1272 SAFE_FREE(pseed_chal);
1273 SAFE_FREE(pclnt_chal);
1274 SAFE_FREE(psrv_chal);
1275 SAFE_FREE(psess_key);
1276 SAFE_FREE(pmach_pw);
1277 SAFE_FREE(value.dptr);
1278 return False;
1279 }
1280
1281 tdb_close(tdb_sc);
1282
1283 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1284 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1285 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1286 memcpy(pdc->sess_key, psess_key, 16);
1287 memcpy(pdc->mach_pw, pmach_pw, 16);
1288
1289 /* We know these are true so didn't bother to store them. */
1290 pdc->challenge_sent = True;
1291 pdc->authenticated = True;
1292
1293 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1294 keystr ));
1295
1296 SAFE_FREE(pseed_chal);
1297 SAFE_FREE(pclnt_chal);
1298 SAFE_FREE(psrv_chal);
1299 SAFE_FREE(psess_key);
1300 SAFE_FREE(pmach_pw);
1301
1302 TALLOC_FREE(keystr);
1303 SAFE_FREE(value.dptr);
1304
1305 *ppdc = pdc;
1306
1307 return True;
1308}
1309
1310BOOL secrets_store_generic(const char *owner, const char *key, const char *secret)
1311{
1312 char *tdbkey = NULL;
1313 BOOL ret;
1314
1315 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1316 DEBUG(0, ("asprintf failed!\n"));
1317 return False;
1318 }
1319
1320 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1321
1322 SAFE_FREE(tdbkey);
1323 return ret;
1324}
1325
1326/*******************************************************************
1327 Find the ldap password.
1328******************************************************************/
1329
1330char *secrets_fetch_generic(const char *owner, const char *key)
1331{
1332 char *secret = NULL;
1333 char *tdbkey = NULL;
1334
1335 if (( ! owner) || ( ! key)) {
1336 DEBUG(1, ("Invalid Paramters"));
1337 return NULL;
1338 }
1339
1340 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1341 DEBUG(0, ("Out of memory!\n"));
1342 return NULL;
1343 }
1344
1345 secret = (char *)secrets_fetch(tdbkey, NULL);
1346 SAFE_FREE(tdbkey);
1347
1348 return secret;
1349}
1350
Note: See TracBrowser for help on using the repository browser.