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