Coverage Report

Created: 2026-05-24 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/passdb/machine_account_secrets.c
Line
Count
Source
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 "passdb.h"
27
#include "../libcli/auth/libcli_auth.h"
28
#include "secrets.h"
29
#include "dbwrap/dbwrap.h"
30
#include "../librpc/ndr/libndr.h"
31
#include "util_tdb.h"
32
#include "libcli/security/security.h"
33
34
#include "librpc/gen_ndr/libnet_join.h"
35
#include "librpc/gen_ndr/ndr_secrets.h"
36
#include "lib/crypto/crypto.h"
37
#include "lib/krb5_wrap/krb5_samba.h"
38
#include "lib/util/time_basic.h"
39
#include "../libds/common/flags.h"
40
#include "lib/util/string_wrappers.h"
41
42
#undef DBGC_CLASS
43
0
#define DBGC_CLASS DBGC_PASSDB
44
45
static char *domain_info_keystr(const char *domain);
46
47
static char *des_salt_key(const char *realm);
48
49
/**
50
 * Form a key for fetching the domain sid
51
 *
52
 * @param domain domain name
53
 *
54
 * @return keystring
55
 **/
56
static const char *domain_sid_keystr(const char *domain)
57
0
{
58
0
  char *keystr;
59
60
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
61
0
              SECRETS_DOMAIN_SID, domain);
62
0
  SMB_ASSERT(keystr != NULL);
63
0
  return keystr;
64
0
}
65
66
static const char *domain_guid_keystr(const char *domain)
67
0
{
68
0
  char *keystr;
69
70
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
71
0
              SECRETS_DOMAIN_GUID, domain);
72
0
  SMB_ASSERT(keystr != NULL);
73
0
  return keystr;
74
0
}
75
76
static const char *protect_ids_keystr(const char *domain)
77
0
{
78
0
  char *keystr;
79
80
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
81
0
              SECRETS_PROTECT_IDS, domain);
82
0
  SMB_ASSERT(keystr != NULL);
83
0
  return keystr;
84
0
}
85
86
/* N O T E: never use this outside of passdb modules that store the SID on their own */
87
bool secrets_mark_domain_protected(const char *domain)
88
0
{
89
0
  bool ret;
90
91
0
  ret = secrets_store(protect_ids_keystr(domain), "TRUE", 5);
92
0
  if (!ret) {
93
0
    DEBUG(0, ("Failed to protect the Domain IDs\n"));
94
0
  }
95
0
  return ret;
96
0
}
97
98
bool secrets_clear_domain_protection(const char *domain)
99
0
{
100
0
  bool ret;
101
0
  void *protection = secrets_fetch(protect_ids_keystr(domain), NULL);
102
103
0
  if (protection) {
104
0
    SAFE_FREE(protection);
105
0
    ret = secrets_delete_entry(protect_ids_keystr(domain));
106
0
    if (!ret) {
107
0
      DEBUG(0, ("Failed to remove Domain IDs protection\n"));
108
0
    }
109
0
    return ret;
110
0
  }
111
0
  return true;
112
0
}
113
114
bool secrets_store_domain_sid(const char *domain, const struct dom_sid  *sid)
115
0
{
116
0
  char *protect_ids;
117
0
  bool ret;
118
0
  struct dom_sid clean_sid = { 0 };
119
120
0
  protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
121
0
  if (protect_ids) {
122
0
    if (strncmp(protect_ids, "TRUE", 4)) {
123
0
      DEBUG(0, ("Refusing to store a Domain SID, "
124
0
          "it has been marked as protected!\n"));
125
0
      SAFE_FREE(protect_ids);
126
0
      return false;
127
0
    }
128
0
  }
129
0
  SAFE_FREE(protect_ids);
130
131
  /*
132
   * use a copy to prevent uninitialized memory from being carried over
133
   * to the tdb
134
   */
135
0
  sid_copy(&clean_sid, sid);
136
137
0
  ret = secrets_store(domain_sid_keystr(domain),
138
0
          &clean_sid,
139
0
          sizeof(struct dom_sid));
140
141
  /* Force a re-query */
142
0
  if (ret) {
143
    /*
144
     * Do not call get_global_domain_sid() here, or we will call it
145
     * recursively.
146
     */
147
0
    reset_global_sam_sid();
148
0
  }
149
0
  return ret;
150
0
}
151
152
bool secrets_fetch_domain_sid(const char *domain, struct dom_sid  *sid)
153
0
{
154
0
  struct dom_sid  *dyn_sid;
155
0
  size_t size = 0;
156
157
0
  dyn_sid = (struct dom_sid  *)secrets_fetch(domain_sid_keystr(domain), &size);
158
159
0
  if (dyn_sid == NULL)
160
0
    return False;
161
162
0
  if (size != sizeof(struct dom_sid)) {
163
0
    SAFE_FREE(dyn_sid);
164
0
    return False;
165
0
  }
166
167
0
  *sid = *dyn_sid;
168
0
  SAFE_FREE(dyn_sid);
169
0
  return True;
170
0
}
171
172
bool secrets_store_domain_guid(const char *domain, const struct GUID *guid)
173
0
{
174
0
  char *protect_ids;
175
0
  const char *key;
176
177
0
  protect_ids = secrets_fetch(protect_ids_keystr(domain), NULL);
178
0
  if (protect_ids) {
179
0
    if (strncmp(protect_ids, "TRUE", 4)) {
180
0
      DEBUG(0, ("Refusing to store a Domain SID, "
181
0
          "it has been marked as protected!\n"));
182
0
      SAFE_FREE(protect_ids);
183
0
      return false;
184
0
    }
185
0
  }
186
0
  SAFE_FREE(protect_ids);
187
188
0
  key = domain_guid_keystr(domain);
189
0
  return secrets_store(key, guid, sizeof(struct GUID));
190
0
}
191
192
bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
193
0
{
194
0
  struct GUID *dyn_guid;
195
0
  const char *key;
196
0
  size_t size = 0;
197
0
  struct GUID new_guid;
198
199
0
  key = domain_guid_keystr(domain);
200
0
  dyn_guid = (struct GUID *)secrets_fetch(key, &size);
201
202
0
  if (!dyn_guid) {
203
0
    if (lp_server_role() == ROLE_DOMAIN_PDC ||
204
0
        lp_server_role() == ROLE_IPA_DC) {
205
0
      new_guid = GUID_random();
206
0
      if (!secrets_store_domain_guid(domain, &new_guid))
207
0
        return False;
208
0
      dyn_guid = (struct GUID *)secrets_fetch(key, &size);
209
0
    }
210
0
    if (dyn_guid == NULL) {
211
0
      return False;
212
0
    }
213
0
  }
214
215
0
  if (size != sizeof(struct GUID)) {
216
0
    DEBUG(1,("UUID size %d is wrong!\n", (int)size));
217
0
    SAFE_FREE(dyn_guid);
218
0
    return False;
219
0
  }
220
221
0
  *guid = *dyn_guid;
222
0
  SAFE_FREE(dyn_guid);
223
0
  return True;
224
0
}
225
226
/**
227
 * Form a key for fetching the machine trust account sec channel type
228
 *
229
 * @param domain domain name
230
 *
231
 * @return keystring
232
 **/
233
static const char *machine_sec_channel_type_keystr(const char *domain)
234
0
{
235
0
  char *keystr;
236
237
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
238
0
              SECRETS_MACHINE_SEC_CHANNEL_TYPE,
239
0
              domain);
240
0
  SMB_ASSERT(keystr != NULL);
241
0
  return keystr;
242
0
}
243
244
/**
245
 * Form a key for fetching the machine trust account last change time
246
 *
247
 * @param domain domain name
248
 *
249
 * @return keystring
250
 **/
251
static const char *machine_last_change_time_keystr(const char *domain)
252
0
{
253
0
  char *keystr;
254
255
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
256
0
              SECRETS_MACHINE_LAST_CHANGE_TIME,
257
0
              domain);
258
0
  SMB_ASSERT(keystr != NULL);
259
0
  return keystr;
260
0
}
261
262
263
/**
264
 * Form a key for fetching the machine previous trust account password
265
 *
266
 * @param domain domain name
267
 *
268
 * @return keystring
269
 **/
270
static const char *machine_prev_password_keystr(const char *domain)
271
0
{
272
0
  char *keystr;
273
274
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
275
0
              SECRETS_MACHINE_PASSWORD_PREV, domain);
276
0
  SMB_ASSERT(keystr != NULL);
277
0
  return keystr;
278
0
}
279
280
/**
281
 * Form a key for fetching the machine trust account password
282
 *
283
 * @param domain domain name
284
 *
285
 * @return keystring
286
 **/
287
static const char *machine_password_keystr(const char *domain)
288
0
{
289
0
  char *keystr;
290
291
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
292
0
              SECRETS_MACHINE_PASSWORD, domain);
293
0
  SMB_ASSERT(keystr != NULL);
294
0
  return keystr;
295
0
}
296
297
/**
298
 * Form a key for fetching the machine trust account password
299
 *
300
 * @param domain domain name
301
 *
302
 * @return stored password's key
303
 **/
304
static const char *trust_keystr(const char *domain)
305
0
{
306
0
  char *keystr;
307
308
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
309
0
              SECRETS_MACHINE_ACCT_PASS, domain);
310
0
  SMB_ASSERT(keystr != NULL);
311
0
  return keystr;
312
0
}
313
314
/************************************************************************
315
 Routine to get the default secure channel type for trust accounts
316
************************************************************************/
317
318
enum netr_SchannelType get_default_sec_channel(void)
319
0
{
320
0
  if (IS_DC) {
321
0
    return SEC_CHAN_BDC;
322
0
  } else {
323
0
    return SEC_CHAN_WKSTA;
324
0
  }
325
0
}
326
327
/************************************************************************
328
 Routine to get the trust account password for a domain.
329
 This only tries to get the legacy hashed version of the password.
330
 The user of this function must have locked the trust password file using
331
 the above secrets_lock_trust_account_password().
332
************************************************************************/
333
334
bool secrets_fetch_trust_account_password_legacy(const char *domain,
335
             uint8_t ret_pwd[16],
336
             time_t *pass_last_set_time,
337
             enum netr_SchannelType *channel)
