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

Last change on this file since 104 was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 33.3 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 The user of this function must have locked the trust password file using
272 the above secrets_lock_trust_account_password().
273************************************************************************/
274
275BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
276 time_t *pass_last_set_time,
277 uint32 *channel)
278{
279 struct machine_acct_pass *pass;
280 char *plaintext;
281 size_t size = 0;
282
283 plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
284 channel);
285 if (plaintext) {
286 DEBUG(4,("Using cleartext machine password\n"));
287 E_md4hash(plaintext, ret_pwd);
288 SAFE_FREE(plaintext);
289 return True;
290 }
291
292 if (!(pass = (struct machine_acct_pass *)secrets_fetch(
293 trust_keystr(domain), &size))) {
294 DEBUG(5, ("secrets_fetch failed!\n"));
295 return False;
296 }
297
298 if (size != sizeof(*pass)) {
299 DEBUG(0, ("secrets were of incorrect size!\n"));
300 return False;
301 }
302
303 if (pass_last_set_time) {
304 *pass_last_set_time = pass->mod_time;
305 }
306 memcpy(ret_pwd, pass->hash, 16);
307
308 if (channel) {
309 *channel = get_default_sec_channel();
310 }
311
312 /* Test if machine password has expired and needs to be changed */
313 if (lp_machine_password_timeout()) {
314 if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
315 (time_t)lp_machine_password_timeout())) {
316 global_machine_password_needs_changing = True;
317 }
318 }
319
320 SAFE_FREE(pass);
321 return True;
322}
323
324/**
325 * Pack SID passed by pointer
326 *
327 * @param pack_buf pointer to buffer which is to be filled with packed data
328 * @param bufsize size of packing buffer
329 * @param sid pointer to sid to be packed
330 *
331 * @return length of the packed representation of the whole structure
332 **/
333static size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid)
334{
335 int idx;
336 size_t len = 0;
337
338 if (!sid || !pack_buf) return -1;
339
340 len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num,
341 sid->num_auths);
342
343 for (idx = 0; idx < 6; idx++) {
344 len += tdb_pack(pack_buf + len, bufsize - len, "b",
345 sid->id_auth[idx]);
346 }
347
348 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
349 len += tdb_pack(pack_buf + len, bufsize - len, "d",
350 sid->sub_auths[idx]);
351 }
352
353 return len;
354}
355
356/**
357 * Unpack SID into a pointer
358 *
359 * @param pack_buf pointer to buffer with packed representation
360 * @param bufsize size of the buffer
361 * @param sid pointer to sid structure to be filled with unpacked data
362 *
363 * @return size of structure unpacked from buffer
364 **/
365static size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid)
366{
367 int idx, len = 0;
368
369 if (!sid || !pack_buf) return -1;
370
371 len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
372 &sid->sid_rev_num, &sid->num_auths);
373
374 for (idx = 0; idx < 6; idx++) {
375 len += tdb_unpack(pack_buf + len, bufsize - len, "b",
376 &sid->id_auth[idx]);
377 }
378
379 for (idx = 0; idx < MAXSUBAUTHS; idx++) {
380 len += tdb_unpack(pack_buf + len, bufsize - len, "d",
381 &sid->sub_auths[idx]);
382 }
383
384 return len;
385}
386
387/**
388 * Pack TRUSTED_DOM_PASS passed by pointer
389 *
390 * @param pack_buf pointer to buffer which is to be filled with packed data
391 * @param bufsize size of the buffer
392 * @param pass pointer to trusted domain password to be packed
393 *
394 * @return length of the packed representation of the whole structure
395 **/
396static size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize,
397 TRUSTED_DOM_PASS* pass)
398{
399 int idx, len = 0;
400
401 if (!pack_buf || !pass) return -1;
402
403 /* packing unicode domain name and password */
404 len += tdb_pack(pack_buf + len, bufsize - len, "d",
405 pass->uni_name_len);
406
407 for (idx = 0; idx < 32; idx++)
408 len += tdb_pack(pack_buf + len, bufsize - len, "w",
409 pass->uni_name[idx]);
410
411 len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len,
412 pass->pass, pass->mod_time);
413
414 /* packing SID structure */
415 len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid);
416
417 return len;
418}
419
420
421/**
422 * Unpack TRUSTED_DOM_PASS passed by pointer
423 *
424 * @param pack_buf pointer to buffer with packed representation
425 * @param bufsize size of the buffer
426 * @param pass pointer to trusted domain password to be filled with unpacked data
427 *
428 * @return size of structure unpacked from buffer
429 **/
430static size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize,
431 TRUSTED_DOM_PASS* pass)
432{
433 int idx, len = 0;
434
435 if (!pack_buf || !pass) return -1;
436
437 /* unpack unicode domain name and plaintext password */
438 len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
439
440 for (idx = 0; idx < 32; idx++)
441 len += tdb_unpack(pack_buf + len, bufsize - len, "w",
442 &pass->uni_name[idx]);
443
444 len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
445 &pass->pass_len, &pass->pass, &pass->mod_time);
446
447 /* unpack domain sid */
448 len += tdb_sid_unpack(pack_buf + len, bufsize - len,
449 &pass->domain_sid);
450
451 return len;
452}
453
454/************************************************************************
455 Routine to get account password to trusted domain
456************************************************************************/
457
458BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
459 DOM_SID *sid, time_t *pass_last_set_time)
460{
461 struct trusted_dom_pass pass;
462 size_t size = 0;
463
464 /* unpacking structures */
465 char* pass_buf;
466 int pass_len = 0;
467
468 ZERO_STRUCT(pass);
469
470 /* fetching trusted domain password structure */
471 if (!(pass_buf = (char *)secrets_fetch(trustdom_keystr(domain),
472 &size))) {
473 DEBUG(5, ("secrets_fetch failed!\n"));
474 return False;
475 }
476
477 /* unpack trusted domain password */
478 pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
479 SAFE_FREE(pass_buf);
480
481 if (pass_len != size) {
482 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
483 return False;
484 }
485
486 /* the trust's password */
487 if (pwd) {
488 *pwd = SMB_STRDUP(pass.pass);
489 if (!*pwd) {
490 return False;
491 }
492 }
493
494 /* last change time */
495 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
496
497 /* domain sid */
498 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
499
500 return True;
501}
502
503/************************************************************************
504 Routine to set the trust account password for a domain.
505************************************************************************/
506
507BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
508{
509 struct machine_acct_pass pass;
510
511 pass.mod_time = time(NULL);
512 memcpy(pass.hash, new_pwd, 16);
513
514 return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
515}
516
517/**
518 * Routine to store the password for trusted domain
519 *
520 * @param domain remote domain name
521 * @param pwd plain text password of trust relationship
522 * @param sid remote domain sid
523 *
524 * @return true if succeeded
525 **/
526
527BOOL secrets_store_trusted_domain_password(const char* domain, const char* pwd,
528 const DOM_SID *sid)
529{
530 smb_ucs2_t *uni_dom_name;
531
532 /* packing structures */
533 pstring pass_buf;
534 int pass_len = 0;
535 int pass_buf_len = sizeof(pass_buf);
536
537 struct trusted_dom_pass pass;
538 ZERO_STRUCT(pass);
539
540 if (push_ucs2_allocate(&uni_dom_name, domain) == (size_t)-1) {
541 DEBUG(0, ("Could not convert domain name %s to unicode\n",
542 domain));
543 return False;
544 }
545
546 strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
547 pass.uni_name_len = strlen_w(uni_dom_name)+1;
548 SAFE_FREE(uni_dom_name);
549
550 /* last change time */
551 pass.mod_time = time(NULL);
552
553 /* password of the trust */
554 pass.pass_len = strlen(pwd);
555 fstrcpy(pass.pass, pwd);
556
557 /* domain sid */
558 sid_copy(&pass.domain_sid, sid);
559
560 pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
561
562 return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
563}
564
565/************************************************************************
566 Routine to set the plaintext machine account password for a realm
567the password is assumed to be a null terminated ascii string
568************************************************************************/
569
570BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
571{
572 char *key = NULL;
573 BOOL ret;
574 uint32 last_change_time;
575 uint32 sec_channel_type;
576
577 asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
578 if (!key)
579 return False;
580 strupper_m(key);
581
582 ret = secrets_store(key, pass, strlen(pass)+1);
583 SAFE_FREE(key);
584
585 if (!ret)
586 return ret;
587
588 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
589 if (!key)
590 return False;
591 strupper_m(key);
592
593 SIVAL(&last_change_time, 0, time(NULL));
594 ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
595 SAFE_FREE(key);
596
597 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
598 if (!key)
599 return False;
600 strupper_m(key);
601
602 SIVAL(&sec_channel_type, 0, sec_channel);
603 ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
604 SAFE_FREE(key);
605
606 return ret;
607}
608
609/************************************************************************
610 Routine to fetch the plaintext machine account password for a realm
611 the password is assumed to be a null terminated ascii string.
612************************************************************************/
613
614char *secrets_fetch_machine_password(const char *domain,
615 time_t *pass_last_set_time,
616 uint32 *channel)
617{
618 char *key = NULL;
619 char *ret;
620 asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
621 strupper_m(key);
622 ret = (char *)secrets_fetch(key, NULL);
623 SAFE_FREE(key);
624
625 if (pass_last_set_time) {
626 size_t size;
627 uint32 *last_set_time;
628 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
629 strupper_m(key);
630 last_set_time = (unsigned int *)secrets_fetch(key, &size);
631 if (last_set_time) {
632 *pass_last_set_time = IVAL(last_set_time,0);
633 SAFE_FREE(last_set_time);
634 } else {
635 *pass_last_set_time = 0;
636 }
637 SAFE_FREE(key);
638 }
639
640 if (channel) {
641 size_t size;
642 uint32 *channel_type;
643 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
644 strupper_m(key);
645 channel_type = (unsigned int *)secrets_fetch(key, &size);
646 if (channel_type) {
647 *channel = IVAL(channel_type,0);
648 SAFE_FREE(channel_type);
649 } else {
650 *channel = get_default_sec_channel();
651 }
652 SAFE_FREE(key);
653 }
654
655 return ret;
656}
657
658/*******************************************************************
659 Wrapper around retrieving the trust account password
660*******************************************************************/
661
662BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], uint32 *channel)
663{
664 DOM_SID sid;
665 char *pwd;
666 time_t last_set_time;
667
668 /* if we are a DC and this is not our domain, then lookup an account
669 for the domain trust */
670
671 if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) {
672 if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
673 &last_set_time)) {
674 DEBUG(0, ("get_trust_pw: could not fetch trust "
675 "account password for trusted domain %s\n",
676 domain));
677 return False;
678 }
679
680 *channel = SEC_CHAN_DOMAIN;
681 E_md4hash(pwd, ret_pwd);
682 SAFE_FREE(pwd);
683
684 return True;
685 }
686
687 /* Just get the account for the requested domain. In the future this
688 * might also cover to be member of more than one domain. */
689
690 if (secrets_fetch_trust_account_password(domain, ret_pwd,
691 &last_set_time, channel))
692 return True;
693
694 DEBUG(5, ("get_trust_pw: could not fetch trust account "
695 "password for domain %s\n", domain));
696 return False;
697}
698
699/************************************************************************
700 Routine to delete the machine trust account password file for a domain.
701************************************************************************/
702
703BOOL trust_password_delete(const char *domain)
704{
705 return secrets_delete(trust_keystr(domain));
706}
707
708/************************************************************************
709 Routine to delete the password for trusted domain
710************************************************************************/
711
712BOOL trusted_domain_password_delete(const char *domain)
713{
714 return secrets_delete(trustdom_keystr(domain));
715}
716
717BOOL secrets_store_ldap_pw(const char* dn, char* pw)
718{
719 char *key = NULL;
720 BOOL ret;
721
722 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
723 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
724 return False;
725 }
726
727 ret = secrets_store(key, pw, strlen(pw)+1);
728
729 SAFE_FREE(key);
730 return ret;
731}
732
733/*******************************************************************
734 Find the ldap password.
735******************************************************************/
736
737BOOL fetch_ldap_pw(char **dn, char** pw)
738{
739 char *key = NULL;
740 size_t size = 0;
741
742 *dn = smb_xstrdup(lp_ldap_admin_dn());
743
744 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
745 SAFE_FREE(*dn);
746 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
747 }
748
749 *pw=(char *)secrets_fetch(key, &size);
750 SAFE_FREE(key);
751
752 if (!size) {
753 /* Upgrade 2.2 style entry */
754 char *p;
755 char* old_style_key = SMB_STRDUP(*dn);
756 char *data;
757 fstring old_style_pw;
758
759 if (!old_style_key) {
760 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
761 return False;
762 }
763
764 for (p=old_style_key; *p; p++)
765 if (*p == ',') *p = '/';
766
767 data=(char *)secrets_fetch(old_style_key, &size);
768 if (!size && size < sizeof(old_style_pw)) {
769 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
770 SAFE_FREE(old_style_key);
771 SAFE_FREE(*dn);
772 return False;
773 }
774
775 size = MIN(size, sizeof(fstring)-1);
776 strncpy(old_style_pw, data, size);
777 old_style_pw[size] = 0;
778
779 SAFE_FREE(data);
780
781 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
782 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
783 SAFE_FREE(old_style_key);
784 SAFE_FREE(*dn);
785 return False;
786 }
787 if (!secrets_delete(old_style_key)) {
788 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
789 }
790
791 SAFE_FREE(old_style_key);
792
793 *pw = smb_xstrdup(old_style_pw);
794 }
795
796 return True;
797}
798
799/**
800 * Get trusted domains info from secrets.tdb.
801 **/
802
803NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
804 struct trustdom_info ***domains)
805{
806 TDB_LIST_NODE *keys, *k;
807 char *pattern;
808 TALLOC_CTX *tmp_ctx;
809
810 if (!(tmp_ctx = talloc_new(mem_ctx))) {
811 return NT_STATUS_NO_MEMORY;
812 }
813
814 if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
815
816 /* generate searching pattern */
817 pattern = talloc_asprintf(tmp_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
818 if (pattern == NULL) {
819 DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
820 "failed!\n"));
821 TALLOC_FREE(tmp_ctx);
822 return NT_STATUS_NO_MEMORY;
823 }
824
825 *num_domains = 0;
826
827 /*
828 * Make sure that a talloc context for the trustdom_info structs
829 * exists
830 */
831
832 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
833 TALLOC_FREE(tmp_ctx);
834 return NT_STATUS_NO_MEMORY;
835 }
836
837 /* fetching trusted domains' data and collecting them in a list */
838 keys = tdb_search_keys(tdb, pattern);
839
840 /* searching for keys in secrets db -- way to go ... */
841 for (k = keys; k; k = k->next) {
842 char *packed_pass;
843 size_t size = 0, packed_size = 0;
844 struct trusted_dom_pass pass;
845 char *secrets_key;
846 struct trustdom_info *dom_info;
847
848 /* important: ensure null-termination of the key string */
849 secrets_key = talloc_strndup(tmp_ctx,
850 k->node_key.dptr,
851 k->node_key.dsize);
852 if (!secrets_key) {
853 DEBUG(0, ("strndup failed!\n"));
854 tdb_search_list_free(keys);
855 TALLOC_FREE(tmp_ctx);
856 return NT_STATUS_NO_MEMORY;
857 }
858
859 packed_pass = (char *)secrets_fetch(secrets_key, &size);
860 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
861 &pass);
862 /* packed representation isn't needed anymore */
863 SAFE_FREE(packed_pass);
864
865 if (size != packed_size) {
866 DEBUG(2, ("Secrets record %s is invalid!\n",
867 secrets_key));
868 continue;
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_static(&pass.domain_sid),
875 pass.domain_sid.num_auths));
876 continue;
877 }
878
879 if (!(dom_info = TALLOC_P(*domains, struct trustdom_info))) {
880 DEBUG(0, ("talloc failed\n"));
881 tdb_search_list_free(keys);
882 TALLOC_FREE(tmp_ctx);
883 return NT_STATUS_NO_MEMORY;
884 }
885
886 if (pull_ucs2_talloc(dom_info, &dom_info->name,
887 pass.uni_name) == (size_t)-1) {
888 DEBUG(2, ("pull_ucs2_talloc failed\n"));
889 tdb_search_list_free(keys);
890 TALLOC_FREE(tmp_ctx);
891 return NT_STATUS_NO_MEMORY;
892 }
893
894 sid_copy(&dom_info->sid, &pass.domain_sid);
895
896 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
897 domains, num_domains);
898
899 if (*domains == NULL) {
900 tdb_search_list_free(keys);
901 TALLOC_FREE(tmp_ctx);
902 return NT_STATUS_NO_MEMORY;
903 }
904 }
905
906 DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
907 *num_domains));
908
909 /* free the results of searching the keys */
910 tdb_search_list_free(keys);
911 TALLOC_FREE(tmp_ctx);
912
913 return NT_STATUS_OK;
914}
915
916/*******************************************************************************
917 Lock the secrets tdb based on a string - this is used as a primitive form of mutex
918 between smbd instances.
919*******************************************************************************/
920
921BOOL secrets_named_mutex(const char *name, unsigned int timeout)
922{
923 int ret = 0;
924
925 if (!secrets_init())
926 return False;
927
928 ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
929 if (ret == 0)
930 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
931
932 return (ret == 0);
933}
934
935/*******************************************************************************
936 Unlock a named mutex.
937*******************************************************************************/
938
939void secrets_named_mutex_release(const char *name)
940{
941 tdb_unlock_bystring(tdb, name);
942 DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
943}
944
945/*******************************************************************************
946 Store a complete AFS keyfile into secrets.tdb.
947*******************************************************************************/
948
949BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
950{
951 fstring key;
952
953 if ((cell == NULL) || (keyfile == NULL))
954 return False;
955
956 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
957 return False;
958
959 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
960 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
961}
962
963/*******************************************************************************
964 Fetch the current (highest) AFS key from secrets.tdb
965*******************************************************************************/
966BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
967{
968 fstring key;
969 struct afs_keyfile *keyfile;
970 size_t size = 0;
971 uint32 i;
972
973 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
974
975 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
976
977 if (keyfile == NULL)
978 return False;
979
980 if (size != sizeof(struct afs_keyfile)) {
981 SAFE_FREE(keyfile);
982 return False;
983 }
984
985 i = ntohl(keyfile->nkeys);
986
987 if (i > SECRETS_AFS_MAXKEYS) {
988 SAFE_FREE(keyfile);
989 return False;
990 }
991
992 *result = keyfile->entry[i-1];
993
994 result->kvno = ntohl(result->kvno);
995
996 return True;
997}
998
999/******************************************************************************
1000 When kerberos is not available, choose between anonymous or
1001 authenticated connections.
1002
1003 We need to use an authenticated connection if DCs have the
1004 RestrictAnonymous registry entry set > 0, or the "Additional
1005 restrictions for anonymous connections" set in the win2k Local
1006 Security Policy.
1007
1008 Caller to free() result in domain, username, password
1009*******************************************************************************/
1010void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
1011{
1012 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
1013 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
1014 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
1015
1016 if (*username && **username) {
1017
1018 if (!*domain || !**domain)
1019 *domain = smb_xstrdup(lp_workgroup());
1020
1021 if (!*password || !**password)
1022 *password = smb_xstrdup("");
1023
1024 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
1025 *domain, *username));
1026
1027 } else {
1028 DEBUG(3, ("IPC$ connections done anonymously\n"));
1029 *username = smb_xstrdup("");
1030 *domain = smb_xstrdup("");
1031 *password = smb_xstrdup("");
1032 }
1033}
1034
1035/******************************************************************************
1036 Open or create the schannel session store tdb.
1037*******************************************************************************/
1038
1039static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
1040{
1041 TDB_DATA vers;
1042 uint32 ver;
1043 TDB_CONTEXT *tdb_sc = NULL;
1044 char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
1045
1046 if (!fname) {
1047 return NULL;
1048 }
1049
1050 tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
1051
1052 if (!tdb_sc) {
1053 DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
1054 TALLOC_FREE(fname);
1055 return NULL;
1056 }
1057
1058 vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
1059 if (vers.dptr == NULL) {
1060 /* First opener, no version. */
1061 SIVAL(&ver,0,1);
1062 vers.dptr = (char *)&ver;
1063 vers.dsize = 4;
1064 tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
1065 vers.dptr = NULL;
1066 } else if (vers.dsize == 4) {
1067 ver = IVAL(vers.dptr,0);
1068 if (ver != 1) {
1069 tdb_close(tdb_sc);
1070 tdb_sc = NULL;
1071 DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
1072 (int)ver, fname ));
1073 }
1074 } else {
1075 tdb_close(tdb_sc);
1076 tdb_sc = NULL;
1077 DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
1078 (int)vers.dsize, fname ));
1079 }
1080
1081 SAFE_FREE(vers.dptr);
1082 TALLOC_FREE(fname);
1083
1084 return tdb_sc;
1085}
1086
1087/******************************************************************************
1088 Store the schannel state after an AUTH2 call.
1089 Note we must be root here.
1090*******************************************************************************/
1091
1092BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
1093 const char *remote_machine,
1094 const struct dcinfo *pdc)
1095{
1096 TDB_CONTEXT *tdb_sc = NULL;
1097 TDB_DATA value;
1098 BOOL ret;
1099 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1100 remote_machine);
1101 if (!keystr) {
1102 return False;
1103 }
1104
1105 strupper_m(keystr);
1106
1107 /* Work out how large the record is. */
1108 value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
1109 pdc->sequence,
1110 8, pdc->seed_chal.data,
1111 8, pdc->clnt_chal.data,
1112 8, pdc->srv_chal.data,
1113 16, pdc->sess_key,
1114 16, pdc->mach_pw,
1115 pdc->mach_acct,
1116 pdc->remote_machine,
1117 pdc->domain);
1118
1119 value.dptr = (char *)TALLOC(mem_ctx, value.dsize);
1120 if (!value.dptr) {
1121 TALLOC_FREE(keystr);
1122 return False;
1123 }
1124
1125 value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
1126 pdc->sequence,
1127 8, pdc->seed_chal.data,
1128 8, pdc->clnt_chal.data,
1129 8, pdc->srv_chal.data,
1130 16, pdc->sess_key,
1131 16, pdc->mach_pw,
1132 pdc->mach_acct,
1133 pdc->remote_machine,
1134 pdc->domain);
1135
1136 tdb_sc = open_schannel_session_store(mem_ctx);
1137 if (!tdb_sc) {
1138 TALLOC_FREE(keystr);
1139 TALLOC_FREE(value.dptr);
1140 return False;
1141 }
1142
1143 ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
1144
1145 DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
1146 keystr ));
1147
1148 tdb_close(tdb_sc);
1149 TALLOC_FREE(keystr);
1150 TALLOC_FREE(value.dptr);
1151 return ret;
1152}
1153
1154/******************************************************************************
1155 Restore the schannel state on a client reconnect.
1156 Note we must be root here.
1157*******************************************************************************/
1158
1159BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
1160 const char *remote_machine,
1161 struct dcinfo **ppdc)
1162{
1163 TDB_CONTEXT *tdb_sc = NULL;
1164 TDB_DATA value;
1165 unsigned char *pseed_chal = NULL;
1166 unsigned char *pclnt_chal = NULL;
1167 unsigned char *psrv_chal = NULL;
1168 unsigned char *psess_key = NULL;
1169 unsigned char *pmach_pw = NULL;
1170 uint32 l1, l2, l3, l4, l5;
1171 int ret;
1172 struct dcinfo *pdc = NULL;
1173 char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
1174 remote_machine);
1175
1176 *ppdc = NULL;
1177
1178 if (!keystr) {
1179 return False;
1180 }
1181
1182 strupper_m(keystr);
1183
1184 tdb_sc = open_schannel_session_store(mem_ctx);
1185 if (!tdb_sc) {
1186 TALLOC_FREE(keystr);
1187 return False;
1188 }
1189
1190 value = tdb_fetch_bystring(tdb_sc, keystr);
1191 if (!value.dptr) {
1192 DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
1193 keystr ));
1194 tdb_close(tdb_sc);
1195 return False;
1196 }
1197
1198 pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
1199
1200 /* Retrieve the record. */
1201 ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
1202 &pdc->sequence,
1203 &l1, &pseed_chal,
1204 &l2, &pclnt_chal,
1205 &l3, &psrv_chal,
1206 &l4, &psess_key,
1207 &l5, &pmach_pw,
1208 &pdc->mach_acct,
1209 &pdc->remote_machine,
1210 &pdc->domain);
1211
1212 if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
1213 /* Bad record - delete it. */
1214 tdb_delete_bystring(tdb_sc, keystr);
1215 tdb_close(tdb_sc);
1216 TALLOC_FREE(keystr);
1217 TALLOC_FREE(pdc);
1218 SAFE_FREE(pseed_chal);
1219 SAFE_FREE(pclnt_chal);
1220 SAFE_FREE(psrv_chal);
1221 SAFE_FREE(psess_key);
1222 SAFE_FREE(pmach_pw);
1223 SAFE_FREE(value.dptr);
1224 return False;
1225 }
1226
1227 tdb_close(tdb_sc);
1228
1229 memcpy(pdc->seed_chal.data, pseed_chal, 8);
1230 memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
1231 memcpy(pdc->srv_chal.data, psrv_chal, 8);
1232 memcpy(pdc->sess_key, psess_key, 16);
1233 memcpy(pdc->mach_pw, pmach_pw, 16);
1234
1235 /* We know these are true so didn't bother to store them. */
1236 pdc->challenge_sent = True;
1237 pdc->authenticated = True;
1238
1239 DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
1240 keystr ));
1241
1242 SAFE_FREE(pseed_chal);
1243 SAFE_FREE(pclnt_chal);
1244 SAFE_FREE(psrv_chal);
1245 SAFE_FREE(psess_key);
1246 SAFE_FREE(pmach_pw);
1247
1248 TALLOC_FREE(keystr);
1249 SAFE_FREE(value.dptr);
1250
1251 *ppdc = pdc;
1252
1253 return True;
1254}
1255
1256BOOL secrets_store_generic(const char *owner, const char *key, const char *secret)
1257{
1258 char *tdbkey = NULL;
1259 BOOL ret;
1260
1261 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1262 DEBUG(0, ("asprintf failed!\n"));
1263 return False;
1264 }
1265
1266 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
1267
1268 SAFE_FREE(tdbkey);
1269 return ret;
1270}
1271
1272/*******************************************************************
1273 Find the ldap password.
1274******************************************************************/
1275
1276char *secrets_fetch_generic(const char *owner, const char *key)
1277{
1278 char *secret = NULL;
1279 char *tdbkey = NULL;
1280
1281 if (( ! owner) || ( ! key)) {
1282 DEBUG(1, ("Invalid Paramters"));
1283 return NULL;
1284 }
1285
1286 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
1287 DEBUG(0, ("Out of memory!\n"));
1288 return NULL;
1289 }
1290
1291 secret = (char *)secrets_fetch(tdbkey, NULL);
1292 SAFE_FREE(tdbkey);
1293
1294 return secret;
1295}
1296
Note: See TracBrowser for help on using the repository browser.