source: vendor/current/source3/passdb/secrets.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 11.5 KB
Line 
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
38static struct db_context *db_ctx;
39
40/* open up the secrets database with specified private_dir path */
41bool 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 */
76bool secrets_init(void)
77{
78 return secrets_init_path(lp_private_dir());
79}
80
81struct 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 */
93void 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 */
101void *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 */
132bool 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 */
149bool secrets_delete(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 * Form a key for fetching a trusted domain password
163 *
164 * @param domain trusted domain name
165 *
166 * @return stored password's key
167 **/
168static char *trustdom_keystr(const char *domain)
169{
170 char *keystr;
171
172 keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
173 SECRETS_DOMTRUST_ACCT_PASS,
174 domain);
175 SMB_ASSERT(keystr != NULL);
176 return keystr;
177}
178
179/************************************************************************
180 Routine to get account password to trusted domain
181************************************************************************/
182
183bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
184 struct dom_sid *sid, time_t *pass_last_set_time)
185{
186 struct TRUSTED_DOM_PASS pass;
187 enum ndr_err_code ndr_err;
188
189 /* unpacking structures */
190 DATA_BLOB blob;
191
192 /* fetching trusted domain password structure */
193 if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain),
194 &blob.length))) {
195 DEBUG(5, ("secrets_fetch failed!\n"));
196 return False;
197 }
198
199 /* unpack trusted domain password */
200 ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &pass,
201 (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS);
202
203 SAFE_FREE(blob.data);
204
205 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
206 return false;
207 }
208
209
210 /* the trust's password */
211 if (pwd) {
212 *pwd = SMB_STRDUP(pass.pass);
213 if (!*pwd) {
214 return False;
215 }
216 }
217
218 /* last change time */
219 if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
220
221 /* domain sid */
222 if (sid != NULL) sid_copy(sid, &pass.domain_sid);
223
224 return True;
225}
226
227/**
228 * Routine to store the password for trusted domain
229 *
230 * @param domain remote domain name
231 * @param pwd plain text password of trust relationship
232 * @param sid remote domain sid
233 *
234 * @return true if succeeded
235 **/
236
237bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
238 const struct dom_sid *sid)
239{
240 bool ret;
241
242 /* packing structures */
243 DATA_BLOB blob;
244 enum ndr_err_code ndr_err;
245 struct TRUSTED_DOM_PASS pass;
246 ZERO_STRUCT(pass);
247
248 pass.uni_name = domain;
249 pass.uni_name_len = strlen(domain)+1;
250
251 /* last change time */
252 pass.mod_time = time(NULL);
253
254 /* password of the trust */
255 pass.pass_len = strlen(pwd);
256 pass.pass = pwd;
257
258 /* domain sid */
259 sid_copy(&pass.domain_sid, sid);
260
261 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &pass,
262 (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS);
263 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
264 return false;
265 }
266
267 ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length);
268
269 data_blob_free(&blob);
270
271 return ret;
272}
273
274/************************************************************************
275 Routine to delete the password for trusted domain
276************************************************************************/
277
278bool trusted_domain_password_delete(const char *domain)
279{
280 return secrets_delete(trustdom_keystr(domain));
281}
282
283bool secrets_store_ldap_pw(const char* dn, char* pw)
284{
285 char *key = NULL;
286 bool ret;
287
288 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
289 DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
290 return False;
291 }
292
293 ret = secrets_store(key, pw, strlen(pw)+1);
294
295 SAFE_FREE(key);
296 return ret;
297}
298
299/*******************************************************************
300 Find the ldap password.
301******************************************************************/
302
303bool fetch_ldap_pw(char **dn, char** pw)
304{
305 char *key = NULL;
306 size_t size = 0;
307
308 *dn = smb_xstrdup(lp_ldap_admin_dn(talloc_tos()));
309
310 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
311 SAFE_FREE(*dn);
312 DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
313 return false;
314 }
315
316 *pw=(char *)secrets_fetch(key, &size);
317 SAFE_FREE(key);
318
319 if (!size) {
320 /* Upgrade 2.2 style entry */
321 char *p;
322 char* old_style_key = SMB_STRDUP(*dn);
323 char *data;
324 fstring old_style_pw;
325
326 if (!old_style_key) {
327 DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
328 return False;
329 }
330
331 for (p=old_style_key; *p; p++)
332 if (*p == ',') *p = '/';
333
334 data=(char *)secrets_fetch(old_style_key, &size);
335 if ((data == NULL) || (size < sizeof(old_style_pw))) {
336 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
337 SAFE_FREE(old_style_key);
338 SAFE_FREE(*dn);
339 SAFE_FREE(data);
340 return False;
341 }
342
343 size = MIN(size, sizeof(fstring)-1);
344 strncpy(old_style_pw, data, size);
345 old_style_pw[size] = 0;
346
347 SAFE_FREE(data);
348
349 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
350 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
351 SAFE_FREE(old_style_key);
352 SAFE_FREE(*dn);
353 return False;
354 }
355 if (!secrets_delete(old_style_key)) {
356 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
357 }
358
359 SAFE_FREE(old_style_key);
360
361 *pw = smb_xstrdup(old_style_pw);
362 }
363
364 return True;
365}
366
367/*******************************************************************************
368 Store a complete AFS keyfile into secrets.tdb.
369*******************************************************************************/
370
371bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
372{
373 fstring key;
374
375 if ((cell == NULL) || (keyfile == NULL))
376 return False;
377
378 if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
379 return False;
380
381 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
382 return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
383}
384
385/*******************************************************************************
386 Fetch the current (highest) AFS key from secrets.tdb
387*******************************************************************************/
388bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
389{
390 fstring key;
391 struct afs_keyfile *keyfile;
392 size_t size = 0;
393 uint32_t i;
394
395 slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
396
397 keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
398
399 if (keyfile == NULL)
400 return False;
401
402 if (size != sizeof(struct afs_keyfile)) {
403 SAFE_FREE(keyfile);
404 return False;
405 }
406
407 i = ntohl(keyfile->nkeys);
408
409 if (i > SECRETS_AFS_MAXKEYS) {
410 SAFE_FREE(keyfile);
411 return False;
412 }
413
414 *result = keyfile->entry[i-1];
415
416 result->kvno = ntohl(result->kvno);
417
418 SAFE_FREE(keyfile);
419
420 return True;
421}
422
423/******************************************************************************
424 When kerberos is not available, choose between anonymous or
425 authenticated connections.
426
427 We need to use an authenticated connection if DCs have the
428 RestrictAnonymous registry entry set > 0, or the "Additional
429 restrictions for anonymous connections" set in the win2k Local
430 Security Policy.
431
432 Caller to free() result in domain, username, password
433*******************************************************************************/
434void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
435{
436 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
437 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
438 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
439
440 if (*username && **username) {
441
442 if (!*domain || !**domain)
443 *domain = smb_xstrdup(lp_workgroup());
444
445 if (!*password || !**password)
446 *password = smb_xstrdup("");
447
448 DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
449 *domain, *username));
450
451 } else {
452 DEBUG(3, ("IPC$ connections done anonymously\n"));
453 *username = smb_xstrdup("");
454 *domain = smb_xstrdup("");
455 *password = smb_xstrdup("");
456 }
457}
458
459bool secrets_store_generic(const char *owner, const char *key, const char *secret)
460{
461 char *tdbkey = NULL;
462 bool ret;
463
464 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
465 DEBUG(0, ("asprintf failed!\n"));
466 return False;
467 }
468
469 ret = secrets_store(tdbkey, secret, strlen(secret)+1);
470
471 SAFE_FREE(tdbkey);
472 return ret;
473}
474
475/*******************************************************************
476 Find the ldap password.
477******************************************************************/
478
479char *secrets_fetch_generic(const char *owner, const char *key)
480{
481 char *secret = NULL;
482 char *tdbkey = NULL;
483
484 if (( ! owner) || ( ! key)) {
485 DEBUG(1, ("Invalid Parameters"));
486 return NULL;
487 }
488
489 if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
490 DEBUG(0, ("Out of memory!\n"));
491 return NULL;
492 }
493
494 secret = (char *)secrets_fetch(tdbkey, NULL);
495 SAFE_FREE(tdbkey);
496
497 return secret;
498}
499
Note: See TracBrowser for help on using the repository browser.