338
0
{
339
0
  struct machine_acct_pass *pass;
340
0
  size_t size = 0;
341
342
0
  if (!(pass = (struct machine_acct_pass *)secrets_fetch(
343
0
          trust_keystr(domain), &size))) {
344
0
    DEBUG(5, ("secrets_fetch failed!\n"));
345
0
    return False;
346
0
  }
347
348
0
  if (size != sizeof(*pass)) {
349
0
    DEBUG(0, ("secrets were of incorrect size!\n"));
350
0
    BURN_FREE(pass, size);
351
0
    return False;
352
0
  }
353
354
0
  if (pass_last_set_time) {
355
0
    *pass_last_set_time = pass->mod_time;
356
0
  }
357
0
  memcpy(ret_pwd, pass->hash, 16);
358
359
0
  if (channel) {
360
0
    *channel = get_default_sec_channel();
361
0
  }
362
363
0
  BURN_FREE(pass, size);
364
0
  return True;
365
0
}
366
367
/************************************************************************
368
 Routine to delete all information related to the domain joined machine.
369
************************************************************************/
370
371
bool secrets_delete_machine_password_ex(const char *domain, const char *realm)
372
0
{
373
0
  const char *tmpkey = NULL;
374
0
  bool ok;
375
376
0
  tmpkey = domain_info_keystr(domain);
377
0
  ok = secrets_delete(tmpkey);
378
0
  if (!ok) {
379
0
    return false;
380
0
  }
381
382
0
  if (realm != NULL) {
383
0
    tmpkey = des_salt_key(domain);
384
0
    ok = secrets_delete(tmpkey);
385
0
    if (!ok) {
386
0
      return false;
387
0
    }
388
0
  }
389
390
0
  tmpkey = domain_guid_keystr(domain);
391
0
  ok = secrets_delete(tmpkey);
392
0
  if (!ok) {
393
0
    return false;
394
0
  }
395
396
0
  tmpkey = machine_prev_password_keystr(domain);
397
0
  ok = secrets_delete(tmpkey);
398
0
  if (!ok) {
399
0
    return false;
400
0
  }
401
402
0
  tmpkey = machine_password_keystr(domain);
403
0
  ok = secrets_delete(tmpkey);
404
0
  if (!ok) {
405
0
    return false;
406
0
  }
407
408
0
  tmpkey = machine_sec_channel_type_keystr(domain);
409
0
  ok = secrets_delete(tmpkey);
410
0
  if (!ok) {
411
0
    return false;
412
0
  }
413
414
0
  tmpkey = machine_last_change_time_keystr(domain);
415
0
  ok = secrets_delete(tmpkey);
416
0
  if (!ok) {
417
0
    return false;
418
0
  }
419
420
0
  tmpkey = domain_sid_keystr(domain);
421
0
  ok = secrets_delete(tmpkey);
422
0
  if (!ok) {
423
0
    return false;
424
0
  }
425
426
0
  return true;
427
0
}
428
429
/************************************************************************
430
 Routine to delete the domain sid
431
************************************************************************/
432
433
bool secrets_delete_domain_sid(const char *domain)
434
0
{
435
0
  return secrets_delete_entry(domain_sid_keystr(domain));
436
0
}
437
438
/************************************************************************
439
 Set the machine trust account password, the old pw and last change
440
 time, domain SID and salting principals based on values passed in
441
 (added to support the secrets_tdb_sync module on secrets.ldb)
442
************************************************************************/
443
444
bool secrets_store_machine_pw_sync(const char *pass, const char *oldpass, const char *domain,
445
           const char *realm,
446
           const char *salting_principal, uint32_t supported_enc_types,
447
           const struct dom_sid *domain_sid, uint32_t last_change_time,
448
           uint32_t secure_channel_type,
449
           bool delete_join)
450
0
{
451
0
  bool ret;
452
0
  uint8_t last_change_time_store[4];
453
0
  TALLOC_CTX *frame = talloc_stackframe();
454
0
  uint8_t sec_channel_bytes[4];
455
456
0
  if (delete_join) {
457
0
    secrets_delete_machine_password_ex(domain, realm);
458
0
    TALLOC_FREE(frame);
459
0
    return true;
460
0
  }
461
462
0
  ret = secrets_store(machine_password_keystr(domain), pass, strlen(pass)+1);
463
0
  if (!ret) {
464
0
    TALLOC_FREE(frame);
465
0
    return ret;
466
0
  }
467
468
0
  if (oldpass) {
469
0
    ret = secrets_store(machine_prev_password_keystr(domain), oldpass, strlen(oldpass)+1);
470
0
  } else {
471
0
    ret = secrets_delete(machine_prev_password_keystr(domain));
472
0
  }
473
0
  if (!ret) {
474
0
    TALLOC_FREE(frame);
475
0
    return ret;
476
0
  }
477
478
0
  if (secure_channel_type == 0) {
479
    /* We delete this and instead have the read code fall back to
480
     * a default based on server role, as our caller can't specify
481
     * this with any more certainty */
482
0
    ret = secrets_delete(machine_sec_channel_type_keystr(domain));
483
0
    if (!ret) {
484
0
      TALLOC_FREE(frame);
485
0
      return ret;
486
0
    }
487
0
  } else {
488
0
    SIVAL(&sec_channel_bytes, 0, secure_channel_type);
489
0
    ret = secrets_store(machine_sec_channel_type_keystr(domain),
490
0
            &sec_channel_bytes, sizeof(sec_channel_bytes));
491
0
    if (!ret) {
492
0
      TALLOC_FREE(frame);
493
0
      return ret;
494
0
    }
495
0
  }
496
497
0
  SIVAL(&last_change_time_store, 0, last_change_time);
498
0
  ret = secrets_store(machine_last_change_time_keystr(domain),
499
0
          &last_change_time_store, sizeof(last_change_time));
500
501
0
  if (!ret) {
502
0
    TALLOC_FREE(frame);
503
0
    return ret;
504
0
  }
505
506
0
  ret = secrets_store_domain_sid(domain, domain_sid);
507
508
0
  if (!ret) {
509
0
    TALLOC_FREE(frame);
510
0
    return ret;
511
0
  }
512
513
0
  if (realm != NULL) {
514
0
    char *key = des_salt_key(realm);
515
516
0
    if (salting_principal != NULL) {
517
0
      ret = secrets_store(key,
518
0
              salting_principal,
519
0
              strlen(salting_principal)+1);
520
0
    } else {
521
0
      ret = secrets_delete(key);
522
0
    }
523
0
  }
524
525
0
  TALLOC_FREE(frame);
526
0
  return ret;
527
0
}
528
529
/************************************************************************
530
 Return the standard DES salt key
531
************************************************************************/
532
533
char* kerberos_standard_des_salt( void )
534
0
{
535
0
  fstring salt;
536
537
0
  fstr_sprintf( salt, "host/%s.%s@", lp_netbios_name(), lp_realm() );
538
0
  (void)strlower_m( salt );
539
0
  fstrcat( salt, lp_realm() );
540
541
0
  return SMB_STRDUP( salt );
542
0
}
543
544
/************************************************************************
545
************************************************************************/
546
547
static char *des_salt_key(const char *realm)
548
0
{
549
0
  char *keystr;
550
551
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/DES/%s",
552
0
              SECRETS_SALTING_PRINCIPAL,
553
0
              realm);
554
0
  SMB_ASSERT(keystr != NULL);
555
0
  return keystr;
556
0
}
557
558
/************************************************************************
559
************************************************************************/
560
561
bool kerberos_secrets_store_des_salt( const char* salt )
562
0
{
563
0
  char* key;
564
0
  bool ret;
565
566
0
  key = des_salt_key(lp_realm());
567
0
  if (key == NULL) {
568
0
    DEBUG(0,("kerberos_secrets_store_des_salt: failed to generate key!\n"));
569
0
    return False;
570
0
  }
571
572
0
  if ( !salt ) {
573
0
    DEBUG(8,("kerberos_secrets_store_des_salt: deleting salt\n"));
574
0
    secrets_delete_entry( key );
575
0
    return True;
576
0
  }
577
578
0
  DEBUG(3,("kerberos_secrets_store_des_salt: Storing salt \"%s\"\n", salt));
579
580
0
  ret = secrets_store( key, salt, strlen(salt)+1 );
581
582
0
  TALLOC_FREE(key);
583
584
0
  return ret;
585
0
}
586
587
/************************************************************************
588
************************************************************************/
589
590
static
591
char* kerberos_secrets_fetch_des_salt( void )
592
0
{
593
0
  char *salt, *key;
594
595
0
  key = des_salt_key(lp_realm());
596
0
  if (key == NULL) {
597
0
    DEBUG(0,("kerberos_secrets_fetch_des_salt: failed to generate key!\n"));
598
0
    return NULL;
599
0
  }
600
601
0
  salt = (char*)secrets_fetch( key, NULL );
602
603
0
  TALLOC_FREE(key);
604
605
0
  return salt;
606
0
}
607
608
/************************************************************************
609
 Routine to get the salting principal for this service.
610
 Caller must free if return is not null.
611
 ************************************************************************/
612
613
char *kerberos_secrets_fetch_salt_princ(void)
614
0
{
615
0
  char *salt_princ_s;
616
  /* lookup new key first */
617
618
0
  salt_princ_s = kerberos_secrets_fetch_des_salt();
619
0
  if (salt_princ_s == NULL) {
620
    /* fall back to host/machine.realm@REALM */
621
0
    salt_princ_s = kerberos_standard_des_salt();
622
0
  }
623
624
0
  return salt_princ_s;
625
0
}
626
627
/************************************************************************
628
 Routine to fetch the previous plaintext machine account password for a realm
629
 the password is assumed to be a null terminated ascii string.
630
************************************************************************/
631
632
char *secrets_fetch_prev_machine_password(const char *domain)
633
0
{
634
0
  return (char *)secrets_fetch(machine_prev_password_keystr(domain), NULL);
635
0
}
636
637
/************************************************************************
638
 Routine to fetch the last change time of the machine account password
639
  for a realm
640
************************************************************************/
641
642
time_t secrets_fetch_pass_last_set_time(const char *domain)
643
0
{
644
0
  uint32_t *last_set_time;
645
0
  time_t pass_last_set_time;
646
647
0
  last_set_time = secrets_fetch(machine_last_change_time_keystr(domain),
648
0
              NULL);
649
0
  if (last_set_time) {
650
0
    pass_last_set_time = IVAL(last_set_time,0);
651
0
    SAFE_FREE(last_set_time);
652
0
  } else {
653
0
    pass_last_set_time = 0;
654
0
  }
655
656
0
  return pass_last_set_time;
657
0
}
658
659
/************************************************************************
660
 Routine to fetch the plaintext machine account password for a realm
661
 the password is assumed to be a null terminated ascii string.
662
************************************************************************/
663
664
char *secrets_fetch_machine_password(const char *domain,
665
             time_t *pass_last_set_time,
666
             enum netr_SchannelType *channel)
