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