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