667
0
{
668
0
  char *ret;
669
0
  ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL);
670
671
0
  if (pass_last_set_time) {
672
0
    *pass_last_set_time = secrets_fetch_pass_last_set_time(domain);
673
0
  }
674
675
0
  if (channel) {
676
0
    size_t size;
677
0
    uint32_t *channel_type;
678
0
    channel_type = (unsigned int *)secrets_fetch(machine_sec_channel_type_keystr(domain), &size);
679
0
    if (channel_type) {
680
0
      *channel = IVAL(channel_type,0);
681
0
      SAFE_FREE(channel_type);
682
0
    } else {
683
0
      *channel = get_default_sec_channel();
684
0
    }
685
0
  }
686
687
0
  return ret;
688
0
}
689
690
static int password_nt_hash_destructor(struct secrets_domain_info1_password *pw)
691
0
{
692
0
  ZERO_STRUCT(pw->nt_hash);
693
694
0
  return 0;
695
0
}
696
697
static int setup_password_zeroing(struct secrets_domain_info1_password *pw)
698
0
{
699
0
  if (pw != NULL) {
700
0
    size_t i;
701
702
0
    talloc_keep_secret(pw->cleartext_blob.data);
703
0
    talloc_set_destructor(pw, password_nt_hash_destructor);
704
0
    for (i = 0; i < pw->num_keys; i++) {
705
0
      talloc_keep_secret(pw->keys[i].value.data);
706
0
    }
707
0
  }
708
709
0
  return 0;
710
0
}
711
712
static char *domain_info_keystr(const char *domain)
713
0
{
714
0
  char *keystr;
715
716
0
  keystr = talloc_asprintf_strupper_m(talloc_tos(), "%s/%s",
717
0
              SECRETS_MACHINE_DOMAIN_INFO,
718
0
              domain);
719
0
  SMB_ASSERT(keystr != NULL);
720
0
  return keystr;
721
0
}
722
723
/************************************************************************
724
 Routine to get account password to trusted domain
725
************************************************************************/
726
727
static NTSTATUS secrets_fetch_domain_info1_by_key(const char *key,
728
        TALLOC_CTX *mem_ctx,
729
        struct secrets_domain_info1 **_info1)
730
0
{
731
0
  struct secrets_domain_infoB sdib = { .version = 0, };
732
0
  enum ndr_err_code ndr_err;
733
  /* unpacking structures */
734
0
  DATA_BLOB blob;
735
736
  /* fetching trusted domain password structure */
737
0
  blob.data = (uint8_t *)secrets_fetch(key, &blob.length);
738
0
  if (blob.data == NULL) {
739
0
    DBG_NOTICE("secrets_fetch failed!\n");
740
0
    return NT_STATUS_OBJECT_NAME_NOT_FOUND;
741
0
  }
742
743
  /* unpack trusted domain password */
744
0
  ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sdib,
745
0
      (ndr_pull_flags_fn_t)ndr_pull_secrets_domain_infoB);
746
0
  BURN_FREE(blob.data, blob.length);
747
0
  if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
748
0
    DBG_ERR("ndr_pull_struct_blob failed - %s!\n",
749
0
      ndr_errstr(ndr_err));
750
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
751
0
  }
752
753
0
  if (sdib.info.info1->next_change != NULL) {
754
0
    setup_password_zeroing(sdib.info.info1->next_change->password);
755
0
  }
756
0
  setup_password_zeroing(sdib.info.info1->password);
757
0
  setup_password_zeroing(sdib.info.info1->old_password);
758
0
  setup_password_zeroing(sdib.info.info1->older_password);
759
760
0
  if (sdib.version != SECRETS_DOMAIN_INFO_VERSION_1) {
761
0
    DBG_ERR("sdib.version = %u\n", (unsigned)sdib.version);
762
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
763
0
  }
764
765
0
  *_info1 = sdib.info.info1;
766
0
  return NT_STATUS_OK;;
767
0
}
768
769
static NTSTATUS secrets_fetch_domain_info(const char *domain,
770
            TALLOC_CTX *mem_ctx,
771
            struct secrets_domain_info1 **pinfo)
772
0
{
773
0
  char *key = domain_info_keystr(domain);
774
0
  return secrets_fetch_domain_info1_by_key(key, mem_ctx, pinfo);
775
0
}
776
777
void secrets_debug_domain_info(int lvl, const struct secrets_domain_info1 *info1,
778
             const char *name)
779
0
{
780
0
  struct secrets_domain_infoB sdib = {
781
0
    .version = SECRETS_DOMAIN_INFO_VERSION_1,
782
0
  };
783
784
0
  sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
785
786
0
  NDR_PRINT_DEBUG_LEVEL(lvl, secrets_domain_infoB, &sdib);
787
0
}
788
789
char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domain_info1 *info1,
790
         const char *name, bool include_secrets)
791
0
{
792
0
  TALLOC_CTX *frame = talloc_stackframe();
793
0
  struct secrets_domain_infoB sdib = {
794
0
    .version = SECRETS_DOMAIN_INFO_VERSION_1,
795
0
  };
796
0
  struct ndr_print *ndr = NULL;
797
0
  char *ret = NULL;
798
799
0
  sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
800
801
0
  ndr = talloc_zero(frame, struct ndr_print);
802
0
  if (ndr == NULL) {
803
0
    TALLOC_FREE(frame);
804
0
    return NULL;
805
0
  }
806
0
  ndr->private_data = talloc_strdup(ndr, "");
807
0
  if (ndr->private_data == NULL) {
808
0
    TALLOC_FREE(frame);
809
0
    return NULL;
810
0
  }
811
0
  ndr->print = ndr_print_string_helper;
812
0
  ndr->depth = 1;
813
0
  ndr->print_secrets = include_secrets;
814
815
0
  ndr_print_secrets_domain_infoB(ndr, name, &sdib);
816
0
  ret = talloc_steal(mem_ctx, (char *)ndr->private_data);
817
0
  TALLOC_FREE(frame);
818
0
  return ret;
819
0
}
820
821
static NTSTATUS secrets_store_domain_info1_by_key(const char *key,
822
          const struct secrets_domain_info1 *info1)
823
0
{
824
0
  struct secrets_domain_infoB sdib = {
825
0
    .version = SECRETS_DOMAIN_INFO_VERSION_1,
826
0
  };
827
  /* packing structures */
828
0
  DATA_BLOB blob;
829
0
  enum ndr_err_code ndr_err;
830
0
  bool ok;
831
832
0
  sdib.info.info1 = discard_const_p(struct secrets_domain_info1, info1);
833
834
0
  ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &sdib,
835
0
      (ndr_push_flags_fn_t)ndr_push_secrets_domain_infoB);
836
0
  if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
837
0
    return ndr_map_error2ntstatus(ndr_err);
838
0
  }
839
840
0
  ok = secrets_store(key, blob.data, blob.length);
841
0
  data_blob_clear_free(&blob);
842
0
  if (!ok) {
843
0
    return NT_STATUS_INTERNAL_DB_ERROR;
844
0
  }
845
846
0
  return NT_STATUS_OK;
847
0
}
848
849
static NTSTATUS secrets_store_domain_info(const struct secrets_domain_info1 *info,
850
            bool upgrade)
851
0
{
852
0
  TALLOC_CTX *frame = talloc_stackframe();
853
0
  const char *domain = info->domain_info.name.string;
854
0
  const char *realm = info->domain_info.dns_domain.string;
855
0
  char *key = domain_info_keystr(domain);
856
0
  struct db_context *db = NULL;
857
0
  struct timeval last_change_tv;
858
0
  const DATA_BLOB *cleartext_blob = NULL;
859
0
  DATA_BLOB pw_blob = data_blob_null;
860
0
  DATA_BLOB old_pw_blob = data_blob_null;
861
0
  const char *pw = NULL;
862
0
  const char *old_pw = NULL;
863
0
  bool ok;
864
0
  NTSTATUS status;
865
0
  int ret;
866
0
  int role = lp_server_role();
867
868
0
  switch (info->secure_channel_type) {
869
0
  case SEC_CHAN_WKSTA:
870
0
  case SEC_CHAN_BDC:
871
0
    if (!upgrade && role >= ROLE_ACTIVE_DIRECTORY_DC) {
872
0
      DBG_ERR("AD_DC not supported for %s\n",
873
0
        domain);
874
0
      TALLOC_FREE(frame);
875
0
      return NT_STATUS_INTERNAL_ERROR;
876
0
    }
877
878
0
    break;
879
0
  default:
880
0
    DBG_ERR("SEC_CHAN_* not supported for %s\n",
881
0
      domain);
882
0
    TALLOC_FREE(frame);
883
0
    return NT_STATUS_INTERNAL_ERROR;
884
0
  }
885
886
0
  db = secrets_db_ctx();
887
888
0
  ret = dbwrap_transaction_start(db);
889
0
  if (ret != 0) {
890
0
    DBG_ERR("dbwrap_transaction_start() failed for %s\n",
891
0
      domain);
892
0
    TALLOC_FREE(frame);
893
0
    return NT_STATUS_INTERNAL_DB_ERROR;
894
0
  }
895
896
0
  ok = secrets_clear_domain_protection(domain);
897
0
  if (!ok) {
898
0
    DBG_ERR("secrets_clear_domain_protection(%s) failed\n",
899
0
      domain);
900
0
    dbwrap_transaction_cancel(db);
901
0
    TALLOC_FREE(frame);
902
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
903
0
  }
904
905
0
  ok = secrets_delete_machine_password_ex(domain, realm);
906
0
  if (!ok) {
907
0
    DBG_ERR("secrets_delete_machine_password_ex(%s) failed\n",
908
0
      domain);
909
0
    dbwrap_transaction_cancel(db);
910
0
    TALLOC_FREE(frame);
911
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
912
0
  }
913
914
0
  status = secrets_store_domain_info1_by_key(key, info);
915
0
  if (!NT_STATUS_IS_OK(status)) {
916
0
    DBG_ERR("secrets_store_domain_info1_by_key() failed "
917
0
      "for %s - %s\n", domain, nt_errstr(status));
918
0
    dbwrap_transaction_cancel(db);
919
0
    TALLOC_FREE(frame);
920
0
    return status;
921
0
  }
922
923
  /*
924
   * We use info->password_last_change instead
925
   * of info->password.change_time because
926
   * we may want to defer the next change approach
927
   * if the server rejected the change the last time,
928
   * e.g. due to RefusePasswordChange=1.
929
   */
930
0
  nttime_to_timeval(&last_change_tv, info->password_last_change);
931
932
0
  cleartext_blob = &info->password->cleartext_blob;
933
0
  ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
934
0
           cleartext_blob->data,
935
0
           cleartext_blob->length,
936
0
           (void **)&pw_blob.data,
937
0
           &pw_blob.length);
