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