~ubuntu-branches/ubuntu/lucid/samba/lucid-proposed

« back to all changes in this revision

Viewing changes to .pc/fhs-filespaths.patch/source3/passdb/secrets.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2009-12-28 05:02:32 UTC
  • mfrom: (0.34.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091228050232-jdd4xy3otxp71kdt
Tags: 2:3.4.3-2ubuntu1
* Merge from debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/smb.conf:
    - Add "(Samba, Ubuntu)" to server string.
    - Comment out the default [homes] share, and add a comment about "valid users = %s" 
      to show users how to restrict access to \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are allowed to create
      public shares in additon to authenticated ones.
    - add map to guest = Bad user, maps bad username to gues access.
  + debian/samba-common.conf:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/mksambapasswd.awk:
    - Do not add user with UID less than 1000 to smbpasswd.
  + debian/control:
    - Make libswbclient0 replace/conflickt with hardy's likewise-open.
    - Don't build against ctdb.
    - Build-depend on libreadline-dev instead of libreadline5-dev.
  + debian/rules:
    - Enable "native" PIE hardening.
    - Add BIND_NOW to maximize benefit of RELRO hardening.
  + Add ufw integration:
    - Created debian/samba.ufw.profile.
    - debian/rules, debian/samba.dirs, debian/samba.files: install

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
27
#undef DBGC_CLASS
 
28
#define DBGC_CLASS DBGC_PASSDB
 
29
 
 
30
static struct db_context *db_ctx;
 
31
 
 
32
/* Urrrg. global.... */
 
33
bool global_machine_password_needs_changing;
 
34
 
 
35
/**
 
36
 * Use a TDB to store an incrementing random seed.
 
37
 *
 
38
 * Initialised to the current pid, the very first time Samba starts,
 
39
 * and incremented by one each time it is needed.
 
40
 *
 
41
 * @note Not called by systems with a working /dev/urandom.
 
42
 */
 
43
static void get_rand_seed(void *userdata, int *new_seed)
 
44
{
 
45
        *new_seed = sys_getpid();
 
46
        if (db_ctx) {
 
47
                dbwrap_change_int32_atomic(db_ctx, "INFO/random_seed",
 
48
                                           new_seed, 1);
 
49
        }
 
50
}
 
51
 
 
52
/* open up the secrets database */
 
53
bool secrets_init(void)
 
54
{
 
55
        char *fname = NULL;
 
56
        unsigned char dummy;
 
57
 
 
58
        if (db_ctx != NULL)
 
59
                return True;
 
60
 
 
61
        fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb",
 
62
                                lp_private_dir());
 
63
        if (fname == NULL) {
 
64
                return false;
 
65
        }
 
66
 
 
67
        db_ctx = db_open(NULL, fname, 0,
 
68
                         TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
 
69
 
 
70
        if (db_ctx == NULL) {
 
71
                DEBUG(0,("Failed to open %s\n", fname));
 
72
                TALLOC_FREE(fname);
 
73
                return False;
 
74
        }
 
75
 
 
76
        TALLOC_FREE(fname);
 
77
 
 
78
        /**
 
79
         * Set a reseed function for the crypto random generator
 
80
         *
 
81
         * This avoids a problem where systems without /dev/urandom
 
82
         * could send the same challenge to multiple clients
 
83
         */
 
84
        set_rand_reseed_callback(get_rand_seed, NULL);
 
85
 
 
86
        /* Ensure that the reseed is done now, while we are root, etc */
 
87
        generate_random_buffer(&dummy, sizeof(dummy));
 
88
 
 
89
        return True;
 
90
}
 
91
 
 
92
struct db_context *secrets_db_ctx(void)
 
93
{
 
94
        if (!secrets_init()) {
 
95
                return NULL;
 
96
        }
 
97
 
 
98
        return db_ctx;
 
99
}
 
100
 
 
101
/*
 
102
 * close secrets.tdb
 
103
 */
 
104
void secrets_shutdown(void)
 
105
{
 
106
        TALLOC_FREE(db_ctx);
 
107
}
 
108
 
 
109
/* read a entry from the secrets database - the caller must free the result
 
110
   if size is non-null then the size of the entry is put in there
 
111
 */
 
112
void *secrets_fetch(const char *key, size_t *size)
 
113
{
 
114
        TDB_DATA dbuf;
 
115
        void *result;
 
116
 
 
117
        if (!secrets_init()) {
 
118
                return NULL;
 
119
        }
 
120
 
 
121
        if (db_ctx->fetch(db_ctx, talloc_tos(), string_tdb_data(key),
 
122
                          &dbuf) != 0) {
 
123
                return NULL;
 
124
        }
 
125
 
 
126
        result = memdup(dbuf.dptr, dbuf.dsize);
 
127
        if (result == NULL) {
 
128
                return NULL;
 
129
        }
 
130
        TALLOC_FREE(dbuf.dptr);
 
131
 
 
132
        if (size) {
 
133
                *size = dbuf.dsize;
 
134
        }
 
135
 
 
136
        return result;
 
137
}
 
138
 
 
139
/* store a secrets entry
 
140
 */
 
141
bool secrets_store(const char *key, const void *data, size_t size)
 
142
{
 
143
        NTSTATUS status;
 
144
 
 
145
        if (!secrets_init()) {
 
146
                return false;
 
147
        }
 
148
 
 
149
        status = dbwrap_trans_store(db_ctx, string_tdb_data(key),
 
150
                                    make_tdb_data((const uint8 *)data, size),
 
151
                                    TDB_REPLACE);
 
152
        return NT_STATUS_IS_OK(status);
 
153
}
 
154
 
 
155
 
 
156
/* delete a secets database entry
 
157
 */
 
158
bool secrets_delete(const char *key)
 
159
{
 
160
        NTSTATUS status;
 
161
        if (!secrets_init()) {
 
162
                return false;
 
163
        }
 
164
 
 
165
        status = dbwrap_trans_delete(db_ctx, string_tdb_data(key));
 
166
 
 
167
        return NT_STATUS_IS_OK(status);
 
168
}
 
169
 
 
170
/**
 
171
 * Form a key for fetching the domain sid
 
172
 *
 
173
 * @param domain domain name
 
174
 *
 
175
 * @return keystring
 
176
 **/
 
177
static const char *domain_sid_keystr(const char *domain)
 
178
{
 
179
        char *keystr;
 
180
 
 
181
        keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 
182
                                            SECRETS_DOMAIN_SID, domain);
 
183
        SMB_ASSERT(keystr != NULL);
 
184
        return keystr;
 
185
}
 