938
0
  if (!ok) {
939
0
    status = NT_STATUS_UNMAPPABLE_CHARACTER;
940
0
    if (errno == ENOMEM) {
941
0
      status = NT_STATUS_NO_MEMORY;
942
0
    }
943
0
    DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
944
0
      "failed for pw of %s - %s\n",
945
0
      domain, nt_errstr(status));
946
0
    dbwrap_transaction_cancel(db);
947
0
    TALLOC_FREE(frame);
948
0
    return status;
949
0
  }
950
0
  pw = (const char *)pw_blob.data;
951
0
  if (info->old_password != NULL) {
952
0
    cleartext_blob = &info->old_password->cleartext_blob;
953
0
    ok = convert_string_talloc(frame, CH_UTF16MUNGED, CH_UNIX,
954
0
             cleartext_blob->data,
955
0
             cleartext_blob->length,
956
0
             (void **)&old_pw_blob.data,
957
0
             &old_pw_blob.length);
958
0
    if (!ok) {
959
0
      status = NT_STATUS_UNMAPPABLE_CHARACTER;
960
0
      if (errno == ENOMEM) {
961
0
        status = NT_STATUS_NO_MEMORY;
962
0
      }
963
0
      DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
964
0
        "failed for old_pw of %s - %s\n",
965
0
        domain, nt_errstr(status));
966
0
      dbwrap_transaction_cancel(db);
967
0
      data_blob_clear_free(&pw_blob);
968
0
      TALLOC_FREE(frame);
969
0
      return status;
970
0
    }
971
0
    old_pw = (const char *)old_pw_blob.data;
972
0
  }
973
974
0
  ok = secrets_store_machine_pw_sync(pw, old_pw,
975
0
             domain, realm,
976
0
             info->salt_principal,
977
0
             info->supported_enc_types,
978
0
             info->domain_info.sid,
979
0
             last_change_tv.tv_sec,
980
0
             info->secure_channel_type,
981
0
             false); /* delete_join */
982
0
  data_blob_clear_free(&pw_blob);
983
0
  data_blob_clear_free(&old_pw_blob);
984
0
  if (!ok) {
985
0
    DBG_ERR("secrets_store_machine_pw_sync(%s) failed\n",
986
0
      domain);
987
0
    dbwrap_transaction_cancel(db);
988
0
    TALLOC_FREE(frame);
989
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
990
0
  }
991
992
0
  if (!GUID_all_zero(&info->domain_info.domain_guid)) {
993
0
    ok = secrets_store_domain_guid(domain,
994
0
        &info->domain_info.domain_guid);
995
0
    if (!ok) {
996
0
      DBG_ERR("secrets_store_domain_guid(%s) failed\n",
997
0
        domain);
998
0
      dbwrap_transaction_cancel(db);
999
0
      TALLOC_FREE(frame);
1000
0
      return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1001
0
    }
1002
0
  }
1003
1004
0
  ok = secrets_mark_domain_protected(domain);
1005
0
  if (!ok) {
1006
0
    DBG_ERR("secrets_mark_domain_protected(%s) failed\n",
1007
0
      domain);
1008
0
    dbwrap_transaction_cancel(db);
1009
0
    TALLOC_FREE(frame);
1010
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1011
0
  }
1012
1013
0
  ret = dbwrap_transaction_commit(db);
1014
0
  if (ret != 0) {
1015
0
    DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1016
0
      domain);
1017
0
    TALLOC_FREE(frame);
1018
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1019
0
  }
1020
1021
0
  TALLOC_FREE(frame);
1022
0
  return NT_STATUS_OK;
1023
0
}
1024
1025
static int secrets_domain_info_kerberos_keys(struct secrets_domain_info1_password *p,
1026
               const char *salt_principal)
