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