186
 
 
187
bool secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
 
188
{
 
189
        bool ret;
 
190
 
 
191
        ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(DOM_SID));
 
192
 
 
193
        /* Force a re-query, in case we modified our domain */
 
194
        if (ret)
 
195
                reset_global_sam_sid();
 
196
        return ret;
 
197
}
 
198
 
 
199
bool secrets_fetch_domain_sid(const char *domain, DOM_SID *sid)
 
200
{
 
201
        DOM_SID *dyn_sid;
 
202
        size_t size = 0;
 
203
 
 
204
        dyn_sid = (DOM_SID *)secrets_fetch(domain_sid_keystr(domain), &size);
 
205
 
 
206
        if (dyn_sid == NULL)
 
207
                return False;
 
208
 
 
209
        if (size != sizeof(DOM_SID)) {
 
210
                SAFE_FREE(dyn_sid);
 
211
                return False;
 
212
        }
 
213
 
 
214
        *sid = *dyn_sid;
 
215
        SAFE_FREE(dyn_sid);
 
216
        return True;
 
217
}
 
218
 
 
219
bool secrets_store_domain_guid(const char *domain, struct GUID *guid)
 
220
{
 
221
        fstring key;
 
222
 
 
223
        slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
 
224
        strupper_m(key);
 
225
        return secrets_store(key, guid, sizeof(struct GUID));
 
226
}
 
227
 
 
228
bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
 
229
{
 
230
        struct GUID *dyn_guid;
 
231
        fstring key;
 
232
        size_t size = 0;
 
233
        struct GUID new_guid;
 
234
 
 
235
        slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
 
236
        strupper_m(key);
 
237
        dyn_guid = (struct GUID *)secrets_fetch(key, &size);
 
238
 
 
239
        if (!dyn_guid) {
 
240
                if (lp_server_role() == ROLE_DOMAIN_PDC) {
 
241
                        new_guid = GUID_random();
 
242
                        if (!secrets_store_domain_guid(domain, &new_guid))
 
243
                                return False;
 
244
                        dyn_guid = (struct GUID *)secrets_fetch(key, &size);
 
245
                }
 
246
                if (dyn_guid == NULL) {
 
247
                        return False;
 
248
                }
 
249
        }
 
250
 
 
251
        if (size != sizeof(struct GUID)) {
 
252
                DEBUG(1,("UUID size %d is wrong!\n", (int)size));
 
253
                SAFE_FREE(dyn_guid);
 
254
                return False;
 
255
        }
 
256
 
 
257
        *guid = *dyn_guid;
 
258
        SAFE_FREE(dyn_guid);
 
259
        return True;
 
260
}
 
261
 
 
262
bool secrets_store_local_schannel_key(uint8_t schannel_key[16])
 
263
{
 
264
        return secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, schannel_key, 16);
 
265
}
 
266
 
 
267
bool secrets_fetch_local_schannel_key(uint8_t schannel_key[16])
 
268
{
 
269
        size_t size = 0;
 
270
        uint8_t *key;
 
271
 
 
272
        key = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, &size);
 
273
        if (key == NULL) {
 
274
                return false;
 
275
        }
 
276
 
 
277
        if (size != 16) {
 
278
                SAFE_FREE(key);
 
279
                return false;
 
280
        }
 
281
 
 
282
        memcpy(schannel_key, key, 16);
 
283
        SAFE_FREE(key);
 
284
        return true;
 
285
}
 
286
 
 
287
/**
 
288
 * Form a key for fetching the machine trust account sec channel type
 
289
 *
 
290
 * @param domain domain name
 
291
 *
 
292
 * @return keystring
 
293
 **/
 
294
static const char *machine_sec_channel_type_keystr(const char *domain)
 
295
{
 
296
        char *keystr;
 
297
 
 
298
        keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 
299
                                            SECRETS_MACHINE_SEC_CHANNEL_TYPE,
 
300
                                            domain);
 
301
        SMB_ASSERT(keystr != NULL);
 
302
        return keystr;
 
303
}
 
304
 
 
305
/**
 
306
 * Form a key for fetching the machine trust account last change time
 
307
 *
 
308
 * @param domain domain name
 
309
 *
 
310
 * @return keystring
 
311
 **/
 
312
static const char *machine_last_change_time_keystr(const char *domain)
 
313
{
 
314
        char *keystr;
 
315
 
 
316
        keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 
317
                                            SECRETS_MACHINE_LAST_CHANGE_TIME,
 
318
                                            domain);
 
319
        SMB_ASSERT(keystr != NULL);
 
320
        return keystr;
 
321
}
 
322
 
 
323
 
 
324
/**
 
325
 * Form a key for fetching the machine trust account password
 
326
 *
 
327
 * @param domain domain name
 
328
 *
 
329
 * @return keystring
 
330
 **/
 
331
static const char *machine_password_keystr(const char *domain)
 
332
{
 
333
        char *keystr;
 
334
 
 
335
        keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 
336
                                            SECRETS_MACHINE_PASSWORD, domain);
 
337
        SMB_ASSERT(keystr != NULL);
 
338
        return keystr;
 
339
}
 
340
 
 
341
/**
 
342
 * Form a key for fetching the machine trust account password
 
343
 *
 
344
 * @param domain domain name
 
345
 *
 
346
 * @return stored password's key
 
347
 **/
 
348
static const char *trust_keystr(const char *domain)
 
349
{
 
350
        char *keystr;
 
351
 
 
352
        keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 
353
                                            SECRETS_MACHINE_ACCT_PASS, domain);
 
354
        SMB_ASSERT(keystr != NULL);
 
355
        return keystr;
 
356
}
 
357
 
 
358
/**
 
359
 * Form a key for fetching a trusted domain password
 
360
 *
 
361
 * @param domain trusted domain name
 
362
 *
 
363
 * @return stored password's key
 
364
 **/
 
365
static char *trustdom_keystr(const char *domain)
 
366
{
 
367
        char *keystr;
 
368
 
 
369
        keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
 
370
                                            SECRETS_DOMTRUST_ACCT_PASS,
 
371
                                            domain);
 