1027
0
{
1028
0
#ifdef HAVE_ADS
1029
0
  krb5_error_code krb5_ret;
1030
0
  krb5_context krb5_ctx = NULL;
1031
0
  DATA_BLOB cleartext_utf8_b = data_blob_null;
1032
0
  krb5_data cleartext_utf8;
1033
0
  krb5_data salt;
1034
0
  krb5_keyblock key;
1035
0
  DATA_BLOB aes_256_b = data_blob_null;
1036
0
  DATA_BLOB aes_128_b = data_blob_null;
1037
0
  bool ok;
1038
0
#endif /* HAVE_ADS */
1039
0
  DATA_BLOB arc4_b = data_blob_null;
1040
0
  const uint16_t max_keys = 3;
1041
0
  struct secrets_domain_info1_kerberos_key *keys = NULL;
1042
0
  uint16_t idx = 0;
1043
0
  char *salt_data = NULL;
1044
1045
  /*
1046
   * We calculate:
1047
   * ENCTYPE_AES256_CTS_HMAC_SHA1_96
1048
   * ENCTYPE_AES128_CTS_HMAC_SHA1_96
1049
   * ENCTYPE_ARCFOUR_HMAC
1050
   *
1051
   * We don't include ENCTYPE_DES_CBC_CRC
1052
   * and ENCTYPE_DES_CBC_MD5
1053
   * as they are no longer supported.
1054
   *
1055
   * Note we store all enctypes we support,
1056
   * including the weak encryption types,
1057
   * but that's no problem as we also
1058
   * store the cleartext password anyway.
1059
   *
1060
   * Which values are then used to construct
1061
   * a keytab is configured at runtime and the
1062
   * configuration of msDS-SupportedEncryptionTypes.
1063
   *
1064
   * If we don't have kerberos support or no
1065
   * salt, we only generate an entry for arcfour-hmac-md5.
1066
   */
1067
0
  keys = talloc_zero_array(p,
1068
0
         struct secrets_domain_info1_kerberos_key,
1069
0
         max_keys);
1070
0
  if (keys == NULL) {
1071
0
    return ENOMEM;
1072
0
  }
1073
1074
0
  arc4_b = data_blob_talloc_s(keys,
1075
0
          p->nt_hash.hash,
1076
0
          sizeof(p->nt_hash.hash));
1077
0
  if (arc4_b.data == NULL) {
1078
0
    DBG_ERR("data_blob_talloc failed for arcfour-hmac-md5.\n");
1079
0
    TALLOC_FREE(keys);
1080
0
    return ENOMEM;
1081
0
  }
1082
1083
0
#ifdef HAVE_ADS
1084
0
  if (salt_principal == NULL) {
1085
0
    goto no_kerberos;
1086
0
  }
1087
1088
0
  krb5_ret = smb_krb5_init_context_common(&krb5_ctx);
1089
0
  if (krb5_ret != 0) {
1090
0
    DBG_ERR("kerberos init context failed (%s)\n",
1091
0
      error_message(krb5_ret));
1092
0
    TALLOC_FREE(keys);
1093
0
    return krb5_ret;
1094
0
  }
1095
1096
0
  krb5_ret = smb_krb5_salt_principal2data(krb5_ctx, salt_principal,
1097
0
            p, &salt_data);
1098
0
  if (krb5_ret != 0) {
1099
0
    DBG_ERR("smb_krb5_salt_principal2data(%s) failed: %s\n",
1100
0
      salt_principal,
1101
0
      smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1102
0
    krb5_free_context(krb5_ctx);
1103
0
    TALLOC_FREE(keys);
1104
0
    return krb5_ret;
1105
0
  }
1106
1107
0
  salt = (krb5_data) {
1108
0
    .data = discard_const(salt_data),
1109
0
    .length = strlen(salt_data),
1110
0
  };
1111
1112
0
  ok = convert_string_talloc(keys, CH_UTF16MUNGED, CH_UTF8,
1113
0
           p->cleartext_blob.data,
1114
0
           p->cleartext_blob.length,
1115
0
           (void **)&cleartext_utf8_b.data,
1116
0
           &cleartext_utf8_b.length);
1117
0
  if (!ok) {
1118
0
    if (errno != 0) {
1119
0
      krb5_ret = errno;
1120
0
    } else {
1121
0
      krb5_ret = EINVAL;
1122
0
    }
1123
0
    krb5_free_context(krb5_ctx);
1124
0
    TALLOC_FREE(keys);
1125
0
    return krb5_ret;
1126
0
  }
1127
0
  talloc_keep_secret(cleartext_utf8_b.data);
1128
0
  cleartext_utf8.data = (void *)cleartext_utf8_b.data;
1129
0
  cleartext_utf8.length = cleartext_utf8_b.length;
1130
1131
0
  krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1132
0
               NULL,
1133
0
               &salt,
1134
0
               &cleartext_utf8,
1135
0
               ENCTYPE_AES256_CTS_HMAC_SHA1_96,
1136
0
               &key);
1137
0
  if (krb5_ret != 0) {
1138
0
    DBG_ERR("generation of a aes256-cts-hmac-sha1-96 key failed: %s\n",
1139
0
      smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1140
0
    krb5_free_context(krb5_ctx);
1141
0
    TALLOC_FREE(keys);
1142
0
    TALLOC_FREE(salt_data);
1143
0
    return krb5_ret;
1144
0
  }
1145
0
  aes_256_b = data_blob_talloc_s(keys,
1146
0
             KRB5_KEY_DATA(&key),
1147
0
             KRB5_KEY_LENGTH(&key));
1148
0
  krb5_free_keyblock_contents(krb5_ctx, &key);
1149
0
  if (aes_256_b.data == NULL) {
1150
0
    DBG_ERR("data_blob_talloc failed for aes-256.\n");
1151
0
    krb5_free_context(krb5_ctx);
1152
0
    TALLOC_FREE(keys);
1153
0
    TALLOC_FREE(salt_data);
1154
0
    return ENOMEM;
1155
0
  }
1156
1157
0
  krb5_ret = smb_krb5_create_key_from_string(krb5_ctx,
1158
0
               NULL,
1159
0
               &salt,
1160
0
               &cleartext_utf8,
1161
0
               ENCTYPE_AES128_CTS_HMAC_SHA1_96,
1162
0
               &key);
1163
0
  if (krb5_ret != 0) {
1164
0
    DBG_ERR("generation of a aes128-cts-hmac-sha1-96 key failed: %s\n",
1165
0
      smb_get_krb5_error_message(krb5_ctx, krb5_ret, keys));
1166
0
    krb5_free_context(krb5_ctx);
1167
0
    TALLOC_FREE(keys);
1168
0
    TALLOC_FREE(salt_data);
1169
0
    return krb5_ret;
1170
0
  }
1171
0
  aes_128_b = data_blob_talloc_s(keys,
1172
0
             KRB5_KEY_DATA(&key),
1173
0
             KRB5_KEY_LENGTH(&key));
1174
0
  krb5_free_keyblock_contents(krb5_ctx, &key);
1175
0
  if (aes_128_b.data == NULL) {
1176
0
    DBG_ERR("data_blob_talloc failed for aes-128.\n");
1177
0
    krb5_free_context(krb5_ctx);
1178
0
    TALLOC_FREE(keys);
1179
0
    TALLOC_FREE(salt_data);
1180
0
    return ENOMEM;
1181
0
  }
1182
1183
0
  krb5_free_context(krb5_ctx);
1184
0
no_kerberos:
1185
1186
0
  if (aes_256_b.length != 0) {
1187
0
    keys[idx].keytype   = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1188
0
    keys[idx].iteration_count = 4096;
1189
0
    keys[idx].value     = aes_256_b;
1190
0
    idx += 1;
1191
0
  }
1192
1193
0
  if (aes_128_b.length != 0) {
1194
0
    keys[idx].keytype   = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1195
0
    keys[idx].iteration_count = 4096;
1196
0
    keys[idx].value     = aes_128_b;
1197
0
    idx += 1;
1198
0
  }
1199
1200
0
#endif /* HAVE_ADS */
1201
1202
0
  keys[idx].keytype   = ENCTYPE_ARCFOUR_HMAC;
1203
0
  keys[idx].iteration_count = 4096;
1204
0
  keys[idx].value     = arc4_b;
1205
0
  idx += 1;
1206
1207
0
  p->salt_data = salt_data;
1208
0
  p->default_iteration_count = 4096;
1209
0
  p->num_keys = idx;
1210
0
  p->keys = keys;
1211
0
  return 0;
1212
0
}
1213
1214
static NTSTATUS secrets_domain_info_password_create(TALLOC_CTX *mem_ctx,
1215
        const char *cleartext_unix,
1216
        const char *salt_principal,
1217
        NTTIME change_time,
1218
        const char *change_server,
1219
        struct secrets_domain_info1_password **_p)
1220
0
{
1221
0
  struct secrets_domain_info1_password *p = NULL;
1222
0
  bool ok;
1223
0
  size_t len;
1224
0
  int ret;
1225
1226
0
  if (change_server == NULL) {
1227
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
1228
0
  }
1229
1230
0
  p = talloc_zero(mem_ctx, struct secrets_domain_info1_password);
1231
0
  if (p == NULL) {
1232
0
    return NT_STATUS_NO_MEMORY;
1233
0
  }
1234
0
  p->change_time = change_time;
1235
0
  p->change_server = talloc_strdup(p, change_server);
1236
0
  if (p->change_server == NULL) {
1237
0
    TALLOC_FREE(p);
1238
0
    return NT_STATUS_NO_MEMORY;
1239
0
  }
1240
0
  len = strlen(cleartext_unix);
1241
0
  ok = convert_string_talloc(p, CH_UNIX, CH_UTF16,
1242
0
           cleartext_unix, len,
1243
0
           (void **)&p->cleartext_blob.data,
1244
0
           &p->cleartext_blob.length);
1245
0
  if (!ok) {
1246
0
    NTSTATUS status = NT_STATUS_UNMAPPABLE_CHARACTER;
1247
0
    if (errno == ENOMEM) {
1248
0
      status = NT_STATUS_NO_MEMORY;
1249
0
    }
1250
0
    TALLOC_FREE(p);
1251
0
    return status;
1252
0
  }
1253
0
  talloc_keep_secret(p->cleartext_blob.data);
1254
0
  mdfour(p->nt_hash.hash,
1255
0
         p->cleartext_blob.data,
1256
0
         p->cleartext_blob.length);
1257
1258
0
  talloc_set_destructor(p, password_nt_hash_destructor);
1259
0
  ret = secrets_domain_info_kerberos_keys(p, salt_principal);
1260
0
  if (ret != 0) {
1261
0
    NTSTATUS status = krb5_to_nt_status(ret);
1262
0
    TALLOC_FREE(p);
1263
0
    return status;
1264
0
  }
1265
1266
0
  *_p = p;
1267
0
  return NT_STATUS_OK;
1268
0
}
1269
1270
NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain,
1271
          TALLOC_CTX *mem_ctx,
1272
          struct secrets_domain_info1 **pinfo)
1273
0
{
1274
0
  TALLOC_CTX *frame = NULL;
1275
0
  struct secrets_domain_info1 *old = NULL;
1276
0
  struct secrets_domain_info1 *info = NULL;
1277
0
  const char *dns_domain = NULL;
1278
0
  const char *server = NULL;
1279
0
  struct db_context *db = NULL;
1280
0
  time_t last_set_time;
1281
0
  NTTIME last_set_nt;
1282
0
  enum netr_SchannelType channel;
1283
0
  char *pw = NULL;
1284
0
  char *old_pw = NULL;
1285
0
  struct dom_sid domain_sid;
1286
0
  struct GUID domain_guid;
1287
0
  bool ok;
1288
0
  NTSTATUS status;
1289
0
  int ret;
1290
1291
0
  ok = strequal(domain, lp_workgroup());
1292
0
  if (ok) {
1293
0
    dns_domain = lp_dnsdomain();
1294
1295
0
    if (dns_domain != NULL && dns_domain[0] == '\0') {
1296
0
      dns_domain = NULL;
1297
0
    }
1298
0
  }
1299
1300
0
  last_set_time = secrets_fetch_pass_last_set_time(domain);
1301
0
  if (last_set_time == 0) {
1302
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1303
0
  }
1304
0
  unix_to_nt_time(&last_set_nt, last_set_time);
1305
1306
0
  frame = talloc_stackframe();
1307
1308
0
  status = secrets_fetch_domain_info(domain, frame, &old);
1309
0
  if (NT_STATUS_IS_OK(status)) {
1310
0
    if (old->password_last_change >= last_set_nt) {
1311
0
      *pinfo = talloc_move(mem_ctx, &old);
1312
0
      TALLOC_FREE(frame);
1313
0
      return NT_STATUS_OK;
1314
0
    }
1315
0
    TALLOC_FREE(old);
1316
0
  }
1317
1318
0
  info = talloc_zero(frame, struct secrets_domain_info1);
1319
0
  if (info == NULL) {
1320
0
    DBG_ERR("talloc_zero failed\n");
1321
0
    TALLOC_FREE(frame);
1322
0
    return NT_STATUS_NO_MEMORY;
1323
0
  }
1324
1325
0
  db = secrets_db_ctx();
1326
1327
0
  ret = dbwrap_transaction_start(db);
1328
0
  if (ret != 0) {
1329
0
    DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1330
0
      domain);
1331
0
    TALLOC_FREE(frame);
1332
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1333
0
  }
1334
1335
0
  pw = secrets_fetch_machine_password(domain,
1336
0
              &last_set_time,
1337
0
              &channel);
1338
0
  if (pw == NULL) {
1339
0
    DBG_ERR("secrets_fetch_machine_password(%s) failed\n",
1340
0
      domain);
1341
0
    dbwrap_transaction_cancel(db);
1342
0
    TALLOC_FREE(frame);
1343
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1344
0
  }
1345
0
  unix_to_nt_time(&last_set_nt, last_set_time);
1346
1347
0
  old_pw = secrets_fetch_prev_machine_password(domain);
1348
1349
0
  ok = secrets_fetch_domain_sid(domain, &domain_sid);
1350
0
  if (!ok) {
1351
0
    DBG_ERR("secrets_fetch_domain_sid(%s) failed\n",
1352
0
      domain);
1353
0
    dbwrap_transaction_cancel(db);
1354
0
    BURN_FREE_STR(old_pw);
1355
0
    BURN_FREE_STR(pw);
1356
0
    TALLOC_FREE(frame);
1357
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1358
0
  }
1359
1360
0
  ok = secrets_fetch_domain_guid(domain, &domain_guid);
1361
0
  if (!ok) {
1362
0
    domain_guid = GUID_zero();
1363
0
  }
1364
1365
0
  info->computer_name = lp_netbios_name();
1366
0
  info->account_name = talloc_asprintf(frame, "%s$", info->computer_name);
1367
0
  if (info->account_name == NULL) {
1368
0
    DBG_ERR("talloc_asprintf(%s$) failed\n", info->computer_name);
1369
0
    dbwrap_transaction_cancel(db);
1370
0
    BURN_FREE_STR(old_pw);
1371
0
    BURN_FREE_STR(pw);
1372
0
    TALLOC_FREE(frame);
1373
0
    return NT_STATUS_NO_MEMORY;
1374
0
  }
