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