372
        SMB_ASSERT(keystr != NULL);
 
373
        return keystr;
 
374
}
 
375
 
 
376
/************************************************************************
 
377
 Lock the trust password entry.
 
378
************************************************************************/
 
379
 
 
380
void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain)
 
381
{
 
382
        if (!secrets_init()) {
 
383
                return NULL;
 
384
        }
 
385
 
 
386
        return db_ctx->fetch_locked(
 
387
                db_ctx, mem_ctx, string_term_tdb_data(trust_keystr(domain)));
 
388
}
 
389
 
 
390
/************************************************************************
 
391
 Routine to get the default secure channel type for trust accounts
 
392
************************************************************************/
 
393
 
 
394
uint32 get_default_sec_channel(void)
 
395
{
 
396
        if (lp_server_role() == ROLE_DOMAIN_BDC ||
 
397
            lp_server_role() == ROLE_DOMAIN_PDC) {
 
398
                return SEC_CHAN_BDC;
 
399
        } else {
 
400
                return SEC_CHAN_WKSTA;
 
401
        }
 
402
}
 
403
 
 
404
/************************************************************************
 
405
 Routine to get the trust account password for a domain.
 
406
 This only tries to get the legacy hashed version of the password.
 
407
 The user of this function must have locked the trust password file using
 
408
 the above secrets_lock_trust_account_password().
 
409
************************************************************************/
 
410
 
 
411
bool secrets_fetch_trust_account_password_legacy(const char *domain,
 
412
                                                 uint8 ret_pwd[16],
 
413
                                                 time_t *pass_last_set_time,
 
414
                                                 uint32 *channel)
 
415
{
 
416
        struct machine_acct_pass *pass;
 
417
        size_t size = 0;
 
418
 
 
419
        if (!(pass = (struct machine_acct_pass *)secrets_fetch(
 
420
                      trust_keystr(domain), &size))) {
 
421
                DEBUG(5, ("secrets_fetch failed!\n"));
 
422
                return False;
 
423
        }
 
424
 
 
425
        if (size != sizeof(*pass)) {
 
426
                DEBUG(0, ("secrets were of incorrect size!\n"));
 
427
                SAFE_FREE(pass);
 
428
                return False;
 
429
        }
 
430
 
 
431
        if (pass_last_set_time) {
 
432
                *pass_last_set_time = pass->mod_time;
 
433
        }
 
434
        memcpy(ret_pwd, pass->hash, 16);
 
435
 
 
436
        if (channel) {
 
437
                *channel = get_default_sec_channel();
 
438
        }
 
439
 
 
440
        /* Test if machine password has expired and needs to be changed */
 
441
        if (lp_machine_password_timeout()) {
 
442
                if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
 
443
                                (time_t)lp_machine_password_timeout())) {
 
444
                        global_machine_password_needs_changing = True;
 
445
                }
 
446
        }
 
447
 
 
448
        SAFE_FREE(pass);
 
449
        return True;
 
450
}
 
451
 
 
452
/************************************************************************
 
453
 Routine to get the trust account password for a domain.
 
454
 The user of this function must have locked the trust password file using
 
455
 the above secrets_lock_trust_account_password().
 
456
************************************************************************/
 
457
 
 
458
bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
 
459
                                          time_t *pass_last_set_time,
 
460
                                          uint32 *channel)
 
461
{
 
462
        char *plaintext;
 
463
 
 
464
        plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
 
465
                                                   channel);
 
466
        if (plaintext) {
 
467
                DEBUG(4,("Using cleartext machine password\n"));
 
468
                E_md4hash(plaintext, ret_pwd);
 
469
                SAFE_FREE(plaintext);
 
470
                return True;
 
471
        }
 
472
 
 
473
        return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
 
474
                                                           pass_last_set_time,
 
475
                                                           channel);
 
476
}
 
477
 
 
478
/**
 
479
 * Pack SID passed by pointer
 
480
 *
 
481
 * @param pack_buf pointer to buffer which is to be filled with packed data
 
482
 * @param bufsize size of packing buffer
 
483
 * @param sid pointer to sid to be packed
 
484
 *
 
485
 * @return length of the packed representation of the whole structure
 
486
 **/
 
487
static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
 
488
{
 
489
        int idx;
 
490
        size_t len = 0;
 
491
        uint8 *p = pack_buf;
 
492
        int remaining_space = pack_buf ? bufsize : 0;
 
493
 
 
494
        if (!sid) {
 
495
                return -1;
 
496
        }
 
497
 
 
498
        len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num,
 
499
                        sid->num_auths);
 
500
        if (pack_buf) {
 
501
                p = pack_buf + len;
 
502
                remaining_space = bufsize - len;
 
503
        }
 
504
 
 
505
        for (idx = 0; idx < 6; idx++) {
 
506
                len += tdb_pack(p, remaining_space, "b",
 
507
                                sid->id_auth[idx]);
 
508
                if (pack_buf) {
 
509
                        p = pack_buf + len;
 
510
                        remaining_space = bufsize - len;
 
511
                }
 
512
        }
 
513
 
 
514
        for (idx = 0; idx < MAXSUBAUTHS; idx++) {
 
515
                len += tdb_pack(p, remaining_space, "d",
 
516
                                sid->sub_auths[idx]);
 
517
                if (pack_buf) {
 
518
                        p = pack_buf + len;
 
519
                        remaining_space = bufsize - len;
 
520
                }
 
521
        }
 
522
 
 
523
        return len;
 
524
}
 
525
 
 
526
/**
 
527
 * Unpack SID into a pointer
 
528
 *
 
529
 * @param pack_buf pointer to buffer with packed representation
 
530
 * @param bufsize size of the buffer
 
531
 * @param sid pointer to sid structure to be filled with unpacked data
 
532
 *
 
533
 * @return size of structure unpacked from buffer
 
534
 **/
 
535
static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid)
 