1375
0
  info->secure_channel_type = channel;
1376
1377
0
  info->domain_info.name.string = domain;
1378
0
  info->domain_info.dns_domain.string = dns_domain;
1379
0
  info->domain_info.dns_forest.string = dns_domain;
1380
0
  info->domain_info.domain_guid = domain_guid;
1381
0
  info->domain_info.sid = &domain_sid;
1382
1383
0
  info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1384
0
  info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1385
1386
0
  if (dns_domain != NULL) {
1387
    /*
1388
     * We just assume all AD domains are
1389
     * NETR_TRUST_FLAG_NATIVE these days.
1390
     *
1391
     * This isn't used anyway for now.
1392
     */
1393
0
    info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1394
1395
0
    info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1396
1397
0
    server = info->domain_info.dns_domain.string;
1398
0
  } else {
1399
0
    info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1400
1401
0
    server = talloc_asprintf(info,
1402
0
           "%s#%02X",
1403
0
           domain,
1404
0
           NBT_NAME_PDC);
1405
0
    if (server == NULL) {
1406
0
      DBG_ERR("talloc_asprintf(%s#%02X) failed\n",
1407
0
        domain, NBT_NAME_PDC);
1408
0
      dbwrap_transaction_cancel(db);
1409
0
      BURN_FREE_STR(pw);
1410
0
      BURN_FREE_STR(old_pw);
1411
0
      TALLOC_FREE(frame);
1412
0
      return NT_STATUS_NO_MEMORY;
1413
0
    }
1414
0
  }
1415
0
  info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1416
1417
0
  info->join_time = 0;
1418
1419
  /*
1420
   * We don't have enough information about the configured
1421
   * enctypes.
1422
   */
1423
0
  info->supported_enc_types = 0;
1424
0
  info->salt_principal = NULL;
1425
0
  if (info->trust_type == LSA_TRUST_TYPE_UPLEVEL) {
1426
0
    char *p = NULL;
1427
1428
0
    p = kerberos_secrets_fetch_salt_princ();
1429
0
    if (p == NULL) {
1430
0
      dbwrap_transaction_cancel(db);
1431
0
      BURN_FREE_STR(old_pw);
1432
0
      BURN_FREE_STR(pw);
1433
0
      TALLOC_FREE(frame);
1434
0
      return NT_STATUS_INTERNAL_ERROR;
1435
0
    }
1436
0
    info->salt_principal = talloc_strdup(info, p);
1437
0
    SAFE_FREE(p);
1438
0
    if (info->salt_principal == NULL) {
1439
0
      dbwrap_transaction_cancel(db);
1440
0
      BURN_FREE_STR(pw);
1441
0
      BURN_FREE_STR(old_pw);
1442
0
      TALLOC_FREE(frame);
1443
0
      return NT_STATUS_NO_MEMORY;
1444
0
    }
1445
0
  }
1446
1447
0
  info->password_last_change = last_set_nt;
1448
0
  info->password_changes = 1;
1449
0
  info->next_change = NULL;
1450
1451
0
  status = secrets_domain_info_password_create(info,
1452
0
                 pw,
1453
0
                 info->salt_principal,
1454
0
                 last_set_nt, server,
1455
0
                 &info->password);
1456
0
  BURN_FREE_STR(pw);
1457
0
  if (!NT_STATUS_IS_OK(status)) {
1458
0
    DBG_ERR("secrets_domain_info_password_create(pw) failed "
1459
0
      "for %s - %s\n", domain, nt_errstr(status));
1460
0
    dbwrap_transaction_cancel(db);
1461
0
    BURN_FREE_STR(old_pw);
1462
0
    TALLOC_FREE(frame);
1463
0
    return status;
1464
0
  }
1465
1466
  /*
1467
   * After a join we don't have old passwords.
1468
   */
1469
0
  if (old_pw != NULL) {
1470
0
    status = secrets_domain_info_password_create(info,
1471
0
                   old_pw,
1472
0
                   info->salt_principal,
1473
0
                   0, server,
1474
0
                   &info->old_password);
1475
0
    BURN_FREE_STR(old_pw);
1476
0
    if (!NT_STATUS_IS_OK(status)) {
1477
0
      DBG_ERR("secrets_domain_info_password_create(old) failed "
1478
0
        "for %s - %s\n", domain, nt_errstr(status));
1479
0
      dbwrap_transaction_cancel(db);
1480
0
      TALLOC_FREE(frame);
1481
0
      return status;
1482
0
    }
1483
0
    info->password_changes += 1;
1484
0
  } else {
1485
0
    info->old_password = NULL;
1486
0
  }
1487
0
  info->older_password = NULL;
1488
1489
0
  secrets_debug_domain_info(DBGLVL_INFO, info, "upgrade");
1490
1491
0
  status = secrets_store_domain_info(info, true /* upgrade */);
1492
0
  if (!NT_STATUS_IS_OK(status)) {
1493
0
    DBG_ERR("secrets_store_domain_info() failed "
1494
0
      "for %s - %s\n", domain, nt_errstr(status));
1495
0
    dbwrap_transaction_cancel(db);
1496
0
    TALLOC_FREE(frame);
1497
0
    return status;
1498
0
  }
1499
1500
  /*
1501
   * We now reparse it.
1502
   */
1503
0
  status = secrets_fetch_domain_info(domain, frame, &info);
1504
0
  if (!NT_STATUS_IS_OK(status)) {
1505
0
    DBG_ERR("secrets_fetch_domain_info() failed "
1506
0
      "for %s - %s\n", domain, nt_errstr(status));
1507
0
    dbwrap_transaction_cancel(db);
1508
0
    TALLOC_FREE(frame);
1509
0
    return status;
1510
0
  }
1511
1512
0
  ret = dbwrap_transaction_commit(db);
1513
0
  if (ret != 0) {
1514
0
    DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1515
0
      domain);
1516
0
    TALLOC_FREE(frame);
1517
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1518
0
  }
1519
1520
0
  *pinfo = talloc_move(mem_ctx, &info);
1521
0
  TALLOC_FREE(frame);
1522
0
  return NT_STATUS_OK;
1523
0
}
1524
1525
NTSTATUS secrets_store_JoinCtx(const struct libnet_JoinCtx *r)
1526
0
{
1527
0
  TALLOC_CTX *frame = talloc_stackframe();
1528
0
  struct secrets_domain_info1 *old = NULL;
1529
0
  struct secrets_domain_info1 *info = NULL;
1530
0
  struct db_context *db = NULL;
1531
0
  struct timeval tv = timeval_current();
1532
0
  NTTIME now = timeval_to_nttime(&tv);
1533
0
  const char *domain = r->out.netbios_domain_name;
1534
0
  NTSTATUS status;
1535
0
  int ret;
1536
1537
0
  info = talloc_zero(frame, struct secrets_domain_info1);
1538
0
  if (info == NULL) {
1539
0
    DBG_ERR("talloc_zero failed\n");
1540
0
    TALLOC_FREE(frame);
1541
0
    return NT_STATUS_NO_MEMORY;
1542
0
  }
1543
1544
0
  info->computer_name = r->in.machine_name;
1545
0
  info->account_name = r->out.account_name;
1546
0
  info->secure_channel_type = r->in.secure_channel_type;
1547
1548
0
  info->domain_info.name.string =
1549
0
    r->out.netbios_domain_name;
1550
0
  info->domain_info.dns_domain.string =
1551
0
    r->out.dns_domain_name;
1552
0
  info->domain_info.dns_forest.string =
1553
0
    r->out.forest_name;
1554
0
  info->domain_info.domain_guid = r->out.domain_guid;
1555
0
  info->domain_info.sid = r->out.domain_sid;
1556
1557
0
  info->trust_flags = NETR_TRUST_FLAG_PRIMARY;
1558
0
  info->trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
1559
0
  if (r->out.domain_is_ad) {
1560
    /*
1561
     * We just assume all AD domains are
1562
     * NETR_TRUST_FLAG_NATIVE these days.
1563
     *
1564
     * This isn't used anyway for now.
1565
     */
1566
0
    info->trust_flags |= NETR_TRUST_FLAG_NATIVE;
1567
1568
0
    info->trust_type = LSA_TRUST_TYPE_UPLEVEL;
1569
0
  } else {
1570
0
    info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1571
0
  }
1572
0
  info->trust_attributes = LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL;
1573
1574
0
  info->join_time = now;
1575
1576
0
  info->supported_enc_types = r->out.set_encryption_types;
1577
0
  info->salt_principal = r->out.krb5_salt;
1578
1579
0
  if (info->salt_principal == NULL && r->out.domain_is_ad) {
1580
0
    char *p = NULL;
1581
1582
0
    ret = smb_krb5_salt_principal_str(info->domain_info.dns_domain.string,
1583
0
              info->account_name,
1584
0
              NULL /* userPrincipalName */,
1585
0
              UF_WORKSTATION_TRUST_ACCOUNT,
1586
0
              info, &p);
1587
0
    if (ret != 0) {
1588
0
      status = krb5_to_nt_status(ret);
1589
0
      DBG_ERR("smb_krb5_salt_principal() failed "
1590
0
        "for %s - %s\n", domain, nt_errstr(status));
1591
0
      TALLOC_FREE(frame);
1592
0
      return status;
1593
0
    }
1594
0
    info->salt_principal = p;
1595
0
  }
1596
1597
0
  info->password_last_change = now;
1598
0
  info->password_changes = 1;
1599
0
  info->next_change = NULL;
1600
1601
0
  status = secrets_domain_info_password_create(info,
1602
0
                 r->in.machine_password,
1603
0
                 info->salt_principal,
1604
0
                 now, r->in.dc_name,
1605
0
                 &info->password);
1606
0
  if (!NT_STATUS_IS_OK(status)) {
1607
0
    DBG_ERR("secrets_domain_info_password_create(pw) failed "
1608
0
      "for %s - %s\n", domain, nt_errstr(status));
1609
0
    TALLOC_FREE(frame);
1610
0
    return status;
1611
0
  }
1612
1613
0
  db = secrets_db_ctx();
1614
1615
0
  ret = dbwrap_transaction_start(db);
1616
0
  if (ret != 0) {
1617
0
    DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1618
0
      domain);
1619
0
    TALLOC_FREE(frame);
1620
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1621
0
  }
