s3: Fix auth_netlogond to cope with netlogon_creds_CredentialState
[samba.git] / source3 / 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 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 #include "secrets.h"
29 #include "dbwrap.h"
30 #include "../libcli/security/security.h"
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_PASSDB
34
35 static struct db_context *db_ctx;
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  */
45 static 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 */
55 bool 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
94 struct 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  */
106 void 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  */
114 void *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  */
143 bool 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  */
160 bool 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 a trusted domain password
174  *
175  * @param domain trusted domain name
176  *
177  * @return stored password's key
178  **/
179 static char *trustdom_keystr(const char *domain)
180 {
181         char *keystr;
182
183         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
184                                             SECRETS_DOMTRUST_ACCT_PASS,
185                                             domain);
186         SMB_ASSERT(keystr != NULL);
187         return keystr;
188 }
189
190 /************************************************************************
191  Routine to get account password to trusted domain
192 ************************************************************************/
193
194 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
195                                            struct dom_sid *sid, time_t *pass_last_set_time)
196 {
197         struct TRUSTED_DOM_PASS pass;
198         enum ndr_err_code ndr_err;
199
200         /* unpacking structures */
201         DATA_BLOB blob;
202
203         /* fetching trusted domain password structure */
204         if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
205                                                    &blob.length))) {
206                 DEBUG(5, ("secrets_fetch failed!\n"));
207                 return False;
208         }
209
210         /* unpack trusted domain password */
211         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
212                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
213
214         SAFE_FREE(blob.data);
215
216         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
217                 return false;
218         }
219
220
221         /* the trust's password */
222         if (pwd) {
223                 *pwd = SMB_STRDUP(pass.pass);
224                 if (!*pwd) {
225                         return False;
226                 }
227         }
228
229         /* last change time */
230         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
231
232         /* domain sid */
233         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
234
235         return True;
236 }
237
238 /**
239  * Routine to store the password for trusted domain
240  *
241  * @param domain remote domain name
242  * @param pwd plain text password of trust relationship
243  * @param sid remote domain sid
244  *
245  * @return true if succeeded
246  **/
247
248 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
249                                            const struct dom_sid *sid)
250 {
251         bool ret;
252
253         /* packing structures */
254         DATA_BLOB blob;
255         enum ndr_err_code ndr_err;
256         struct TRUSTED_DOM_PASS pass;
257         ZERO_STRUCT(pass);
258
259         pass.uni_name = domain;
260         pass.uni_name_len = strlen(domain)+1;
261
262         /* last change time */
263         pass.mod_time = time(NULL);
264
265         /* password of the trust */
266         pass.pass_len = strlen(pwd);
267         pass.pass = pwd;
268
269         /* domain sid */
270         sid_copy(&pass.domain_sid, sid);
271
272         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
273                         (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
274         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
275                 return false;
276         }
277
278         ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
279
280         data_blob_free(&blob);
281
282         return ret;
283 }
284
285 /************************************************************************
286  Routine to delete the password for trusted domain
287 ************************************************************************/
288
289 bool trusted_domain_password_delete(const char *domain)
290 {
291         return secrets_delete(trustdom_keystr(domain));
292 }
293
294 bool secrets_store_ldap_pw(const char* dn, char* pw)
295 {
296         char *key = NULL;
297         bool ret;
298
299         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
300                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
301                 return False;
302         }
303
304         ret = secrets_store(key, pw, strlen(pw)+1);
305
306         SAFE_FREE(key);
307         return ret;
308 }
309
310 /*******************************************************************
311  Find the ldap password.
312 ******************************************************************/
313
314 bool fetch_ldap_pw(char **dn, char** pw)
315 {
316         char *key = NULL;
317         size_t size = 0;
318
319         *dn = smb_xstrdup(lp_ldap_admin_dn());
320
321         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
322                 SAFE_FREE(*dn);
323                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
324                 return false;
325         }
326
327         *pw=(char *)secrets_fetch(key, &size);
328         SAFE_FREE(key);
329
330         if (!size) {
331                 /* Upgrade 2.2 style entry */
332                 char *p;
333                 char* old_style_key = SMB_STRDUP(*dn);
334                 char *data;
335                 fstring old_style_pw;
336
337                 if (!old_style_key) {
338                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
339                         return False;
340                 }
341
342                 for (p=old_style_key; *p; p++)
343                         if (*p == ',') *p = '/';
344
345                 data=(char *)secrets_fetch(old_style_key, &size);
346                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
347                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
348                         SAFE_FREE(old_style_key);
349                         SAFE_FREE(*dn);
350                         SAFE_FREE(data);
351                         return False;
352                 }
353
354                 size = MIN(size, sizeof(fstring)-1);
355                 strncpy(old_style_pw, data, size);
356                 old_style_pw[size] = 0;
357
358                 SAFE_FREE(data);
359
360                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
361                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
362                         SAFE_FREE(old_style_key);
363                         SAFE_FREE(*dn);
364                         return False;
365                 }
366                 if (!secrets_delete(old_style_key)) {
367                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
368                 }
369
370                 SAFE_FREE(old_style_key);
371
372                 *pw = smb_xstrdup(old_style_pw);
373         }
374
375         return True;
376 }
377
378 /**
379  * Get trusted domains info from secrets.tdb.
380  **/
381
382 struct list_trusted_domains_state {
383         uint32 num_domains;
384         struct trustdom_info **domains;
385 };
386
387 static int list_trusted_domain(struct db_record *rec, void *private_data)
388 {
389         const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
390         struct TRUSTED_DOM_PASS pass;
391         enum ndr_err_code ndr_err;
392         DATA_BLOB blob;
393         struct trustdom_info *dom_info;
394
395         struct list_trusted_domains_state *state =
396                 (struct list_trusted_domains_state *)private_data;
397
398         if ((rec->key.dsize < prefix_len)
399             || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
400                         prefix_len) != 0)) {
401                 return 0;
402         }
403
404         blob = data_blob_const(rec->value.dptr, rec->value.dsize);
405
406         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
407                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
408         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
409                 return false;
410         }
411
412         if (pass.domain_sid.num_auths != 4) {
413                 DEBUG(0, ("SID %s is not a domain sid, has %d "
414                           "auths instead of 4\n",
415                           sid_string_dbg(&pass.domain_sid),
416                           pass.domain_sid.num_auths));
417                 return 0;
418         }
419
420         if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
421                 DEBUG(0, ("talloc failed\n"));
422                 return 0;
423         }
424
425         dom_info->name = talloc_strdup(dom_info, pass.uni_name);
426         if (!dom_info->name) {
427                 TALLOC_FREE(dom_info);
428                 return 0;
429         }
430
431         sid_copy(&dom_info->sid, &pass.domain_sid);
432
433         ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
434                      &state->domains, &state->num_domains);
435
436         if (state->domains == NULL) {
437                 state->num_domains = 0;
438                 return -1;
439         }
440         return 0;
441 }
442
443 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
444                                  struct trustdom_info ***domains)
445 {
446         struct list_trusted_domains_state state;
447
448         secrets_init();
449
450         if (db_ctx == NULL) {
451                 return NT_STATUS_ACCESS_DENIED;
452         }
453
454         state.num_domains = 0;
455
456         /*
457          * Make sure that a talloc context for the trustdom_info structs
458          * exists
459          */
460
461         if (!(state.domains = TALLOC_ARRAY(
462                       mem_ctx, struct trustdom_info *, 1))) {
463                 return NT_STATUS_NO_MEMORY;
464         }
465
466         db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
467
468         *num_domains = state.num_domains;
469         *domains = state.domains;
470         return NT_STATUS_OK;
471 }
472
473 /*******************************************************************************
474  Store a complete AFS keyfile into secrets.tdb.
475 *******************************************************************************/
476
477 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
478 {
479         fstring key;
480
481         if ((cell == NULL) || (keyfile == NULL))
482                 return False;
483
484         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
485                 return False;
486
487         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
488         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
489 }
490
491 /*******************************************************************************
492  Fetch the current (highest) AFS key from secrets.tdb
493 *******************************************************************************/
494 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
495 {
496         fstring key;
497         struct afs_keyfile *keyfile;
498         size_t size = 0;
499         uint32 i;
500
501         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
502
503         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
504
505         if (keyfile == NULL)
506                 return False;
507
508         if (size != sizeof(struct afs_keyfile)) {
509                 SAFE_FREE(keyfile);
510                 return False;
511         }
512
513         i = ntohl(keyfile->nkeys);
514
515         if (i > SECRETS_AFS_MAXKEYS) {
516                 SAFE_FREE(keyfile);
517                 return False;
518         }
519
520         *result = keyfile->entry[i-1];
521
522         result->kvno = ntohl(result->kvno);
523
524         SAFE_FREE(keyfile);
525
526         return True;
527 }
528
529 /******************************************************************************
530   When kerberos is not available, choose between anonymous or
531   authenticated connections.
532
533   We need to use an authenticated connection if DCs have the
534   RestrictAnonymous registry entry set > 0, or the "Additional
535   restrictions for anonymous connections" set in the win2k Local
536   Security Policy.
537
538   Caller to free() result in domain, username, password
539 *******************************************************************************/
540 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
541 {
542         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
543         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
544         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
545
546         if (*username && **username) {
547
548                 if (!*domain || !**domain)
549                         *domain = smb_xstrdup(lp_workgroup());
550
551                 if (!*password || !**password)
552                         *password = smb_xstrdup("");
553
554                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
555                           *domain, *username));
556
557         } else {
558                 DEBUG(3, ("IPC$ connections done anonymously\n"));
559                 *username = smb_xstrdup("");
560                 *domain = smb_xstrdup("");
561                 *password = smb_xstrdup("");
562         }
563 }
564
565 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
566 {
567         char *tdbkey = NULL;
568         bool ret;
569
570         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
571                 DEBUG(0, ("asprintf failed!\n"));
572                 return False;
573         }
574
575         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
576
577         SAFE_FREE(tdbkey);
578         return ret;
579 }
580
581 bool secrets_delete_generic(const char *owner, const char *key)
582 {
583         char *tdbkey = NULL;
584         bool ret;
585
586         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
587                 DEBUG(0, ("asprintf failed!\n"));
588                 return False;
589         }
590
591         ret = secrets_delete(tdbkey);
592
593         SAFE_FREE(tdbkey);
594         return ret;
595 }
596
597 /*******************************************************************
598  Find the ldap password.
599 ******************************************************************/
600
601 char *secrets_fetch_generic(const char *owner, const char *key)
602 {
603         char *secret = NULL;
604         char *tdbkey = NULL;
605
606         if (( ! owner) || ( ! key)) {
607                 DEBUG(1, ("Invalid Parameters"));
608                 return NULL;
609         }
610
611         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
612                 DEBUG(0, ("Out of memory!\n"));
613                 return NULL;
614         }
615
616         secret = (char *)secrets_fetch(tdbkey, NULL);
617         SAFE_FREE(tdbkey);
618
619         return secret;
620 }
621