536
{
 
537
        int idx, len = 0;
 
538
 
 
539
        if (!sid || !pack_buf) return -1;
 
540
 
 
541
        len += tdb_unpack(pack_buf + len, bufsize - len, "bb",
 
542
                          &sid->sid_rev_num, &sid->num_auths);
 
543
 
 
544
        for (idx = 0; idx < 6; idx++) {
 
545
                len += tdb_unpack(pack_buf + len, bufsize - len, "b",
 
546
                                  &sid->id_auth[idx]);
 
547
        }
 
548
 
 
549
        for (idx = 0; idx < MAXSUBAUTHS; idx++) {
 
550
                len += tdb_unpack(pack_buf + len, bufsize - len, "d",
 
551
                                  &sid->sub_auths[idx]);
 
552
        }
 
553
 
 
554
        return len;
 
555
}
 
556
 
 
557
/**
 
558
 * Pack TRUSTED_DOM_PASS passed by pointer
 
559
 *
 
560
 * @param pack_buf pointer to buffer which is to be filled with packed data
 
561
 * @param bufsize size of the buffer
 
562
 * @param pass pointer to trusted domain password to be packed
 
563
 *
 
564
 * @return length of the packed representation of the whole structure
 
565
 **/
 
566
static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize,
 
567
                                        TRUSTED_DOM_PASS* pass)
 
568
{
 
569
        int idx, len = 0;
 
570
        uint8 *p = pack_buf;
 
571
        int remaining_space = pack_buf ? bufsize : 0;
 
572
 
 
573
        if (!pass) {
 
574
                return -1;
 
575
        }
 
576
 
 
577
        /* packing unicode domain name and password */
 
578
        len += tdb_pack(p, remaining_space, "d",
 
579
                        pass->uni_name_len);
 
580
        if (pack_buf) {
 
581
                p = pack_buf + len;
 
582
                remaining_space = bufsize - len;
 
583
        }
 
584
 
 
585
        for (idx = 0; idx < 32; idx++) {
 
586
                len += tdb_pack(p, remaining_space, "w",
 
587
                                 pass->uni_name[idx]);
 
588
                if (pack_buf) {
 
589
                        p = pack_buf + len;
 
590
                        remaining_space = bufsize - len;
 
591
                }
 
592
        }
 
593
 
 
594
        len += tdb_pack(p, remaining_space, "dPd", pass->pass_len,
 
595
                             pass->pass, pass->mod_time);
 
596
        if (pack_buf) {
 
597
                p = pack_buf + len;
 
598
                remaining_space = bufsize - len;
 
599
        }
 
600
 
 
601
        /* packing SID structure */
 
602
        len += tdb_sid_pack(p, remaining_space, &pass->domain_sid);
 
603
        if (pack_buf) {
 
604
                p = pack_buf + len;
 
605
                remaining_space = bufsize - len;
 
606
        }
 
607
 
 
608
        return len;
 
609
}
 
610
 
 
611
 
 
612
/**
 
613
 * Unpack TRUSTED_DOM_PASS passed by pointer
 
614
 *
 
615
 * @param pack_buf pointer to buffer with packed representation
 
616
 * @param bufsize size of the buffer
 
617
 * @param pass pointer to trusted domain password to be filled with unpacked data
 
618
 *
 
619
 * @return size of structure unpacked from buffer
 
620
 **/
 
621
static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize,
 
622
                                          TRUSTED_DOM_PASS* pass)
 
623
{
 
624
        int idx, len = 0;
 
625
        char *passp = NULL;
 
626
 
 
627
        if (!pack_buf || !pass) return -1;
 
628
 
 
629
        /* unpack unicode domain name and plaintext password */
 
630
        len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len);
 
631
 
 
632
        for (idx = 0; idx < 32; idx++)
 
633
                len +=  tdb_unpack(pack_buf + len, bufsize - len, "w",
 
634
                                   &pass->uni_name[idx]);
 
635
 
 
636
        len += tdb_unpack(pack_buf + len, bufsize - len, "dPd",
 
637
                          &pass->pass_len, &passp, &pass->mod_time);
 
638
        if (passp) {
 
639
                fstrcpy(pass->pass, passp);
 
640
        }
 
641
        SAFE_FREE(passp);
 
642
 
 
643
        /* unpack domain sid */
 
644
        len += tdb_sid_unpack(pack_buf + len, bufsize - len,
 
645
                              &pass->domain_sid);
 
646
 
 
647
        return len;
 
648
}
 
649
 
 
650
/************************************************************************
 
651
 Routine to get account password to trusted domain
 
652
************************************************************************/
 
653
 
 
654
bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
 
655
                                           DOM_SID *sid, time_t *pass_last_set_time)
 
656
{
 
657
        struct trusted_dom_pass pass;
 
658
        size_t size = 0;
 
659
 
 
660
        /* unpacking structures */
 
661
        uint8 *pass_buf;
 
662
        int pass_len = 0;
 
663
 
 
664
        ZERO_STRUCT(pass);
 
665
 
 
666
        /* fetching trusted domain password structure */
 
667
        if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain),
 
668
                                               &size))) {
 
669
                DEBUG(5, ("secrets_fetch failed!\n"));
 
670
                return False;
 
671
        }
 
672
 
 
673
        /* unpack trusted domain password */
 
674
        pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass);
 
675
        SAFE_FREE(pass_buf);
 
676
 
 
677
        if (pass_len != size) {
 
678
                DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
 
679
                return False;
 
680
        }
 
681
 
 
682
        /* the trust's password */
 
683
        if (pwd) {
 
684
                *pwd = SMB_STRDUP(pass.pass);
 
685
                if (!*pwd) {
 
686
                        return False;
 
687
                }
 
688
        }
 
689
 
 
690
        /* last change time */
 
691
        if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
 
692
 
 
693
        /* domain sid */
 
694
        if (sid != NULL) sid_copy(sid, &pass.domain_sid);
 
695
 
 
696
        return True;
 
697
}
 
698
 
 
699
/**
 
700
 * Routine to store the password for trusted domain
 
701
 *
 
702
 * @param domain remote domain name
 
703
 * @param pwd plain text password of trust relationship
 
704
 * @param sid remote domain sid
 
705
 *
 
706
 * @return true if succeeded
 
707
 **/
 
708
 
 
709
bool secrets_store_trusted_domain_password(const char* domain, const char* pwd,
 
710
                                           const DOM_SID *sid)
 