1622
1623
0
  status = secrets_fetch_or_upgrade_domain_info(domain, frame, &old);
1624
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
1625
0
    DBG_DEBUG("no old join for domain(%s) available\n",
1626
0
        domain);
1627
0
    old = NULL;
1628
0
  } else if (!NT_STATUS_IS_OK(status)) {
1629
0
    DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1630
0
      domain);
1631
0
    dbwrap_transaction_cancel(db);
1632
0
    TALLOC_FREE(frame);
1633
0
    return status;
1634
0
  }
1635
1636
  /*
1637
   * We reuse values from an old join, so that
1638
   * we still accept already granted kerberos tickets.
1639
   */
1640
0
  if (old != NULL) {
1641
0
    info->old_password = old->password;
1642
0
    info->older_password = old->old_password;
1643
0
  }
1644
1645
0
  secrets_debug_domain_info(DBGLVL_INFO, info, "join");
1646
1647
0
  status = secrets_store_domain_info(info, false /* upgrade */);
1648
0
  if (!NT_STATUS_IS_OK(status)) {
1649
0
    DBG_ERR("secrets_store_domain_info() failed "
1650
0
      "for %s - %s\n", domain, nt_errstr(status));
1651
0
    dbwrap_transaction_cancel(db);
1652
0
    TALLOC_FREE(frame);
1653
0
    return status;
1654
0
  }
1655
1656
0
  ret = dbwrap_transaction_commit(db);
1657
0
  if (ret != 0) {
1658
0
    DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1659
0
      domain);
1660
0
    TALLOC_FREE(frame);
1661
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1662
0
  }
1663
1664
0
  TALLOC_FREE(frame);
1665
0
  return NT_STATUS_OK;
1666
0
}
1667
1668
NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
1669
           const char *cleartext_unix,
1670
           TALLOC_CTX *mem_ctx,
1671
           struct secrets_domain_info1 **pinfo,
1672
           struct secrets_domain_info1_change **pprev,
1673
           NTSTATUS (*sync_pw2keytabs_fn)(const char *),
1674
           const char *opt_host)
1675
0
{
1676
0
  TALLOC_CTX *frame = talloc_stackframe();
1677
0
  struct db_context *db = NULL;
1678
0
  struct secrets_domain_info1 *info = NULL;
1679
0
  struct secrets_domain_info1_change *prev = NULL;
1680
0
  struct secrets_domain_info1_change *next = NULL;
1681
0
  struct timeval tv = timeval_current();
1682
0
  NTTIME now = timeval_to_nttime(&tv);
1683
0
  NTSTATUS status;
1684
0
  int ret;
1685
1686
0
  db = secrets_db_ctx();
1687
1688
0
  ret = dbwrap_transaction_start(db);
1689
0
  if (ret != 0) {
1690
0
    DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1691
0
      domain);
1692
0
    TALLOC_FREE(frame);
1693
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1694
0
  }
1695
1696
0
  status = secrets_fetch_or_upgrade_domain_info(domain, frame, &info);
1697
0
  if (!NT_STATUS_IS_OK(status)) {
1698
0
    DBG_ERR("secrets_fetch_or_upgrade_domain_info(%s) failed\n",
1699
0
      domain);
1700
0
    dbwrap_transaction_cancel(db);
1701
0
    TALLOC_FREE(frame);
1702
0
    return status;
1703
0
  }
1704
1705
0
  prev = info->next_change;
1706
0
  info->next_change = NULL;
1707
1708
0
  next = talloc_zero(frame, struct secrets_domain_info1_change);
1709
0
  if (next == NULL) {
1710
0
    DBG_ERR("talloc_zero failed\n");
1711
0
    dbwrap_transaction_cancel(db);
1712
0
    TALLOC_FREE(frame);
1713
0
    return NT_STATUS_NO_MEMORY;
1714
0
  }
1715
1716
0
  if (prev != NULL) {
1717
0
    *next = *prev;
1718
0
  } else {
1719
0
    status = secrets_domain_info_password_create(next,
1720
0
                   cleartext_unix,
1721
0
                   info->salt_principal,
1722
0
                   now, dcname,
1723
0
                   &next->password);
1724
0
    if (!NT_STATUS_IS_OK(status)) {
1725
0
      DBG_ERR("secrets_domain_info_password_create(next) failed "
1726
0
        "for %s - %s\n", domain, nt_errstr(status));
1727
0
      dbwrap_transaction_cancel(db);
1728
0
      TALLOC_FREE(frame);
1729
0
      return status;
1730
0
    }
1731
0
  }
1732
1733
0
  next->local_status = NT_STATUS_OK;
1734
0
  next->remote_status = NT_STATUS_NOT_COMMITTED;
1735
0
  next->change_time = now;
1736
0
  next->change_server = dcname;
1737
1738
0
  info->next_change = next;
1739
1740
0
  secrets_debug_domain_info(DBGLVL_INFO, info, "prepare_change");
1741
1742
0
  status = secrets_store_domain_info(info, false /* upgrade */);
1743
0
  if (!NT_STATUS_IS_OK(status)) {
1744
0
    DBG_ERR("secrets_store_domain_info() failed "
1745
0
      "for %s - %s\n", domain, nt_errstr(status));
1746
0
    dbwrap_transaction_cancel(db);
1747
0
    TALLOC_FREE(frame);
1748
0
    return status;
1749
0
  }
1750
1751
  /*
1752
   * We now reparse it.
1753
   */
1754
0
  status = secrets_fetch_domain_info(domain, frame, &info);
1755
0
  if (!NT_STATUS_IS_OK(status)) {
1756
0
    DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1757
0
    dbwrap_transaction_cancel(db);
1758
0
    TALLOC_FREE(frame);
1759
0
    return status;
1760
0
  }
1761
1762
0
  ret = dbwrap_transaction_commit(db);
1763
0
  if (ret != 0) {
1764
0
    DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1765
0
      domain);
1766
0
    TALLOC_FREE(frame);
1767
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1768
0
  }
1769
1770
0
  if (prev == NULL && sync_pw2keytabs_fn != NULL) {
1771
0
    status = sync_pw2keytabs_fn(opt_host);
1772
0
    if (!NT_STATUS_IS_OK(status)) {
1773
0
      DBG_ERR("Sync of machine password failed.\n");
1774
0
      TALLOC_FREE(frame);
1775
0
      return status;
1776
0
    }
1777
0
  }
1778
1779
0
  *pinfo = talloc_move(mem_ctx, &info);
1780
0
  if (prev != NULL) {
1781
0
    *pprev = talloc_move(mem_ctx, &prev);
1782
0
  } else {
1783
0
    *pprev = NULL;
1784
0
  }
1785
1786
0
  TALLOC_FREE(frame);
1787
0
  return NT_STATUS_OK;
1788
0
}
1789
1790
static NTSTATUS secrets_check_password_change(const struct secrets_domain_info1 *cookie,
1791
                TALLOC_CTX *mem_ctx,
1792
                struct secrets_domain_info1 **pstored)
1793
0
{
1794
0
  const char *domain = cookie->domain_info.name.string;
1795
0
  struct secrets_domain_info1 *stored = NULL;
1796
0
  struct secrets_domain_info1_change *sn = NULL;
1797
0
  struct secrets_domain_info1_change *cn = NULL;
1798
0
  NTSTATUS status;
1799
0
  bool cmp;
1800
1801
0
  if (cookie->next_change == NULL) {
1802
0
    DBG_ERR("cookie->next_change == NULL for %s.\n", domain);
1803
0
    return NT_STATUS_INTERNAL_ERROR;
1804
0
  }
1805
1806
0
  if (cookie->next_change->password == NULL) {
1807
0
    DBG_ERR("cookie->next_change->password == NULL for %s.\n", domain);
1808
0
    return NT_STATUS_INTERNAL_ERROR;
1809
0
  }
1810
1811
0
  if (cookie->password == NULL) {
1812
0
    DBG_ERR("cookie->password == NULL for %s.\n", domain);
1813
0
    return NT_STATUS_INTERNAL_ERROR;
1814
0
  }
1815
1816
  /*
1817
   * Here we check that the given structure still contains the
1818
   * same secrets_domain_info1_change as currently stored.
1819
   *
1820
   * There's always a gap between secrets_prepare_password_change()
1821
   * and the callers of secrets_check_password_change().
1822
   */
1823
1824
0
  status = secrets_fetch_domain_info(domain, mem_ctx, &stored);
1825
0
  if (!NT_STATUS_IS_OK(status)) {
1826
0
    DBG_ERR("secrets_fetch_domain_info(%s) failed\n", domain);
1827
0
    return status;
1828
0
  }
1829
1830
0
  if (stored->next_change == NULL) {
1831
    /*
1832
     * We hit a race..., the administrator
1833
     * rejoined or something similar happened.
1834
     */
1835
0
    DBG_ERR("stored->next_change == NULL for %s.\n", domain);
1836
0
    TALLOC_FREE(stored);
1837
0
    return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1838
0
  }
1839
1840
0
  if (stored->password_last_change != cookie->password_last_change) {
1841
0
    struct timeval store_tv;
1842
0
    struct timeval_buf store_buf;
1843
0
    struct timeval cookie_tv;
1844
0
    struct timeval_buf cookie_buf;
1845
1846
0
    nttime_to_timeval(&store_tv, stored->password_last_change);
1847
0
    nttime_to_timeval(&cookie_tv, cookie->password_last_change);
1848
1849
0
    DBG_ERR("password_last_change differs %s != %s for %s.\n",
1850
0
      timeval_str_buf(&store_tv, false, false, &store_buf),
1851
0
      timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1852
0
      domain);
1853
0
    TALLOC_FREE(stored);
1854
0
    return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1855
0
  }
1856
1857
0
  sn = stored->next_change;
1858
0
  cn = cookie->next_change;
1859
1860
0
  if (sn->change_time != cn->change_time) {
1861
0
    struct timeval store_tv;
1862
0
    struct timeval_buf store_buf;
1863
0
    struct timeval cookie_tv;
1864
0
    struct timeval_buf cookie_buf;
1865
1866
0
    nttime_to_timeval(&store_tv, sn->change_time);
1867
0
    nttime_to_timeval(&cookie_tv, cn->change_time);
1868
1869
0
    DBG_ERR("next change_time differs %s != %s for %s.\n",
1870
0
      timeval_str_buf(&store_tv, false, false, &store_buf),
1871
0
      timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1872
0
      domain);
1873
0
    TALLOC_FREE(stored);
1874
0
    return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1875
0
  }
1876
1877
0
  if (sn->password->change_time != cn->password->change_time) {
1878
0
    struct timeval store_tv;
1879
0
    struct timeval_buf store_buf;
1880
0
    struct timeval cookie_tv;
1881
0
    struct timeval_buf cookie_buf;
1882
1883
0
    nttime_to_timeval(&store_tv, sn->password->change_time);
1884
0
    nttime_to_timeval(&cookie_tv, cn->password->change_time);
1885
1886
0
    DBG_ERR("next password.change_time differs %s != %s for %s.\n",
1887
0
      timeval_str_buf(&store_tv, false, false, &store_buf),
1888
0
      timeval_str_buf(&cookie_tv, false, false, &cookie_buf),
1889
0
      domain);
1890
0
    TALLOC_FREE(stored);
1891
0
    return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1892
0
  }
1893
1894
0
  cmp = mem_equal_const_time(sn->password->nt_hash.hash,
1895
0
           cn->password->nt_hash.hash,
1896
0
           16);
1897
0
  if (!cmp) {
1898
0
    DBG_ERR("next password.nt_hash differs for %s.\n",
1899
0
      domain);
1900
0
    TALLOC_FREE(stored);
1901
0
    return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1902
0
  }
1903
1904
0
  cmp = mem_equal_const_time(stored->password->nt_hash.hash,
1905
0
           cookie->password->nt_hash.hash,
1906
0
           16);
1907
0
  if (!cmp) {
1908
0
    DBG_ERR("password.nt_hash differs for %s.\n",
1909
0
      domain);
1910
0
    TALLOC_FREE(stored);
1911
0
    return NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
1912
0
  }
1913
1914
0
  *pstored = stored;
1915
0
  return NT_STATUS_OK;
1916
0
}
1917
1918
static NTSTATUS secrets_abort_password_change(const char *change_server,
1919
        NTSTATUS local_status,
1920
        NTSTATUS remote_status,
1921
        const struct secrets_domain_info1 *cookie,
1922
        bool defer)
