r3948: Fix incorrect declaration. Bug #2083.
[samba.git] / source / passdb / secrets.c
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
31 static TDB_CONTEXT *tdb;
32
33 /**
34  * Use a TDB to store an incrementing random seed.
35  *
36  * Initialised to the current pid, the very first time Samba starts,
37  * and incremented by one each time it is needed.  
38  * 
39  * @note Not called by systems with a working /dev/urandom.
40  */
41 static void get_rand_seed(int *new_seed) 
42 {
43         *new_seed = sys_getpid();
44         if (tdb) {
45                 tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
46         }
47 }
48
49 /* open up the secrets database */
50 BOOL secrets_init(void)
51 {
52         pstring fname;
53         unsigned char dummy;
54
55         if (tdb)
56                 return True;
57
58         pstrcpy(fname, lp_private_dir());
59         pstrcat(fname,"/secrets.tdb");
60
61         tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
62
63         if (!tdb) {
64                 DEBUG(0,("Failed to open %s\n", fname));
65                 return False;
66         }
67
68         /**
69          * Set a reseed function for the crypto random generator 
70          * 
71          * This avoids a problem where systems without /dev/urandom
72          * could send the same challenge to multiple clients
73          */
74         set_rand_reseed_callback(get_rand_seed);
75
76         /* Ensure that the reseed is done now, while we are root, etc */
77         generate_random_buffer(&dummy, sizeof(dummy));
78
79         return True;
80 }
81
82 /* read a entry from the secrets database - the caller must free the result
83    if size is non-null then the size of the entry is put in there
84  */
85 void *secrets_fetch(const char *key, size_t *size)
86 {
87         TDB_DATA kbuf, dbuf;
88         secrets_init();
89         if (!tdb)
90                 return NULL;
91         kbuf.dptr = (char *)key;
92         kbuf.dsize = strlen(key);
93         dbuf = tdb_fetch(tdb, kbuf);
94         if (size)
95                 *size = dbuf.dsize;
96         return dbuf.dptr;
97 }
98
99 /* store a secrets entry 
100  */
101 BOOL secrets_store(const char *key, const void *data, size_t size)
102 {
103         TDB_DATA kbuf, dbuf;
104         secrets_init();
105         if (!tdb)
106                 return False;
107         kbuf.dptr = (char *)key;
108         kbuf.dsize = strlen(key);
109         dbuf.dptr = (char *)data;
110         dbuf.dsize = size;
111         return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0;
112 }
113
114
115 /* delete a secets database entry
116  */
117 BOOL secrets_delete(const char *key)
118 {
119         TDB_DATA kbuf;
120         secrets_init();
121         if (!tdb)
122                 return False;
123         kbuf.dptr = (char *)key;
124         kbuf.dsize = strlen(key);
125         return tdb_delete(tdb, kbuf) == 0;
126 }
127
128 BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
129 {
130         fstring key;
131         BOOL ret;
132
133         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
134         strupper_m(key);
135         ret = secrets_store(key, sid, sizeof(DOM_SID));
136
137         /* Force a re-query, in case we modified our domain */
138         if (ret)
139                 reset_global_sam_sid();
140         return ret;
141 }
142
143 BOOL secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
144 {
145         DOM_SID *dyn_sid;
146         fstring key;
147         size_t size;
148
149         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_SID, domain);
150         strupper_m(key);
151         dyn_sid = (DOM_SID *)secrets_fetch(key, &size);
152
153         if (dyn_sid == NULL)
154                 return False;
155
156         if (size != sizeof(DOM_SID))
157         { 
158                 SAFE_FREE(dyn_sid);
159                 return False;
160         }
161
162         *sid = *dyn_sid;
163         SAFE_FREE(dyn_sid);
164         return True;
165 }
166
167 BOOL secrets_store_domain_guid(const char *domain, struct uuid *guid)
168 {
169         fstring key;
170
171         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
172         strupper_m(key);
173         return secrets_store(key, guid, sizeof(struct uuid));
174 }
175
176 BOOL secrets_fetch_domain_guid(const char *domain, struct uuid *guid)
177 {
178         struct uuid *dyn_guid;
179         fstring key;
180         size_t size;
181         struct uuid new_guid;
182
183         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
184         strupper_m(key);
185         dyn_guid = (struct uuid *)secrets_fetch(key, &size);
186
187         if ((!dyn_guid) && (lp_server_role() == ROLE_DOMAIN_PDC)) {
188                 smb_uuid_generate_random(&new_guid);
189                 if (!secrets_store_domain_guid(domain, &new_guid))
190                         return False;
191                 dyn_guid = (struct uuid *)secrets_fetch(key, &size);
192                 if (dyn_guid == NULL)
193                         return False;
194         }
195
196         if (size != sizeof(struct uuid))
197         { 
198                 DEBUG(1,("UUID size %d is wrong!\n", (int)size));
199                 SAFE_FREE(dyn_guid);
200                 return False;
201         }
202
203         *guid = *dyn_guid;
204         SAFE_FREE(dyn_guid);
205         return True;
206 }
207
208 /**
209  * Form a key for fetching the machine trust account password
210  *
211  * @param domain domain name
212  *
213  * @return stored password's key
214  **/
215 const char *trust_keystr(const char *domain)
216 {
217         static fstring keystr;
218
219         slprintf(keystr,sizeof(keystr)-1,"%s/%s", 
220                  SECRETS_MACHINE_ACCT_PASS, domain);
221         strupper_m(keystr);
222
223         return keystr;
224 }
225
226 /**
227  * Form a key for fetching a trusted domain password
228  *
229  * @param domain trusted domain name
230  *
231  * @return stored password's key
232  **/
233 static char *trustdom_keystr(const char *domain)
234 {
235         static pstring keystr;
236
237         pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
238         strupper_m(keystr);
239                 
240         return keystr;
241 }
242
243 /************************************************************************
244  Lock the trust password entry.
245 ************************************************************************/
246
247 BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
248 {
249         if (!tdb)
250                 return False;
251
252         if (dolock)
253                 return (tdb_lock_bystring(tdb, trust_keystr(domain),0) == 0);
254         else
255                 tdb_unlock_bystring(tdb, trust_keystr(domain));
256         return True;
257 }
258
259 /************************************************************************
260  Routine to get the default secure channel type for trust accounts
261 ************************************************************************/
262
263 uint32 get_default_sec_channel(void) 
264 {
265         if (lp_server_role() == ROLE_DOMAIN_BDC || 
266             lp_server_role() == ROLE_DOMAIN_PDC) {
267                 return SEC_CHAN_BDC;
268         } else {
269                 return SEC_CHAN_WKSTA;
270         }
271 }
272
273 /************************************************************************
274  Routine to get the trust account password for a domain.
275  The user of this function must have locked the trust password file using
276  the above secrets_lock_trust_account_password().
277 ************************************************************************/
278
279 BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
280                                           time_t *pass_last_set_time,
281                                           uint32 *channel)
282 {
283         struct machine_acct_pass *pass;
284         char *plaintext;
285         size_t size;
286
287         plaintext = secrets_fetch_machine_password(domain, pass_last_set_time, 
288                                                    channel);
289         if (plaintext) {
290                 DEBUG(4,("Using cleartext machine password\n"));
291                 E_md4hash(plaintext, ret_pwd);
292                 SAFE_FREE(plaintext);
293                 return True;
294         }
295
296         if (!(pass = secrets_fetch(trust_keystr(domain), &size))) {
297                 DEBUG(5, ("secrets_fetch failed!\n"));
298                 return False;
299         }
300         
301         if (size != sizeof(*pass)) {
302                 DEBUG(0, ("secrets were of incorrect size!\n"));
303                 return False;
304         }
305
306         if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
307         memcpy(ret_pwd, pass->hash, 16);
308         SAFE_FREE(pass);
309
310         if (channel) 
311                 *channel = get_default_sec_channel();
312
313         return True;
314 }
315
316 /************************************************************************
317  Routine to get account password to trusted domain
318 ************************************************************************/
319
320 BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
321                                            DOM_SID *sid, time_t *pass_last_set_time)
322 {
323         struct trusted_dom_pass pass;
324         size_t size;
325         
326         /* unpacking structures */
327         char* pass_buf;
328         int pass_len = 0;
329
330         ZERO_STRUCT(pass);
331
332         /* fetching trusted domain password structure */
333         if (!(pass_buf = secrets_fetch(trustdom_keystr(domain), &size))) {
334                 DEBUG(5, ("secrets_fetch failed!\n"));
335                 return False;
336         }
337
338         /* unpack trusted domain password */
339         pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
340         SAFE_FREE(pass_buf);
341
342         if (pass_len != size) {
343                 DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
344                 return False;
345         }
346                         
347         /* the trust's password */      
348         if (pwd) {
349                 *pwd = strdup(pass.pass);
350                 if (!*pwd) {
351                         return False;
352                 }
353         }
354
355         /* last change time */
356         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
357
358         /* domain sid */
359         sid_copy(sid, &pass.domain_sid);
360                 
361         return True;
362 }
363
364 /************************************************************************
365  Routine to set the trust account password for a domain.
366 ************************************************************************/
367
368 BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
369 {
370         struct machine_acct_pass pass;
371
372         pass.mod_time = time(NULL);
373         memcpy(pass.hash, new_pwd, 16);
374
375         return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
376 }
377
378 /**
379  * Routine to store the password for trusted domain
380  *
381  * @param domain remote domain name
382  * @param pwd plain text password of trust relationship
383  * @param sid remote domain sid
384  *
385  * @return true if succeeded
386  **/
387
388 BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_dom_name,
389                                            size_t uni_name_len, const char* pwd,
390                                            DOM_SID sid)
391 {       
392         /* packing structures */
393         pstring pass_buf;
394         int pass_len = 0;
395         int pass_buf_len = sizeof(pass_buf);
396         
397         struct trusted_dom_pass pass;
398         ZERO_STRUCT(pass);
399         
400         /* unicode domain name and its length */
401         if (!uni_dom_name)
402                 return False;
403                 
404         strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
405         pass.uni_name_len = uni_name_len;
406
407         /* last change time */
408         pass.mod_time = time(NULL);
409
410         /* password of the trust */
411         pass.pass_len = strlen(pwd);
412         fstrcpy(pass.pass, pwd);
413
414         /* domain sid */
415         sid_copy(&pass.domain_sid, &sid);
416         
417         pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
418
419         return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len);
420 }
421
422 /************************************************************************
423  Routine to set the plaintext machine account password for a realm
424 the password is assumed to be a null terminated ascii string
425 ************************************************************************/
426
427 BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
428 {
429         char *key = NULL;
430         BOOL ret;
431         uint32 last_change_time;
432         uint32 sec_channel_type;
433
434         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
435         if (!key) 
436                 return False;
437         strupper_m(key);
438
439         ret = secrets_store(key, pass, strlen(pass)+1);
440         SAFE_FREE(key);
441
442         if (!ret)
443                 return ret;
444         
445         asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
446         if (!key) 
447                 return False;
448         strupper_m(key);
449
450         SIVAL(&last_change_time, 0, time(NULL));
451         ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
452         SAFE_FREE(key);
453
454         asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
455         if (!key) 
456                 return False;
457         strupper_m(key);
458
459         SIVAL(&sec_channel_type, 0, sec_channel);
460         ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
461         SAFE_FREE(key);
462
463         return ret;
464 }
465
466
467 /************************************************************************
468  Routine to fetch the plaintext machine account password for a realm
469 the password is assumed to be a null terminated ascii string
470 ************************************************************************/
471 char *secrets_fetch_machine_password(const char *domain, 
472                                      time_t *pass_last_set_time,
473                                      uint32 *channel)
474 {
475         char *key = NULL;
476         char *ret;
477         asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
478         strupper_m(key);
479         ret = (char *)secrets_fetch(key, NULL);
480         SAFE_FREE(key);
481         
482         if (pass_last_set_time) {
483                 size_t size;
484                 uint32 *last_set_time;
485                 asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
486                 strupper_m(key);
487                 last_set_time = secrets_fetch(key, &size);
488                 if (last_set_time) {
489                         *pass_last_set_time = IVAL(last_set_time,0);
490                         SAFE_FREE(last_set_time);
491                 } else {
492                         *pass_last_set_time = 0;
493                 }
494                 SAFE_FREE(key);
495         }
496         
497         if (channel) {
498                 size_t size;
499                 uint32 *channel_type;
500                 asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
501                 strupper_m(key);
502                 channel_type = secrets_fetch(key, &size);
503                 if (channel_type) {
504                         *channel = IVAL(channel_type,0);
505                         SAFE_FREE(channel_type);
506                 } else {
507                         *channel = get_default_sec_channel();
508                 }
509                 SAFE_FREE(key);
510         }
511         
512         return ret;
513 }
514
515
516
517 /************************************************************************
518  Routine to delete the machine trust account password file for a domain.
519 ************************************************************************/
520
521 BOOL trust_password_delete(const char *domain)
522 {
523         return secrets_delete(trust_keystr(domain));
524 }
525
526 /************************************************************************
527  Routine to delete the password for trusted domain
528 ************************************************************************/
529
530 BOOL trusted_domain_password_delete(const char *domain)
531 {
532         return secrets_delete(trustdom_keystr(domain));
533 }
534
535
536 BOOL secrets_store_ldap_pw(const char* dn, char* pw)
537 {
538         char *key = NULL;
539         BOOL ret;
540         
541         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
542                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
543                 return False;
544         }
545                 
546         ret = secrets_store(key, pw, strlen(pw)+1);
547         
548         SAFE_FREE(key);
549         return ret;
550 }
551
552
553 /**
554  * Get trusted domains info from secrets.tdb.
555  *
556  * The linked list is allocated on the supplied talloc context, caller gets to destroy
557  * when done.
558  *
559  * @param ctx Allocation context
560  * @param enum_ctx Starting index, eg. we can start fetching at third
561  *        or sixth trusted domain entry. Zero is the first index.
562  *        Value it is set to is the enum context for the next enumeration.
563  * @param num_domains Number of domain entries to fetch at one call
564  * @param domains Pointer to array of trusted domain structs to be filled up
565  *
566  * @return nt status code of rpc response
567  **/ 
568
569 NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned int max_num_domains,
570                                      int *num_domains, TRUSTDOM ***domains)
571 {
572         TDB_LIST_NODE *keys, *k;
573         TRUSTDOM *dom = NULL;
574         char *pattern;
575         unsigned int start_idx;
576         uint32 idx = 0;
577         size_t size, packed_size = 0;
578         fstring dom_name;
579         char *packed_pass;
580         struct trusted_dom_pass *pass = talloc_zero(ctx, sizeof(struct trusted_dom_pass));
581         NTSTATUS status;
582
583         if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
584         
585         if (!pass) {
586                 DEBUG(0, ("talloc_zero failed!\n"));
587                 return NT_STATUS_NO_MEMORY;
588         }
589                                 
590         *num_domains = 0;
591         start_idx = *enum_ctx;
592
593         /* generate searching pattern */
594         if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) {
595                 DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n"));
596                 return NT_STATUS_NO_MEMORY;
597         }
598
599         DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n", 
600                   max_num_domains, *enum_ctx));
601
602         *domains = talloc_zero(ctx, sizeof(**domains)*max_num_domains);
603
604         /* fetching trusted domains' data and collecting them in a list */
605         keys = tdb_search_keys(tdb, pattern);
606
607         /* 
608          * if there's no keys returned ie. no trusted domain,
609          * return "no more entries" code
610          */
611         status = NT_STATUS_NO_MORE_ENTRIES;
612
613         /* searching for keys in secrets db -- way to go ... */
614         for (k = keys; k; k = k->next) {
615                 char *secrets_key;
616                 
617                 /* important: ensure null-termination of the key string */
618                 secrets_key = strndup(k->node_key.dptr, k->node_key.dsize);
619                 if (!secrets_key) {
620                         DEBUG(0, ("strndup failed!\n"));
621                         return NT_STATUS_NO_MEMORY;
622                 }
623
624                 packed_pass = secrets_fetch(secrets_key, &size);
625                 packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass);
626                 /* packed representation isn't needed anymore */
627                 SAFE_FREE(packed_pass);
628                 
629                 if (size != packed_size) {
630                         DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key));
631                         continue;
632                 }
633                 
634                 pull_ucs2_fstring(dom_name, pass->uni_name);
635                 DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
636                            idx, dom_name, sid_string_static(&pass->domain_sid)));
637
638                 SAFE_FREE(secrets_key);
639
640                 if (idx >= start_idx && idx < start_idx + max_num_domains) {
641                         dom = talloc_zero(ctx, sizeof(*dom));
642                         if (!dom) {
643                                 /* free returned tdb record */
644                                 return NT_STATUS_NO_MEMORY;
645                         }
646                         
647                         /* copy domain sid */
648                         SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid));
649                         memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid));
650                         
651                         /* copy unicode domain name */
652                         dom->name = talloc_strdup_w(ctx, pass->uni_name);
653                         
654                         (*domains)[idx - start_idx] = dom;
655                         
656                         DEBUG(18, ("Secret record is in required range.\n \
657                                    start_idx = %d, max_num_domains = %d. Added to returned array.\n",
658                                    start_idx, max_num_domains));
659
660                         *enum_ctx = idx + 1;
661                         (*num_domains)++;
662                 
663                         /* set proper status code to return */
664                         if (k->next) {
665                                 /* there are yet some entries to enumerate */
666                                 status = STATUS_MORE_ENTRIES;
667                         } else {
668                                 /* this is the last entry in the whole enumeration */
669                                 status = NT_STATUS_OK;
670                         }
671                 } else {
672                         DEBUG(18, ("Secret is outside the required range.\n \
673                                    start_idx = %d, max_num_domains = %d. Not added to returned array\n",
674                                    start_idx, max_num_domains));
675                 }
676                 
677                 idx++;          
678         }
679         
680         DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
681
682         /* free the results of searching the keys */
683         tdb_search_list_free(keys);
684
685         return status;
686 }
687
688 /*******************************************************************************
689  Lock the secrets tdb based on a string - this is used as a primitive form of mutex
690  between smbd instances.
691 *******************************************************************************/
692
693 BOOL secrets_named_mutex(const char *name, unsigned int timeout)
694 {
695         int ret = 0;
696
697         if (!message_init())
698                 return False;
699
700         ret = tdb_lock_bystring(tdb, name, timeout);
701         if (ret == 0)
702                 DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
703
704         return (ret == 0);
705 }
706
707 /*******************************************************************************
708  Unlock a named mutex.
709 *******************************************************************************/
710
711 void secrets_named_mutex_release(const char *name)
712 {
713         tdb_unlock_bystring(tdb, name);
714         DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
715 }
716
717 /*********************************************************
718  Check to see if we must talk to the PDC to avoid sam 
719  sync delays
720  ********************************************************/
721  
722 BOOL must_use_pdc( const char *domain )
723 {
724         time_t  now = time(NULL);
725         time_t  last_change_time;
726         unsigned char   passwd[16];   
727         
728         if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) )
729                 return False;
730                 
731         /*
732          * If the time the machine password has changed
733          * was less than about 15 minutes then we need to contact
734          * the PDC only, as we cannot be sure domain replication
735          * has yet taken place. Bug found by Gerald (way to go
736          * Gerald !). JRA.
737          */
738          
739         if ( now - last_change_time < SAM_SYNC_WINDOW )
740                 return True;
741                 
742         return False;
743
744 }
745
746 /*******************************************************************************
747  Store a complete AFS keyfile into secrets.tdb.
748 *******************************************************************************/
749
750 BOOL secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
751 {
752         fstring key;
753
754         if ((cell == NULL) || (keyfile == NULL))
755                 return False;
756
757         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
758                 return False;
759
760         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
761         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
762 }
763
764 /*******************************************************************************
765  Fetch the current (highest) AFS key from secrets.tdb
766 *******************************************************************************/
767 BOOL secrets_fetch_afs_key(const char *cell, struct afs_key *result)
768 {
769         fstring key;
770         struct afs_keyfile *keyfile;
771         size_t size;
772         uint32 i;
773
774         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
775
776         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
777
778         if (keyfile == NULL)
779                 return False;
780
781         if (size != sizeof(struct afs_keyfile)) {
782                 SAFE_FREE(keyfile);
783                 return False;
784         }
785
786         i = ntohl(keyfile->nkeys);
787
788         if (i > SECRETS_AFS_MAXKEYS) {
789                 SAFE_FREE(keyfile);
790                 return False;
791         }
792
793         *result = keyfile->entry[i-1];
794
795         result->kvno = ntohl(result->kvno);
796
797         return True;
798 }
799
800 /******************************************************************************
801   When kerberos is not available, choose between anonymous or
802   authenticated connections.  
803
804   We need to use an authenticated connection if DCs have the
805   RestrictAnonymous registry entry set > 0, or the "Additional
806   restrictions for anonymous connections" set in the win2k Local
807   Security Policy.
808
809   Caller to free() result in domain, username, password
810 *******************************************************************************/
811 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
812 {
813         *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
814         *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
815         *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
816         
817         if (*username && **username) {
818
819                 if (!*domain || !**domain)
820                         *domain = smb_xstrdup(lp_workgroup());
821                 
822                 if (!*password || !**password)
823                         *password = smb_xstrdup("");
824
825                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n", 
826                           *domain, *username));
827
828         } else {
829                 DEBUG(3, ("IPC$ connections done anonymously\n"));
830                 *username = smb_xstrdup("");
831                 *domain = smb_xstrdup("");
832                 *password = smb_xstrdup("");
833         }
834 }
835