711
{
 
712
        smb_ucs2_t *uni_dom_name;
 
713
        bool ret;
 
714
        size_t converted_size;
 
715
 
 
716
        /* packing structures */
 
717
        uint8 *pass_buf = NULL;
 
718
        int pass_len = 0;
 
719
 
 
720
        struct trusted_dom_pass pass;
 
721
        ZERO_STRUCT(pass);
 
722
 
 
723
        if (!push_ucs2_allocate(&uni_dom_name, domain, &converted_size)) {
 
724
                DEBUG(0, ("Could not convert domain name %s to unicode\n",
 
725
                          domain));
 
726
                return False;
 
727
        }
 
728
 
 
729
        strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
 
730
        pass.uni_name_len = strlen_w(uni_dom_name)+1;
 
731
        SAFE_FREE(uni_dom_name);
 
732
 
 
733
        /* last change time */
 
734
        pass.mod_time = time(NULL);
 
735
 
 
736
        /* password of the trust */
 
737
        pass.pass_len = strlen(pwd);
 
738
        fstrcpy(pass.pass, pwd);
 
739
 
 
740
        /* domain sid */
 
741
        sid_copy(&pass.domain_sid, sid);
 
742
 
 
743
        /* Calculate the length. */
 
744
        pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass);
 
745
        pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len);
 
746
        if (!pass_buf) {
 
747
                return false;
 
748
        }
 
749
        pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass);
 
750
        ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf,
 
751
                        pass_len);
 
752
        SAFE_FREE(pass_buf);
 
753
        return ret;
 
754
}
 
755
 
 
756
/************************************************************************
 
757
 Routine to delete the plaintext machine account password
 
758
************************************************************************/
 
759
 
 
760
bool secrets_delete_machine_password(const char *domain)
 
761
{
 
762
        return secrets_delete(machine_password_keystr(domain));
 
763
}
 
764
 
 
765
/************************************************************************
 
766
 Routine to delete the plaintext machine account password, sec channel type and
 
767
 last change time from secrets database
 
768
************************************************************************/
 
769
 
 
770
bool secrets_delete_machine_password_ex(const char *domain)
 
771
{
 
772
        if (!secrets_delete(machine_password_keystr(domain))) {
 
773
                return false;
 
774
        }
 
775
        if (!secrets_delete(machine_sec_channel_type_keystr(domain))) {
 
776
                return false;
 
777
        }
 
778
        return secrets_delete(machine_last_change_time_keystr(domain));
 
779
}
 
780
 
 
781
/************************************************************************
 
782
 Routine to delete the domain sid
 
783
************************************************************************/
 
784
 
 
785
bool secrets_delete_domain_sid(const char *domain)
 
786
{
 
787
        return secrets_delete(domain_sid_keystr(domain));
 
788
}
 
789
 
 
790
/************************************************************************
 
791
 Routine to set the plaintext machine account password for a realm
 
792
the password is assumed to be a null terminated ascii string
 
793
************************************************************************/
 
794
 
 
795
bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
 
796
{
 
797
        bool ret;
 
798
        uint32 last_change_time;
 
799
        uint32 sec_channel_type;
 
800
 
 
801
        ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
 
802
        if (!ret)
 
803
                return ret;
 
804
 
 
805
        SIVAL(&last_change_time, 0, time(NULL));
 
806
        ret = secrets_store(machine_last_change_time_keystr(domain), &last_change_time, sizeof(last_change_time));
 
807
 
 
808
        SIVAL(&sec_channel_type, 0, sec_channel);
 
809
        ret = secrets_store(machine_sec_channel_type_keystr(domain), &sec_channel_type, sizeof(sec_channel_type));
 
810
 
 
811
        return ret;
 
812
}
 
813
 
 
814
/************************************************************************
 
815
 Routine to fetch the plaintext machine account password for a realm
 
816
 the password is assumed to be a null terminated ascii string.
 
817
************************************************************************/
 
818
 
 
819
char *secrets_fetch_machine_password(const char *domain,
 
820
                                     time_t *pass_last_set_time,
 
821
                                     uint32 *channel)
 
822
{
 
823
        char *ret;
 
824
        ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
 
825
 
 
826
        if (pass_last_set_time) {
 
827
                size_t size;
 
828
                uint32 *last_set_time;
 
829
                last_set_time = (unsigned int *)secrets_fetch(machine_last_change_time_keystr(domain), &size);
 
830
                if (last_set_time) {
 
831
                        *pass_last_set_time = IVAL(last_set_time,0);
 
832
                        SAFE_FREE(last_set_time);
 
833
                } else {
 
834
                        *pass_last_set_time = 0;
 
835
                }
 
836
        }
 
837
 
 
838
        if (channel) {
 
839
                size_t size;
 
840
                uint32 *channel_type;
 
841
                channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
 
842
                if (channel_type) {
 
843
                        *channel = IVAL(channel_type,0);
 
844
                        SAFE_FREE(channel_type);
 
845
                } else {
 
846
                        *channel = get_default_sec_channel();
 
847
                }
 
848
        }
 
849
 
 
850
        return ret;
 
851
}
 
852
 
 
853
/************************************************************************
 
854
 Routine to delete the password for trusted domain
 
855
************************************************************************/
 
856
 
 
857
bool trusted_domain_password_delete(const char *domain)
 
858
{
 
859
        return secrets_delete(trustdom_keystr(domain));
 
860
}
 
861
 
 
862
bool secrets_store_ldap_pw(const char* dn, char* pw)
 
863
{
 
864
        char *key = NULL;
 
865
        bool ret;
 
866
 
 
867
        if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
 
868
                DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
 
869
                return False;
 
870
        }
 
871
 
 
872
        ret = secrets_store(key, pw, strlen(pw)+1);
 
873
 
 
874
        SAFE_FREE(key);
 
875
        return ret;
 
876
}
 
877
 
 
878
/*******************************************************************
 
879
 Find the ldap password.
 
880
******************************************************************/
 
881
 
 
882
bool fetch_ldap_pw(char **dn, char** pw)
 
883
{
 
884
        char *key = NULL;
 
885
        size_t size = 0;
 
886
 
 
887
        *dn = smb_xstrdup(lp_ldap_admin_dn());
 
888
 
 
889
        if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
 
890
                SAFE_FREE(*dn);
 
891
                DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
 
892
        }
 
893
 
 
894
        *pw=(char *)secrets_fetch(key, &size);
 
895
        SAFE_FREE(key);
 
