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/dbwrap.h"
31 #include "dbwrap/dbwrap_open.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 /* open up the secrets database with specified private_dir path */
secrets_init_path(const char * private_dir)41 bool secrets_init_path(const char *private_dir)
42 {
43 char *fname = NULL;
44 TALLOC_CTX *frame;
45
46 if (db_ctx != NULL) {
47 return True;
48 }
49
50 if (private_dir == NULL) {
51 return False;
52 }
53
54 frame = talloc_stackframe();
55 fname = talloc_asprintf(frame, "%s/secrets.tdb", private_dir);
56 if (fname == NULL) {
57 TALLOC_FREE(frame);
58 return False;
59 }
60
61 db_ctx = db_open(NULL, fname, 0,
62 TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
63 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
64
65 if (db_ctx == NULL) {
66 DEBUG(0,("Failed to open %s\n", fname));
67 TALLOC_FREE(frame);
68 return False;
69 }
70
71 TALLOC_FREE(frame);
72 return True;
73 }
74
75 /* open up the secrets database */
secrets_init(void)76 bool secrets_init(void)
77 {
78 return secrets_init_path(lp_private_dir());
79 }
80
secrets_db_ctx(void)81 struct db_context *secrets_db_ctx(void)
82 {
83 if (!secrets_init()) {
84 return NULL;
85 }
86
87 return db_ctx;
88 }
89
90 /*
91 * close secrets.tdb
92 */
secrets_shutdown(void)93 void secrets_shutdown(void)
94 {
95 TALLOC_FREE(db_ctx);
96 }
97
98 /* read a entry from the secrets database - the caller must free the result
99 if size is non-null then the size of the entry is put in there
100 */
secrets_fetch(const char * key,size_t * size)101 void *secrets_fetch(const char *key, size_t *size)
102 {
103 TDB_DATA dbuf;
104 void *result;
105 NTSTATUS status;
106
107 if (!secrets_init()) {
108 return NULL;
109 }
110
111 status = dbwrap_fetch(db_ctx, talloc_tos(), string_tdb_data(key),
112 &dbuf);
113 if (!NT_STATUS_IS_OK(status)) {
114 return NULL;
115 }
116
117 result = smb_memdup(dbuf.dptr, dbuf.dsize);
118 if (result == NULL) {
119 return NULL;
120 }
121 TALLOC_FREE(dbuf.dptr);
122
123 if (size) {
124 *size = dbuf.dsize;
125 }
126
127 return result;
128 }
129
130 /* store a secrets entry
131 */
secrets_store(const char * key,const void * data,size_t size)132 bool secrets_store(const char *key, const void *data, size_t size)
133 {
134 NTSTATUS status;
135
136 if (!secrets_init()) {
137 return false;
138 }
139
140 status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
141 make_tdb_data((const uint8_t *)data, size),
142 TDB_REPLACE);
143 return NT_STATUS_IS_OK(status);
144 }
145
146
147 /* delete a secets database entry
148 */
secrets_delete_entry(const char * key)149 bool secrets_delete_entry(const char *key)
150 {
151 NTSTATUS status;
152 if (!secrets_init()) {
153 return false;
154 }
155
156 status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
157
158 return NT_STATUS_IS_OK(status);
159 }
160
161 /*
162 * Deletes the key if it exists.
163 */
secrets_delete(const char * key)164 bool secrets_delete(const char *key)
165 {
166 bool exists;
167
168 if (!secrets_init()) {
169 return false;
170 }
171
172 exists = dbwrap_exists(db_ctx, string_tdb_data(key));
173 if (!exists) {
174 return true;
175 }
176
177 return secrets_delete_entry(key);
178 }
179
180 /**
181 * Form a key for fetching a trusted domain password
182 *
183 * @param domain trusted domain name
184 *
185 * @return stored password's key
186 **/
trustdom_keystr(const char * domain)187 static char *trustdom_keystr(const char *domain)
188 {
189 char *keystr;
190
191 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
192 SECRETS_DOMTRUST_ACCT_PASS,
193 domain);
194 SMB_ASSERT(keystr != NULL);
195 return keystr;
196 }
197
198 /************************************************************************
199 Routine to get account password to trusted domain
200 ************************************************************************/
201
secrets_fetch_trusted_domain_password(const char * domain,char ** pwd,struct dom_sid * sid,time_t * pass_last_set_time)202 bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
203 struct dom_sid *sid, time_t *pass_last_set_time)
204 {
205 struct TRUSTED_DOM_PASS pass;
206 enum ndr_err_code ndr_err;
207
208 /* unpacking structures */
209 DATA_BLOB blob;
210
211 /* fetching trusted domain password structure */
212 if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
213 &blob.length))) {
214 DEBUG(5, ("secrets_fetch failed!\n"));
215 return False;
216 }
217
218 /* unpack trusted domain password */
219 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
220 (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
221
222 SAFE_FREE(blob.data);
223
224 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
225 return false;
226 }
227
228
229 /* the trust's password */
230 if (pwd) {
231 *pwd = SMB_STRDUP(pass.pass);
232 if (!*pwd) {
233 return False;
234 }
235 }
236
237 /* last change time */
238 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
239
240 /* domain sid */
241 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
242
243 return True;
244 }
245
246 /**
247 * Routine to store the password for trusted domain
248 *
249 * @param domain remote domain name
250 * @param pwd plain text password of trust relationship
251 * @param sid remote domain sid
252 *
253 * @return true if succeeded
254 **/
255
secrets_store_trusted_domain_password(const char * domain,const char * pwd,const struct dom_sid * sid)256 bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
257 const struct dom_sid *sid)
258 {
259 bool ret;
260
261 /* packing structures */
262 DATA_BLOB blob;
263 enum ndr_err_code ndr_err;
264 struct TRUSTED_DOM_PASS pass;
265 ZERO_STRUCT(pass);
266
267 pass.uni_name = domain;
268 pass.uni_name_len = strlen(domain)+1;
269
270 /* last change time */
271 pass.mod_time = time(NULL);
272
273 /* password of the trust */
274 pass.pass_len = strlen(pwd);
275 pass.pass = pwd;
276
277 /* domain sid */
278 sid_copy(&pass.domain_sid, sid);
279
280 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
281 (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
282 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
283 return false;
284 }
285
286 ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
287
288 data_blob_free(&blob);
289
290 return ret;
291 }
292
293 /************************************************************************
294 Routine to delete the password for trusted domain
295 ************************************************************************/
296
trusted_domain_password_delete(const char * domain)297 bool trusted_domain_password_delete(const char *domain)
298 {
299 return secrets_delete_entry(trustdom_keystr(domain));
300 }
301
secrets_store_ldap_pw(const char * dn,char * pw)302 bool secrets_store_ldap_pw(const char* dn, char* pw)
303 {
304 char *key = NULL;
305 bool ret;
306
307 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
308 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
309 return False;
310 }
311
312 ret = secrets_store(key, pw, strlen(pw)+1);
313
314 SAFE_FREE(key);
315 return ret;
316 }
317
318 /*******************************************************************
319 Find the ldap password.
320 ******************************************************************/
321
fetch_ldap_pw(char ** dn,char ** pw)322 bool fetch_ldap_pw(char **dn, char** pw)
323 {
324 char *key = NULL;
325 size_t size = 0;
326
327 *dn = smb_xstrdup(lp_ldap_admin_dn());
328
329 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
330 SAFE_FREE(*dn);
331 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
332 return false;
333 }
334
335 *pw=(char *)secrets_fetch(key, &size);
336 SAFE_FREE(key);
337
338 if ((size != 0) && ((*pw)[size-1] != '\0')) {
339 DBG_ERR("Non 0-terminated password for dn %s\n", *dn);
340 SAFE_FREE(*pw);
341 SAFE_FREE(*dn);
342 return false;
343 }
344
345 if (!size) {
346 /* Upgrade 2.2 style entry */
347 char *p;
348 char* old_style_key = SMB_STRDUP(*dn);
349 char *data;
350 fstring old_style_pw;
351
352 if (!old_style_key) {
353 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
354 SAFE_FREE(*pw);
355 SAFE_FREE(*dn);
356 return False;
357 }
358
359 for (p=old_style_key; *p; p++)
360 if (*p == ',') *p = '/';
361
362 data=(char *)secrets_fetch(old_style_key, &size);
363 if ((data == NULL) || (size < sizeof(old_style_pw))) {
364 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
365 SAFE_FREE(old_style_key);
366 SAFE_FREE(*pw);
367 SAFE_FREE(*dn);
368 SAFE_FREE(data);
369 return False;
370 }
371
372 size = MIN(size, sizeof(fstring)-1);
373 strncpy(old_style_pw, data, size);
374 old_style_pw[size] = 0;
375
376 SAFE_FREE(data);
377
378 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
379 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
380 SAFE_FREE(old_style_key);
381 SAFE_FREE(*pw);
382 SAFE_FREE(*dn);
383 return False;
384 }
385 if (!secrets_delete_entry(old_style_key)) {
386 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
387 }
388
389 SAFE_FREE(old_style_key);
390
391 *pw = smb_xstrdup(old_style_pw);
392 }
393
394 return True;
395 }
396
397 /*******************************************************************************
398 Store a complete AFS keyfile into secrets.tdb.
399 *******************************************************************************/
400
secrets_store_afs_keyfile(const char * cell,const struct afs_keyfile * keyfile)401 bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
402 {
403 fstring key;
404
405 if ((cell == NULL) || (keyfile == NULL))
406 return False;
407
408 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
409 return False;
410
411 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
412 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
413 }
414
415 /*******************************************************************************
416 Fetch the current (highest) AFS key from secrets.tdb
417 *******************************************************************************/
secrets_fetch_afs_key(const char * cell,struct afs_key * result)418 bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
419 {
420 fstring key;
421 struct afs_keyfile *keyfile;
422 size_t size = 0;
423 uint32_t i;
424
425 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
426
427 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
428
429 if (keyfile == NULL)
430 return False;
431
432 if (size != sizeof(struct afs_keyfile)) {
433 SAFE_FREE(keyfile);
434 return False;
435 }
436
437 i = ntohl(keyfile->nkeys);
438
439 if (i > SECRETS_AFS_MAXKEYS) {
440 SAFE_FREE(keyfile);
441 return False;
442 }
443
444 *result = keyfile->entry[i-1];
445
446 result->kvno = ntohl(result->kvno);
447
448 SAFE_FREE(keyfile);
449
450 return True;
451 }
452
453 /******************************************************************************
454 When kerberos is not available, choose between anonymous or
455 authenticated connections.
456
457 We need to use an authenticated connection if DCs have the
458 RestrictAnonymous registry entry set > 0, or the "Additional
459 restrictions for anonymous connections" set in the win2k Local
460 Security Policy.
461
462 Caller to free() result in domain, username, password
463 *******************************************************************************/
secrets_fetch_ipc_userpass(char ** username,char ** domain,char ** password)464 void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
465 {
466 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
467 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
468 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
469
470 if (*username && **username) {
471
472 if (!*domain || !**domain)
473 *domain = smb_xstrdup(lp_workgroup());
474
475 if (!*password || !**password)
476 *password = smb_xstrdup("");
477
478 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
479 *domain, *username));
480
481 } else {
482 DEBUG(3, ("IPC$ connections done anonymously\n"));
483 *username = smb_xstrdup("");
484 *domain = smb_xstrdup("");
485 *password = smb_xstrdup("");
486 }
487 }
488
secrets_store_generic(const char * owner,const char * key,const char * secret)489 bool secrets_store_generic(const char *owner, const char *key, const char *secret)
490 {
491 char *tdbkey = NULL;
492 bool ret;
493
494 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
495 DEBUG(0, ("asprintf failed!\n"));
496 return False;
497 }
498
499 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
500
501 SAFE_FREE(tdbkey);
502 return ret;
503 }
504
505 /*******************************************************************
506 Find the ldap password.
507 ******************************************************************/
508
secrets_fetch_generic(const char * owner,const char * key)509 char *secrets_fetch_generic(const char *owner, const char *key)
510 {
511 char *secret = NULL;
512 char *tdbkey = NULL;
513
514 if (( ! owner) || ( ! key)) {
515 DEBUG(1, ("Invalid Parameters"));
516 return NULL;
517 }
518
519 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
520 DEBUG(0, ("Out of memory!\n"));
521 return NULL;
522 }
523
524 secret = (char *)secrets_fetch(tdbkey, NULL);
525 SAFE_FREE(tdbkey);
526
527 return secret;
528 }
529
530