1923
0
{
1924
0
  const char *domain = cookie->domain_info.name.string;
1925
0
  TALLOC_CTX *frame = talloc_stackframe();
1926
0
  struct db_context *db = NULL;
1927
0
  struct secrets_domain_info1 *info = NULL;
1928
0
  const char *reason = defer ? "defer_change" : "failed_change";
1929
0
  struct timeval tv = timeval_current();
1930
0
  NTTIME now = timeval_to_nttime(&tv);
1931
0
  NTSTATUS status;
1932
0
  int ret;
1933
1934
0
  db = secrets_db_ctx();
1935
1936
0
  ret = dbwrap_transaction_start(db);
1937
0
  if (ret != 0) {
1938
0
    DBG_ERR("dbwrap_transaction_start() failed for %s\n",
1939
0
      domain);
1940
0
    TALLOC_FREE(frame);
1941
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1942
0
  }
1943
1944
  /*
1945
   * secrets_check_password_change()
1946
   * checks that cookie->next_change
1947
   * is valid and the same as store
1948
   * in the database.
1949
   */
1950
0
  status = secrets_check_password_change(cookie, frame, &info);
1951
0
  if (!NT_STATUS_IS_OK(status)) {
1952
0
    DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
1953
0
    dbwrap_transaction_cancel(db);
1954
0
    TALLOC_FREE(frame);
1955
0
    return status;
1956
0
  }
1957
1958
  /*
1959
   * Remember the last server and error.
1960
   */
1961
0
  info->next_change->change_server = change_server;
1962
0
  info->next_change->change_time = now;
1963
0
  info->next_change->local_status = local_status;
1964
0
  info->next_change->remote_status = remote_status;
1965
1966
  /*
1967
   * Make sure the next automatic change is deferred.
1968
   */
1969
0
  if (defer) {
1970
0
    info->password_last_change = now;
1971
0
  }
1972
1973
0
  secrets_debug_domain_info(DBGLVL_WARNING, info, reason);
1974
1975
0
  status = secrets_store_domain_info(info, false /* upgrade */);
1976
0
  if (!NT_STATUS_IS_OK(status)) {
1977
0
    DBG_ERR("secrets_store_domain_info() failed "
1978
0
      "for %s - %s\n", domain, nt_errstr(status));
1979
0
    dbwrap_transaction_cancel(db);
1980
0
    TALLOC_FREE(frame);
1981
0
    return status;
1982
0
  }
1983
1984
0
  ret = dbwrap_transaction_commit(db);
1985
0
  if (ret != 0) {
1986
0
    DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
1987
0
      domain);
1988
0
    TALLOC_FREE(frame);
1989
0
    return NT_STATUS_INTERNAL_DB_ERROR;
1990
0
  }
1991
1992
0
  TALLOC_FREE(frame);
1993
0
  return NT_STATUS_OK;
1994
0
}
1995
1996
NTSTATUS secrets_failed_password_change(const char *change_server,
1997
          NTSTATUS local_status,
1998
          NTSTATUS remote_status,
1999
          const struct secrets_domain_info1 *cookie)
2000
0
{
2001
0
  static const bool defer = false;
2002
0
  return secrets_abort_password_change(change_server,
2003
0
               local_status,
2004
0
               remote_status,
2005
0
               cookie, defer);
2006
0
}
2007
2008
NTSTATUS secrets_defer_password_change(const char *change_server,
2009
               NTSTATUS local_status,
2010
               NTSTATUS remote_status,
2011
               const struct secrets_domain_info1 *cookie)
2012
0
{
2013
0
  static const bool defer = true;
2014
0
  return secrets_abort_password_change(change_server,
2015
0
               local_status,
2016
0
               remote_status,
2017
0
               cookie, defer);
2018
0
}
2019
2020
NTSTATUS secrets_finish_password_change(const char *change_server,
2021
          NTTIME change_time,
2022
          const struct secrets_domain_info1 *cookie,
2023
          NTSTATUS (*sync_pw2keytabs_fn)(const char *),
2024
          const char *prefer_dc)
2025
0
{
2026
0
  const char *domain = cookie->domain_info.name.string;
2027
0
  TALLOC_CTX *frame = talloc_stackframe();
2028
0
  struct db_context *db = NULL;
2029
0
  struct secrets_domain_info1 *info = NULL;
2030
0
  struct secrets_domain_info1_change *nc = NULL;
2031
0
  NTSTATUS status;
2032
0
  int ret;
2033
2034
0
  db = secrets_db_ctx();
2035
2036
0
  ret = dbwrap_transaction_start(db);
2037
0
  if (ret != 0) {
2038
0
    DBG_ERR("dbwrap_transaction_start() failed for %s\n",
2039
0
      domain);
2040
0
    TALLOC_FREE(frame);
2041
0
    return NT_STATUS_INTERNAL_DB_ERROR;
2042
0
  }
2043
2044
  /*
2045
   * secrets_check_password_change() checks that cookie->next_change is
2046
   * valid and the same as store in the database.
2047
   */
2048
0
  status = secrets_check_password_change(cookie, frame, &info);
2049
0
  if (!NT_STATUS_IS_OK(status)) {
2050
0
    DBG_ERR("secrets_check_password_change(%s) failed\n", domain);
2051
0
    dbwrap_transaction_cancel(db);
2052
0
    TALLOC_FREE(frame);
2053
0
    return status;
2054
0
  }
2055
2056
0
  nc = info->next_change;
2057
2058
0
  nc->password->change_server = change_server;
2059
0
  nc->password->change_time = change_time;
2060
2061
0
  info->password_last_change = change_time;
2062
0
  info->password_changes += 1;
2063
0
  info->next_change = NULL;
2064
2065
0
  info->older_password = info->old_password;
2066
0
  info->old_password = info->password;
2067
0
  info->password = nc->password;
2068
2069
0
  secrets_debug_domain_info(DBGLVL_WARNING, info, "finish_change");
2070
2071
0
  status = secrets_store_domain_info(info, false /* upgrade */);
2072
0
  if (!NT_STATUS_IS_OK(status)) {
2073
0
    DBG_ERR("secrets_store_domain_info() failed "
2074
0
      "for %s - %s\n", domain, nt_errstr(status));
2075
0
    dbwrap_transaction_cancel(db);
2076
0
    TALLOC_FREE(frame);
2077
0
    return status;
2078
0
  }
2079
2080
  /*
2081
   * For the clustered samba, it is important to have following order:
2082
   * 1. dbwrap_transaction_commit()
2083
   * 2. sync_pw2keytabs()
2084
   * Only this order ensures a correct behavior of
2085
   * the 'sync machine password script' that does:
2086
   * 'onnode all net ads keytab create'
2087
   *
2088
   * If we would call sync_pw2keytabs() before committing the changes to
2089
   * the secrets.tdb, it will not be updated on other nodes, so triggering
2090
   * 'net ads keytab create' will not see the new password yet.
2091
   *
2092
   * This applies also to secrets_prepare_password_change().
2093
   */
2094
0
  ret = dbwrap_transaction_commit(db);
2095
0
  if (ret != 0) {
2096
0
    DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
2097
0
      domain);
2098
0
    TALLOC_FREE(frame);
2099
0
    return NT_STATUS_INTERNAL_DB_ERROR;
2100
0
  }
2101
2102
0
  if (sync_pw2keytabs_fn != NULL) {
2103
0
    status = sync_pw2keytabs_fn(prefer_dc);
2104
0
    if (!NT_STATUS_IS_OK(status)) {
2105
0
      DBG_ERR("Sync of machine password failed.\n");
2106
0
      TALLOC_FREE(frame);
2107
0
      return status;
2108
0
    }
2109
0
  }
2110
2111
0
  TALLOC_FREE(frame);
2112
0
  return NT_STATUS_OK;
2113
0
}