896
 
 
897
        if (!size) {
 
898
                /* Upgrade 2.2 style entry */
 
899
                char *p;
 
900
                char* old_style_key = SMB_STRDUP(*dn);
 
901
                char *data;
 
902
                fstring old_style_pw;
 
903
 
 
904
                if (!old_style_key) {
 
905
                        DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
 
906
                        return False;
 
907
                }
 
908
 
 
909
                for (p=old_style_key; *p; p++)
 
910
                        if (*p == ',') *p = '/';
 
911
 
 
912
                data=(char *)secrets_fetch(old_style_key, &size);
 
913
                if ((data == NULL) || (size < sizeof(old_style_pw))) {
 
914
                        DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
 
915
                        SAFE_FREE(old_style_key);
 
916
                        SAFE_FREE(*dn);
 
917
                        SAFE_FREE(data);
 
918
                        return False;
 
919
                }
 
920
 
 
921
                size = MIN(size, sizeof(fstring)-1);
 
922
                strncpy(old_style_pw, data, size);
 
923
                old_style_pw[size] = 0;
 
924
 
 
925
                SAFE_FREE(data);
 
926
 
 
927
                if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
 
928
                        DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
 
929
                        SAFE_FREE(old_style_key);
 
930
                        SAFE_FREE(*dn);
 
931
                        return False;
 
932
                }
 
933
                if (!secrets_delete(old_style_key)) {
 
934
                        DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
 
935
                }
 
936
 
 
937
                SAFE_FREE(old_style_key);
 
938
 
 
939
                *pw = smb_xstrdup(old_style_pw);
 
940
        }
 
941
 
 
942
        return True;
 
943
}
 
944
 
 
945
/**
 
946
 * Get trusted domains info from secrets.tdb.
 
947
 **/
 
948
 
 
949
struct list_trusted_domains_state {
 
950
        uint32 num_domains;
 
951
        struct trustdom_info **domains;
 
952
};
 
953
 
 
954
static int list_trusted_domain(struct db_record *rec, void *private_data)
 
955
{
 
956
        const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS);
 
957
        size_t converted_size, packed_size = 0;
 
958
        struct trusted_dom_pass pass;
 
959
        struct trustdom_info *dom_info;
 
960
 
 
961
        struct list_trusted_domains_state *state =
 
962
                (struct list_trusted_domains_state *)private_data;
 
963
 
 
964
        if ((rec->key.dsize < prefix_len)
 
965
            || (strncmp((char *)rec->key.dptr, SECRETS_DOMTRUST_ACCT_PASS,
 
966
                        prefix_len) != 0)) {
 
967
                return 0;
 
968
        }
 
969
 
 
970
        packed_size = tdb_trusted_dom_pass_unpack(
 
971
                rec->value.dptr, rec->value.dsize, &pass);
 
972
 
 
973
        if (rec->value.dsize != packed_size) {
 
974
                DEBUG(2, ("Secrets record is invalid!\n"));
 
975
                return 0;
 
976
        }
 
977
 
 
978
        if (pass.domain_sid.num_auths != 4) {
 
979
                DEBUG(0, ("SID %s is not a domain sid, has %d "
 
980
                          "auths instead of 4\n",
 
981
                          sid_string_dbg(&pass.domain_sid),
 
982
                          pass.domain_sid.num_auths));
 
983
                return 0;
 
984
        }
 
985
 
 
986
        if (!(dom_info = TALLOC_P(state->domains, struct trustdom_info))) {
 
987
                DEBUG(0, ("talloc failed\n"));
 
988
                return 0;
 
989
        }
 
990
 
 
991
        if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name,
 
992
                              &converted_size)) {
 
993
                DEBUG(2, ("pull_ucs2_talloc failed\n"));
 
994
                TALLOC_FREE(dom_info);
 
995
                return 0;
 
996
        }
 
997
 
 
998
        sid_copy(&dom_info->sid, &pass.domain_sid);
 
999
 
 
1000
        ADD_TO_ARRAY(state->domains, struct trustdom_info *, dom_info,
 
1001
                     &state->domains, &state->num_domains);
 
1002
 
 
1003
        if (state->domains == NULL) {
 
1004
                state->num_domains = 0;
 
1005
                return -1;
 
1006
        }
 
1007
        return 0;
 
1008
}
 
1009
 
 
1010
NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
 
1011
                                 struct trustdom_info ***domains)
 
1012
{
 
1013
        struct list_trusted_domains_state state;
 
1014
 
 
1015
        secrets_init();
 
1016
 
 
1017
        if (db_ctx == NULL) {
 
1018
                return NT_STATUS_ACCESS_DENIED;
 
1019
        }
 
1020
 
 
1021
        state.num_domains = 0;
 
1022
 
 
1023
        /*
 
1024
         * Make sure that a talloc context for the trustdom_info structs
 
1025
         * exists
 
1026
         */
 
1027
 
 
1028
        if (!(state.domains = TALLOC_ARRAY(
 
1029
                      mem_ctx, struct trustdom_info *, 1))) {
 
1030
                return NT_STATUS_NO_MEMORY;
 
1031
        }
 
1032
 
 
1033
        db_ctx->traverse_read(db_ctx, list_trusted_domain, (void *)&state);
 
1034
 
 
1035
        *num_domains = state.num_domains;
 
1036
        *domains = state.domains;
 
1037
        return NT_STATUS_OK;
 
1038
}
 
1039
 
 
1040
/*******************************************************************************
 
1041
 Store a complete AFS keyfile into secrets.tdb.
 
1042
*******************************************************************************/
 
1043
 
 
1044
bool secrets_store_afs_keyfile(const char *cell, const struct afs_keyfile *keyfile)
 
1045
{
 
1046
        fstring key;
 
1047
 
 
1048
        if ((cell == NULL) || (keyfile == NULL))
 
1049
                return False;
 
1050
 
 
1051
        if (ntohl(keyfile->nkeys) > SECRETS_AFS_MAXKEYS)
 
1052
                return False;
 
1053
 
 
1054
        slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
 
1055
        return secrets_store(key, keyfile, sizeof(struct afs_keyfile));
 
1056
}
 
1057
 
 
1058
/*******************************************************************************
 
1059
 Fetch the current (highest) AFS key from secrets.tdb
 
1060
*******************************************************************************/
 
1061
bool secrets_fetch_afs_key(const char *cell, struct afs_key *result)
 
