source: trunk/server/source3/passdb/secrets.c@ 421

Last change on this file since 421 was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

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