a1337eac9d377514ca241a62238df1ffdcceb24f
[nivanova/samba-autobuild/.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 "system/filesys.h"
27 #include "passdb.h"
28 #include "../libcli/auth/libcli_auth.h"
29 #include "librpc/gen_ndr/ndr_secrets.h"
30 #include "secrets.h"
31 #include "dbwrap.h"
32 #include "../libcli/security/security.h"
33 #include "util_tdb.h"
34
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_PASSDB
37
38 static struct db_context *db_ctx;
39
40 /**
41  * Use a TDB to store an incrementing random seed.
42  *
43  * Initialised to the current pid, the very first time Samba starts,
44  * and incremented by one each time it is needed.
45  *
46  * @note Not called by systems with a working /dev/urandom.
47  */
48 static void get_rand_seed(void *userdata, int *new_seed)
49 {
50         *new_seed = sys_getpid();
51         if (db_ctx) {
52                 dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed",
53                                                  new_seed, 1);
54         }
55 }
56
57 /* open up the secrets database */
58 bool secrets_init(void)
59 {
60         char *fname = NULL;
61         unsigned char dummy;
62
63         if (db_ctx != NULL)
64                 return True;
65
66         fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
67                                 lp_private_dir());
68         if (fname == NULL) {
69                 return false;
70         }
71
72         db_ctx = db_open(NULL, fname, 0,
73                          TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
74
75         if (db_ctx == NULL) {
76                 DEBUG(0,("Failed to open %s\n", fname));
77                 TALLOC_FREE(fname);
78                 return False;
79         }
80
81         TALLOC_FREE(fname);
82
83         /**
84          * Set a reseed function for the crypto random generator
85          *
86          * This avoids a problem where systems without /dev/urandom
87          * could send the same challenge to multiple clients
88          */
89         set_rand_reseed_callback(get_rand_seed, NULL);
90
91         /* Ensure that the reseed is done now, while we are root, etc */
92         generate_random_buffer(&dummy, sizeof(dummy));
93
94         return True;
95 }
96
97 struct db_context *secrets_db_ctx(void)
98 {
99         if (!secrets_init()) {
100                 return NULL;
101         }
102
103         return db_ctx;
104 }
105
106 /*
107  * close secrets.tdb
108  */
109 void secrets_shutdown(void)
110 {
111         TALLOC_FREE(db_ctx);
112 }
113
114 /* read a entry from the secrets database - the caller must free the result
115    if size is non-null then the size of the entry is put in there
116  */
117 void *secrets_fetch(const char *key, size_t *size)
118 {
119         TDB_DATA dbuf;
120         void *result;
121
122         if (!secrets_init()) {
123                 return NULL;
124         }
125
126         if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
127                           &dbuf) != 0) {
128                 return NULL;
129         }
130
131         result = memdup(dbuf.dptr, dbuf.dsize);
132         if (result == NULL) {
133                 return NULL;
134         }
135         TALLOC_FREE(dbuf.dptr);
136
137         if (size) {
138                 *size = dbuf.dsize;
139         }
140
141         return result;
142 }
143
144 /* store a secrets entry
145  */
146 bool secrets_store(const char *key, const void *data, size_t size)
147 {
148         NTSTATUS status;
149
150         if (!secrets_init()) {
151                 return false;
152         }
153
154         status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
155                                     make_tdb_data((const uint8 *)data, size),
156                                     TDB_REPLACE);
157         return NT_STATUS_IS_OK(status);
158 }
159
160
161 /* delete a secets database entry
162  */
163 bool secrets_delete(const char *key)
164 {
165         NTSTATUS status;
166         if (!secrets_init()) {
167                 return false;
168         }
169
170         status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
171
172         return NT_STATUS_IS_OK(status);
173 }
174
175 /**
176  * Form a key for fetching a trusted domain password
177  *
178  * @param domain trusted domain name
179  *
180  * @return stored password's key
181  **/
182 static char *trustdom_keystr(const char *domain)
183 {
184         char *keystr;
185
186         keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
187                                             SECRETS_DOMTRUST_ACCT_PASS,
188                                             domain);
189         SMB_ASSERT(keystr != NULL);
190         return keystr;
191 }
192
193 /************************************************************************
194  Routine to get account password to trusted domain
195 ************************************************************************/
196
197 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
198                                            struct dom_sid *sid, time_t *pass_last_set_time)
199 {
200         struct TRUSTED_DOM_PASS pass;
201         enum ndr_err_code ndr_err;
202
203         /* unpacking structures */
204         DATA_BLOB blob;
205
206         /* fetching trusted domain password structure */
207         if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
208                                                    &blob.length))) {
209                 DEBUG(5, ("secrets_fetch failed!\n"));
210                 return False;
211         }
212
213         /* unpack trusted domain password */
214         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
215                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
216
217         SAFE_FREE(blob.data);
218
219         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
220                 return false;
221         }
222
223
224         /* the trust's password */
225         if (pwd) {
226                 *pwd = SMB_STRDUP(pass.pass);
227                 if (!*pwd) {
228                         return False;
229                 }
230         }
231
232         /* last change time */
233         if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
234
235         /* domain sid */
236         if (sid != NULL) sid_copy(sid, &pass.domain_sid);
237
238         return True;
239 }
240
241 /**
242  * Routine to store the password for trusted domain
243  *
244  * @param domain remote domain name
245  * @param pwd plain text password of trust relationship
246  * @param sid remote domain sid
247  *
248  * @return true if succeeded
249  **/
250
251 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
252                                            const struct dom_sid *sid)
253 {
254         bool ret;
255
256         /* packing structures */
257         DATA_BLOB blob;
258         enum ndr_err_code ndr_err;
259         struct TRUSTED_DOM_PASS pass;
260         ZERO_STRUCT(pass);
261
262         pass.uni_name = domain;
263         pass.uni_name_len = strlen(domain)+1;
264
265         /* last change time */
266         pass.mod_time = time(NULL);
267
268         /* password of the trust */
269         pass.pass_len = strlen(pwd);
270         pass.pass = pwd;
271
272         /* domain sid */
273         sid_copy(&pass.domain_sid, sid);
274
275         ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
276                         (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
277         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
278                 return false;
279         }
280
281         ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
282
283         data_blob_free(&blob);
284
285         return ret;
286 }
287
288 /************************************************************************
289  Routine to delete the password for trusted domain
290 ************************************************************************/
291
292 bool trusted_domain_password_delete(const char *domain)
293 {
294         return secrets_delete(trustdom_keystr(domain));
295 }
296
297 bool secrets_store_ldap_pw(const char* dn, char* pw)
298 {
299         char *key = NULL;
300         bool ret;
301
302         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
303                 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
304                 return False;
305         }
306
307         ret = secrets_store(key, pw, strlen(pw)+1);
308
309         SAFE_FREE(key);
310         return ret;
311 }
312
313 /*******************************************************************
314  Find the ldap password.
315 ******************************************************************/
316
317 bool fetch_ldap_pw(char **dn, char** pw)
318 {
319         char *key = NULL;
320         size_t size = 0;
321
322         *dn = smb_xstrdup(lp_ldap_admin_dn());
323
324         if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
325                 SAFE_FREE(*dn);
326                 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
327                 return false;
328         }
329
330         *pw=(char *)secrets_fetch(key, &size);
331         SAFE_FREE(key);
332
333         if (!size) {
334                 /* Upgrade 2.2 style entry */
335                 char *p;
336                 char* old_style_key = SMB_STRDUP(*dn);
337                 char *data;
338                 fstring old_style_pw;
339
340                 if (!old_style_key) {
341                         DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
342                         return False;
343                 }
344
345                 for (p=old_style_key; *p; p++)
346                         if (*p == ',') *p = '/';
347
348                 data=(char *)secrets_fetch(old_style_key, &size);
349                 if ((data == NULL) || (size < sizeof(old_style_pw))) {
350                         DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
351                         SAFE_FREE(old_style_key);
352                         SAFE_FREE(*dn);
353                         SAFE_FREE(data);
354                         return False;
355                 }
356
357                 size = MIN(size, sizeof(fstring)-1);
358                 strncpy(old_style_pw, data, size);
359                 old_style_pw[size] = 0;
360
361                 SAFE_FREE(data);
362
363                 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
364                         DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
365                         SAFE_FREE(old_style_key);
366                         SAFE_FREE(*dn);
367                         return False;
368                 }
369                 if (!secrets_delete(old_style_key)) {
370                         DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
371                 }
372
373                 SAFE_FREE(old_style_key);
374
375                 *pw = smb_xstrdup(old_style_pw);
376         }
377
378         return True;
379 }
380
381 /**
382  * Get trusted domains info from secrets.tdb.
383  **/
384
385 struct list_trusted_domains_state {
386         uint32 num_domains;
387         struct trustdom_info **domains;
388 };
389
390 static int list_trusted_domain(struct db_record *rec, void *private_data)
391 {
392         const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
393         struct TRUSTED_DOM_PASS pass;
394         enum ndr_err_code ndr_err;
395         DATA_BLOB blob;
396         struct trustdom_info *dom_info;
397
398         struct list_trusted_domains_state *state =
399                 (struct list_trusted_domains_state *)private_data;
400
401         if ((rec->key.dsize < prefix_len)
402             || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
403                         prefix_len) != 0)) {
404                 return 0;
405         }
406
407         blob = data_blob_const(rec->value.dptr, rec->value.dsize);
408
409         ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
410                         (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
411         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
412                 return false;
413         }
414
415         if (pass.domain_sid.num_auths != 4) {
416                 DEBUG(0, ("SID %s is not a domain sid, has %d "
417                           "auths instead of 4\n",
418                           sid_string_dbg(&pass.domain_sid),
419                           pass.domain_sid.num_auths));
420                 return 0;
421         }
422
423         if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
424                 DEBUG(0, ("talloc failed\n"));
425                 return 0;
426         }
427
428         dom_info->name = talloc_strdup(dom_info, pass.uni_name);
429         if (!dom_info->name) {
430                 TALLOC_FREE(dom_info);
431                 return 0;
432         }
433
434         sid_copy(&dom_info->sid, &pass.domain_sid);
435
436         ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
437                      &state->domains, &state->num_domains);
438
439         if (state->domains == NULL) {
440                 state->num_domains = 0;
441                 return -1;
442         }
443         return 0;
444 }
445
446 NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
447                                  struct trustdom_info ***domains)
448 {
449         struct list_trusted_domains_state state;
450
451         if (!secrets_init()) {
452                 return NT_STATUS_ACCESS_DENIED;
453         }
454
455         state.num_domains = 0;
456
457         /*
458          * Make sure that a talloc context for the trustdom_info structs
459          * exists
460          */
461
462         if (!(state.domains = talloc_array(
463                       mem_ctx, struct trustdom_info *, 1))) {
464                 return NT_STATUS_NO_MEMORY;
465         }
466
467         db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
468
469         *num_domains = state.num_domains;
470         *domains = state.domains;
471         return NT_STATUS_OK;
472 }
473
474 /*******************************************************************************
475  Store a complete AFS keyfile into secrets.tdb.
476 *******************************************************************************/
477
478 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
479 {
480         fstring key;
481
482         if ((cell == NULL) || (keyfile == NULL))
483                 return False;
484
485         if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
486                 return False;
487
488         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
489         return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
490 }
491
492 /*******************************************************************************
493  Fetch the current (highest) AFS key from secrets.tdb
494 *******************************************************************************/
495 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
496 {
497         fstring key;
498         struct afs_keyfile *keyfile;
499         size_t size = 0;
500         uint32 i;
501
502         slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
503
504         keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
505
506         if (keyfile == NULL)
507                 return False;
508
509         if (size != sizeof(struct afs_keyfile)) {
510                 SAFE_FREE(keyfile);
511                 return False;
512         }
513
514         i = ntohl(keyfile->nkeys);
515
516         if (i > SECRETS_AFS_MAXKEYS) {
517                 SAFE_FREE(keyfile);
518                 return False;
519         }
520
521         *result = keyfile->entry[i-1];
522
523         result->kvno = ntohl(result->kvno);
524
525         SAFE_FREE(keyfile);
526
527         return True;
528 }
529
530 /******************************************************************************
531   When kerberos is not available, choose between anonymous or
532   authenticated connections.
533
534   We need to use an authenticated connection if DCs have the
535   RestrictAnonymous registry entry set > 0, or the "Additional
536   restrictions for anonymous connections" set in the win2k Local
537   Security Policy.
538
539   Caller to free() result in domain, username, password
540 *******************************************************************************/
541 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
542 {
543         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
544         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
545         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
546
547         if (*username && **username) {
548
549                 if (!*domain || !**domain)
550                         *domain = smb_xstrdup(lp_workgroup());
551
552                 if (!*password || !**password)
553                         *password = smb_xstrdup("");
554
555                 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
556                           *domain, *username));
557
558         } else {
559                 DEBUG(3, ("IPC$ connections done anonymously\n"));
560                 *username = smb_xstrdup("");
561                 *domain = smb_xstrdup("");
562                 *password = smb_xstrdup("");
563         }
564 }
565
566 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
567 {
568         char *tdbkey = NULL;
569         bool ret;
570
571         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
572                 DEBUG(0, ("asprintf failed!\n"));
573                 return False;
574         }
575
576         ret = secrets_store(tdbkey, secret, strlen(secret)+1);
577
578         SAFE_FREE(tdbkey);
579         return ret;
580 }
581
582 bool secrets_delete_generic(const char *owner, const char *key)
583 {
584         char *tdbkey = NULL;
585         bool ret;
586
587         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
588                 DEBUG(0, ("asprintf failed!\n"));
589                 return False;
590         }
591
592         ret = secrets_delete(tdbkey);
593
594         SAFE_FREE(tdbkey);
595         return ret;
596 }
597
598 /*******************************************************************
599  Find the ldap password.
600 ******************************************************************/
601
602 char *secrets_fetch_generic(const char *owner, const char *key)
603 {
604         char *secret = NULL;
605         char *tdbkey = NULL;
606
607         if (( ! owner) || ( ! key)) {
608                 DEBUG(1, ("Invalid Parameters"));
609                 return NULL;
610         }
611
612         if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
613                 DEBUG(0, ("Out of memory!\n"));
614                 return NULL;
615         }
616
617         secret = (char *)secrets_fetch(tdbkey, NULL);
618         SAFE_FREE(tdbkey);
619
620         return secret;
621 }
622