1062
{
 
1063
        fstring key;
 
1064
        struct afs_keyfile *keyfile;
 
1065
        size_t size = 0;
 
1066
        uint32 i;
 
1067
 
 
1068
        slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
 
1069
 
 
1070
        keyfile = (struct afs_keyfile *)secrets_fetch(key, &size);
 
1071
 
 
1072
        if (keyfile == NULL)
 
1073
                return False;
 
1074
 
 
1075
        if (size != sizeof(struct afs_keyfile)) {
 
1076
                SAFE_FREE(keyfile);
 
1077
                return False;
 
1078
        }
 
1079
 
 
1080
        i = ntohl(keyfile->nkeys);
 
1081
 
 
1082
        if (i > SECRETS_AFS_MAXKEYS) {
 
1083
                SAFE_FREE(keyfile);
 
1084
                return False;
 
1085
        }
 
1086
 
 
1087
        *result = keyfile->entry[i-1];
 
1088
 
 
1089
        result->kvno = ntohl(result->kvno);
 
1090
 
 
1091
        SAFE_FREE(keyfile);
 
1092
 
 
1093
        return True;
 
1094
}
 
1095
 
 
1096
/******************************************************************************
 
1097
  When kerberos is not available, choose between anonymous or
 
1098
  authenticated connections.
 
1099
 
 
1100
  We need to use an authenticated connection if DCs have the
 
1101
  RestrictAnonymous registry entry set > 0, or the "Additional
 
1102
  restrictions for anonymous connections" set in the win2k Local
 
1103
  Security Policy.
 
1104
 
 
1105
  Caller to free() result in domain, username, password
 
1106
*******************************************************************************/
 
1107
void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
 
1108
{
 
1109
        *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
 
1110
        *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
 
1111
        *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
 
1112
 
 
1113
        if (*username && **username) {
 
1114
 
 
1115
                if (!*domain || !**domain)
 
1116
                        *domain = smb_xstrdup(lp_workgroup());
 
1117
 
 
1118
                if (!*password || !**password)
 
1119
                        *password = smb_xstrdup("");
 
1120
 
 
1121
                DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
 
1122
                          *domain, *username));
 
1123
 
 
1124
        } else {
 
1125
                DEBUG(3, ("IPC$ connections done anonymously\n"));
 
1126
                *username = smb_xstrdup("");
 
1127
                *domain = smb_xstrdup("");
 
1128
                *password = smb_xstrdup("");
 
1129
        }
 
1130
}
 
1131
 
 
1132
/******************************************************************************
 
1133
 Open or create the schannel session store tdb.
 
1134
*******************************************************************************/
 
1135
 
 
1136
static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
 
1137
{
 
1138
        TDB_DATA vers;
 
1139
        uint32 ver;
 
1140
        TDB_CONTEXT *tdb_sc = NULL;
 
1141
        char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir());
 
1142
 
 
1143
        if (!fname) {
 
1144
                return NULL;
 
1145
        }
 
1146
 
 
1147
        tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
 
1148
 
 
1149
        if (!tdb_sc) {
 
1150
                DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
 
1151
                TALLOC_FREE(fname);
 
1152
                return NULL;
 
1153
        }
 
1154
 
 
1155
        vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION");
 
1156
        if (vers.dptr == NULL) {
 
1157
                /* First opener, no version. */
 
1158
                SIVAL(&ver,0,1);
 
1159
                vers.dptr = (uint8 *)&ver;
 
1160
                vers.dsize = 4;
 
1161
                tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE);
 
1162
                vers.dptr = NULL;
 
1163
        } else if (vers.dsize == 4) {
 
1164
                ver = IVAL(vers.dptr,0);
 
1165
                if (ver != 1) {
 
1166
                        tdb_close(tdb_sc);
 
1167
                        tdb_sc = NULL;
 
1168
                        DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n",
 
1169
                                (int)ver, fname ));
 
1170
                }
 
1171
        } else {
 
1172
                tdb_close(tdb_sc);
 
1173
                tdb_sc = NULL;
 
1174
                DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n",
 
1175
                        (int)vers.dsize, fname ));
 
1176
        }
 
1177
 
 
1178
        SAFE_FREE(vers.dptr);
 
1179
        TALLOC_FREE(fname);
 
1180
 
 
1181
        return tdb_sc;
 
1182
}
 
1183
 
 
1184
/******************************************************************************
 
1185
 Store the schannel state after an AUTH2 call.
 
1186
 Note we must be root here.
 
1187
*******************************************************************************/
 
1188
 
 
1189
bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
 
1190
                                const char *remote_machine,
 
1191
                                const struct dcinfo *pdc)
 
1192
{
 
1193
        TDB_CONTEXT *tdb_sc = NULL;
 
1194
        TDB_DATA value;
 
1195
        bool ret;
 
1196
        char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
 
1197
                                                  SECRETS_SCHANNEL_STATE,
 
1198
                                                  remote_machine);
 
1199
        if (!keystr) {
 
1200
                return False;
 
1201
        }
 
1202
 
 
1203
        /* Work out how large the record is. */
 
1204
        value.dsize = tdb_pack(NULL, 0, "dBBBBBfff",
 
1205
                                pdc->sequence,
 
1206
                                8, pdc->seed_chal.data,
 
1207
                                8, pdc->clnt_chal.data,
 
1208
                                8, pdc->srv_chal.data,
 
1209
                                16, pdc->sess_key,
 
1210
                                16, pdc->mach_pw,
 
1211
                                pdc->mach_acct,
 
1212
                                pdc->remote_machine,
 
1213
                                pdc->domain);
 
1214
 
 
1215
        value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize);
 
1216
        if (!value.dptr) {
 
1217
                TALLOC_FREE(keystr);
 
1218
                return False;
 
1219
        }
 
1220
 
 
1221
        value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff",
 
1222
                                pdc->sequence,
 
1223
                                8, pdc->seed_chal.data,
 
1224
                                8, pdc->clnt_chal.data,
 
1225
                                8, pdc->srv_chal.data,
 
1226
                                16, pdc->sess_key,
 
1227
                                16, pdc->mach_pw,
 
1228
                                pdc->mach_acct,
 
1229
                                pdc->remote_machine,
 
1230
                                pdc->domain);
 
1231
 
 
1232
        tdb_sc = open_schannel_session_store(mem_ctx);
 
1233
        if (!tdb_sc) {
 
1234
                TALLOC_FREE(keystr);
 
1235
                TALLOC_FREE(value.dptr);
 
1236
                return False;
 
1237
        }
 
1238
 
 
1239
        ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False);
 
1240
 
 
1241
        DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n",
 
1242
                keystr ));
 
1243
 
 
1244
        tdb_close(tdb_sc);
 
1245
        TALLOC_FREE(keystr);
 
1246
        TALLOC_FREE(value.dptr);
 
1247
        return ret;
 
1248
}
 
1249
 
 
1250
/******************************************************************************
 
1251
 Restore the schannel state on a client reconnect.
 
1252
 Note we must be root here.
 
1253
*******************************************************************************/
 
1254
 
 
1255
bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
 
1256
                                const char *remote_machine,
 
1257
                                struct dcinfo **ppdc)
 
1258
{
 
1259
        TDB_CONTEXT *tdb_sc = NULL;
 
1260
        TDB_DATA value;
 
1261
        unsigned char *pseed_chal = NULL;
 
1262
        unsigned char *pclnt_chal = NULL;
 
1263
        unsigned char *psrv_chal = NULL;
 
1264
        unsigned char *psess_key = NULL;
 
1265
        unsigned char *pmach_pw = NULL;
 
1266
        uint32 l1, l2, l3, l4, l5;
 
1267
        int ret;
 
1268
        struct dcinfo *pdc = NULL;
 
1269
        char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s",
 
1270
                                                  SECRETS_SCHANNEL_STATE,
 
1271
                                                  remote_machine);
 
1272
 
 
1273
        *ppdc = NULL;
 
1274
 
 
1275
        if (!keystr) {
 
1276
                return False;
 
1277
        }
 
1278
 
 
1279
        tdb_sc = open_schannel_session_store(mem_ctx);
 
1280
        if (!tdb_sc) {
 
1281
                TALLOC_FREE(keystr);
 
1282
                return False;
 
1283
        }
 
1284
 
 
1285
        value = tdb_fetch_bystring(tdb_sc, keystr);
 
1286
        if (!value.dptr) {
 
1287
                DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n",
 
1288
                        keystr ));
 
1289
                tdb_close(tdb_sc);
 
1290
                return False;
 
1291
        }
 
1292
 
 
1293
        pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
 
1294
 
 
1295
        /* Retrieve the record. */
 
1296
        ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
 
1297
                                &pdc->sequence,
 
1298
                                &l1, &pseed_chal,
 
1299
                                &l2, &pclnt_chal,
 
1300
                                &l3, &psrv_chal,
 
1301
                                &l4, &psess_key,
 
1302
                                &l5, &pmach_pw,
 
1303
                                &pdc->mach_acct,
 
1304
                                &pdc->remote_machine,
 
1305
                                &pdc->domain);
 
1306
 
 
1307
        if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
 
1308
                /* Bad record - delete it. */
 
1309
                tdb_delete_bystring(tdb_sc, keystr);
 
1310
                tdb_close(tdb_sc);
 
1311
                TALLOC_FREE(keystr);
 
1312
                TALLOC_FREE(pdc);
 
1313
                SAFE_FREE(pseed_chal);
 
1314
                SAFE_FREE(pclnt_chal);
 
1315
                SAFE_FREE(psrv_chal);
 
1316
                SAFE_FREE(psess_key);
 
1317
                SAFE_FREE(pmach_pw);
 
1318
                SAFE_FREE(value.dptr);
 
1319
                return False;
 
1320
        }
 
1321
 
 
1322
        tdb_close(tdb_sc);
 
1323
 
 
1324
        memcpy(pdc->seed_chal.data, pseed_chal, 8);
 
1325
        memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
 
1326
        memcpy(pdc->srv_chal.data, psrv_chal, 8);
 
1327
        memcpy(pdc->sess_key, psess_key, 16);
 
1328
        memcpy(pdc->mach_pw, pmach_pw, 16);
 
1329
 
 
1330
        /* We know these are true so didn't bother to store them. */
 
1331
        pdc->challenge_sent = True;
 
1332
        pdc->authenticated = True;
 
1333
 
 
1334
        DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
 
1335
                keystr ));
 
1336
 
 
1337
        SAFE_FREE(pseed_chal);
 
1338
        SAFE_FREE(pclnt_chal);
 
1339
        SAFE_FREE(psrv_chal);
 
1340
        SAFE_FREE(psess_key);
 
1341
        SAFE_FREE(pmach_pw);
 
1342
 
 
1343
        TALLOC_FREE(keystr);
 
1344
        SAFE_FREE(value.dptr);
 
1345
 
 
1346
        *ppdc = pdc;
 
1347
 
 
1348
        return True;
 
1349
}
 
1350
 
 
1351
bool secrets_store_generic(const char *owner, const char *key, const char *secret)
 
1352
{
 
1353
        char *tdbkey = NULL;
 
1354
        bool ret;
 
1355
 
 
1356
        if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
 
1357
                DEBUG(0, ("asprintf failed!\n"));
 
1358
                return False;
 
1359
        }
 
1360
 
 
1361
        ret = secrets_store(tdbkey, secret, strlen(secret)+1);
 
1362
 
 
1363
        SAFE_FREE(tdbkey);
 
1364
        return ret;
 
1365
}
 
1366
 
 
1367
/*******************************************************************
 
1368
 Find the ldap password.
 
1369
******************************************************************/
 
1370
 
 
1371
char *secrets_fetch_generic(const char *owner, const char *key)
 
1372
{
 
1373
        char *secret = NULL;
 
1374
        char *tdbkey = NULL;
 
1375
 
 
1376
        if (( ! owner) || ( ! key)) {
 
1377
                DEBUG(1, ("Invalid Paramters"));
 
1378
                return NULL;
 
1379
        }
 
1380
 
 
1381
        if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) {
 
1382
                DEBUG(0, ("Out of memory!\n"));
 
1383
                return NULL;
 
1384
        }
 
1385
 
 
1386
        secret = (char *)secrets_fetch(tdbkey, NULL);
 
1387
        SAFE_FREE(tdbkey);
 
1388
 
 
1389
        return secret;
 
1390
}
 
1391