1ddafb3410147d06200e3d43cf4519de2006f73f
[vlendec/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / password_hash.c
1 /* 
2    ldb database module
3
4    Copyright (C) Simo Sorce  2004-2008
5    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
6    Copyright (C) Andrew Tridgell 2004
7    Copyright (C) Stefan Metzmacher 2007-2010
8    Copyright (C) Matthias Dieter Wallnöfer 2009-2010
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 /*
25  *  Name: ldb
26  *
27  *  Component: ldb password_hash module
28  *
29  *  Description: correctly handle AD password changes fields
30  *
31  *  Author: Andrew Bartlett
32  *  Author: Stefan Metzmacher
33  */
34
35 #include "includes.h"
36 #include "ldb_module.h"
37 #include "libcli/auth/libcli_auth.h"
38 #include "libcli/security/dom_sid.h"
39 #include "system/kerberos.h"
40 #include "auth/kerberos/kerberos.h"
41 #include "dsdb/samdb/samdb.h"
42 #include "dsdb/samdb/ldb_modules/util.h"
43 #include "dsdb/samdb/ldb_modules/password_modules.h"
44 #include "librpc/gen_ndr/ndr_drsblobs.h"
45 #include "../lib/crypto/crypto.h"
46 #include "param/param.h"
47 #include "lib/krb5_wrap/krb5_samba.h"
48 #include "auth/common_auth.h"
49 #include "lib/messaging/messaging.h"
50
51 #ifdef ENABLE_GPGME
52 #undef class
53 #include <gpgme.h>
54 #endif
55
56 /* If we have decided there is a reason to work on this request, then
57  * setup all the password hash types correctly.
58  *
59  * If we haven't the hashes yet but the password given as plain-text (attributes
60  * 'unicodePwd', 'userPassword' and 'clearTextPassword') we have to check for
61  * the constraints. Once this is done, we calculate the password hashes.
62  *
63  * Notice: unlike the real AD which only supports the UTF16 special based
64  * 'unicodePwd' and the UTF8 based 'userPassword' plaintext attribute we
65  * understand also a UTF16 based 'clearTextPassword' one.
66  * The latter is also accessible through LDAP so it can also be set by external
67  * tools and scripts. But be aware that this isn't portable on non SAMBA 4 ADs!
68  *
69  * Also when the module receives only the password hashes (possible through
70  * specifying an internal LDB control - for security reasons) some checks are
71  * performed depending on the operation mode (see below) (e.g. if the password
72  * has been in use before if the password memory policy was activated).
73  *
74  * Attention: There is a difference between "modify" and "reset" operations
75  * (see MS-ADTS 3.1.1.3.1.5). If the client sends a "add" and "remove"
76  * operation for a password attribute we thread this as a "modify"; if it sends
77  * only a "replace" one we have an (administrative) reset.
78  *
79  * Finally, if the administrator has requested that a password history
80  * be maintained, then this should also be written out.
81  *
82  */
83
84 /* TODO: [consider always MS-ADTS 3.1.1.3.1.5]
85  * - Check for right connection encryption
86  */
87
88 /* Notice: Definition of "dsdb_control_password_change_status" moved into
89  * "samdb.h" */
90
91 struct ph_context {
92         struct ldb_module *module;
93         struct ldb_request *req;
94
95         struct ldb_request *dom_req;
96         struct ldb_reply *dom_res;
97
98         struct ldb_reply *search_res;
99
100         struct ldb_message *update_msg;
101
102         struct dsdb_control_password_change_status *status;
103         struct dsdb_control_password_change *change;
104
105         const char **gpg_key_ids;
106
107         bool pwd_reset;
108         bool change_status;
109         bool hash_values;
110         bool userPassword;
111         bool update_password;
112         bool update_lastset;
113         bool pwd_last_set_bypass;
114         bool pwd_last_set_default;
115         bool smartcard_reset;
116         const char **userPassword_schemes;
117 };
118
119
120 struct setup_password_fields_io {
121         struct ph_context *ac;
122
123         struct smb_krb5_context *smb_krb5_context;
124
125         /* info about the user account */
126         struct {
127                 uint32_t userAccountControl;
128                 NTTIME pwdLastSet;
129                 const char *sAMAccountName;
130                 const char *user_principal_name;
131                 bool is_computer;
132                 bool is_krbtgt;
133                 uint32_t restrictions;
134                 struct dom_sid *account_sid;
135         } u;
136
137         /* new credentials and old given credentials */
138         struct setup_password_fields_given {
139                 const struct ldb_val *cleartext_utf8;
140                 const struct ldb_val *cleartext_utf16;
141                 struct samr_Password *nt_hash;
142                 struct samr_Password *lm_hash;
143         } n, og;
144
145         /* old credentials */
146         struct {
147                 struct samr_Password *nt_hash;
148                 struct samr_Password *lm_hash;
149                 uint32_t nt_history_len;
150                 struct samr_Password *nt_history;
151                 uint32_t lm_history_len;
152                 struct samr_Password *lm_history;
153                 const struct ldb_val *supplemental;
154                 struct supplementalCredentialsBlob scb;
155         } o;
156
157         /* generated credentials */
158         struct {
159                 struct samr_Password *nt_hash;
160                 struct samr_Password *lm_hash;
161                 uint32_t nt_history_len;
162                 struct samr_Password *nt_history;
163                 uint32_t lm_history_len;
164                 struct samr_Password *lm_history;
165                 const char *salt;
166                 DATA_BLOB aes_256;
167                 DATA_BLOB aes_128;
168                 DATA_BLOB des_md5;
169                 DATA_BLOB des_crc;
170                 struct ldb_val supplemental;
171                 NTTIME last_set;
172         } g;
173 };
174
175 static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
176                                         const char *name,
177                                         enum ldb_request_type operation,
178                                         const struct ldb_val **new_val,
179                                         const struct ldb_val **old_val);
180
181 static int password_hash_bypass(struct ldb_module *module, struct ldb_request *request)
182 {
183         struct ldb_context *ldb = ldb_module_get_ctx(module);
184         const struct ldb_message *msg;
185         struct ldb_message_element *nte;
186         struct ldb_message_element *lme;
187         struct ldb_message_element *nthe;
188         struct ldb_message_element *lmhe;
189         struct ldb_message_element *sce;
190
191         switch (request->operation) {
192         case LDB_ADD:
193                 msg = request->op.add.message;
194                 break;
195         case LDB_MODIFY:
196                 msg = request->op.mod.message;
197                 break;
198         default:
199                 return ldb_next_request(module, request);
200         }
201
202         /* nobody must touch password histories and 'supplementalCredentials' */
203         nte = dsdb_get_single_valued_attr(msg, "unicodePwd",
204                                           request->operation);
205         lme = dsdb_get_single_valued_attr(msg, "dBCSPwd",
206                                           request->operation);
207         nthe = dsdb_get_single_valued_attr(msg, "ntPwdHistory",
208                                            request->operation);
209         lmhe = dsdb_get_single_valued_attr(msg, "lmPwdHistory",
210                                            request->operation);
211         sce = dsdb_get_single_valued_attr(msg, "supplementalCredentials",
212                                           request->operation);
213
214 #define CHECK_HASH_ELEMENT(e, min, max) do {\
215         if (e && e->num_values) { \
216                 unsigned int _count; \
217                 if (e->num_values != 1) { \
218                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
219                                          "num_values != 1"); \
220                 } \
221                 if ((e->values[0].length % 16) != 0) { \
222                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
223                                          "length % 16 != 0"); \
224                 } \
225                 _count = e->values[0].length / 16; \
226                 if (_count < min) { \
227                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
228                                          "count < min"); \
229                 } \
230                 if (_count > max) { \
231                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
232                                          "count > max"); \
233                 } \
234         } \
235 } while (0)
236
237         CHECK_HASH_ELEMENT(nte, 1, 1);
238         CHECK_HASH_ELEMENT(lme, 1, 1);
239         CHECK_HASH_ELEMENT(nthe, 1, INT32_MAX);
240         CHECK_HASH_ELEMENT(lmhe, 1, INT32_MAX);
241
242         if (sce && sce->num_values) {
243                 enum ndr_err_code ndr_err;
244                 struct supplementalCredentialsBlob *scb;
245                 struct supplementalCredentialsPackage *scpp = NULL;
246                 struct supplementalCredentialsPackage *scpk = NULL;
247                 struct supplementalCredentialsPackage *scpkn = NULL;
248                 struct supplementalCredentialsPackage *scpct = NULL;
249                 DATA_BLOB scpbp = data_blob_null;
250                 DATA_BLOB scpbk = data_blob_null;
251                 DATA_BLOB scpbkn = data_blob_null;
252                 DATA_BLOB scpbct = data_blob_null;
253                 DATA_BLOB blob;
254                 uint32_t i;
255
256                 if (sce->num_values != 1) {
257                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
258                                          "num_values != 1");
259                 }
260
261                 scb = talloc_zero(request, struct supplementalCredentialsBlob);
262                 if (!scb) {
263                         return ldb_module_oom(module);
264                 }
265
266                 ndr_err = ndr_pull_struct_blob_all(&sce->values[0], scb, scb,
267                                 (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
268                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
269                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
270                                          "ndr_pull_struct_blob_all");
271                 }
272
273                 if (scb->sub.num_packages < 2) {
274                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
275                                          "num_packages < 2");
276                 }
277
278                 for (i=0; i < scb->sub.num_packages; i++) {
279                         DATA_BLOB subblob;
280
281                         subblob = strhex_to_data_blob(scb, scb->sub.packages[i].data);
282                         if (subblob.data == NULL) {
283                                 return ldb_module_oom(module);
284                         }
285
286                         if (strcmp(scb->sub.packages[i].name, "Packages") == 0) {
287                                 if (scpp) {
288                                         return ldb_error(ldb,
289                                                          LDB_ERR_CONSTRAINT_VIOLATION,
290                                                          "Packages twice");
291                                 }
292                                 scpp = &scb->sub.packages[i];
293                                 scpbp = subblob;
294                                 continue;
295                         }
296                         if (strcmp(scb->sub.packages[i].name, "Primary:Kerberos") == 0) {
297                                 if (scpk) {
298                                         return ldb_error(ldb,
299                                                          LDB_ERR_CONSTRAINT_VIOLATION,
300                                                          "Primary:Kerberos twice");
301                                 }
302                                 scpk = &scb->sub.packages[i];
303                                 scpbk = subblob;
304                                 continue;
305                         }
306                         if (strcmp(scb->sub.packages[i].name, "Primary:Kerberos-Newer-Keys") == 0) {
307                                 if (scpkn) {
308                                         return ldb_error(ldb,
309                                                          LDB_ERR_CONSTRAINT_VIOLATION,
310                                                          "Primary:Kerberos-Newer-Keys twice");
311                                 }
312                                 scpkn = &scb->sub.packages[i];
313                                 scpbkn = subblob;
314                                 continue;
315                         }
316                         if (strcmp(scb->sub.packages[i].name, "Primary:CLEARTEXT") == 0) {
317                                 if (scpct) {
318                                         return ldb_error(ldb,
319                                                          LDB_ERR_CONSTRAINT_VIOLATION,
320                                                          "Primary:CLEARTEXT twice");
321                                 }
322                                 scpct = &scb->sub.packages[i];
323                                 scpbct = subblob;
324                                 continue;
325                         }
326
327                         data_blob_free(&subblob);
328                 }
329
330                 if (scpp == NULL) {
331                         return ldb_error(ldb,
332                                          LDB_ERR_CONSTRAINT_VIOLATION,
333                                          "Primary:Packages missing");
334                 }
335
336                 if (scpk == NULL) {
337                         /*
338                          * If Primary:Kerberos is missing w2k8r2 reboots
339                          * when a password is changed.
340                          */
341                         return ldb_error(ldb,
342                                          LDB_ERR_CONSTRAINT_VIOLATION,
343                                          "Primary:Kerberos missing");
344                 }
345
346                 if (scpp) {
347                         struct package_PackagesBlob *p;
348                         uint32_t n;
349
350                         p = talloc_zero(scb, struct package_PackagesBlob);
351                         if (p == NULL) {
352                                 return ldb_module_oom(module);
353                         }
354
355                         ndr_err = ndr_pull_struct_blob(&scpbp, p, p,
356                                         (ndr_pull_flags_fn_t)ndr_pull_package_PackagesBlob);
357                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
358                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
359                                                  "ndr_pull_struct_blob Packages");
360                         }
361
362                         if (p->names == NULL) {
363                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
364                                                  "Packages names == NULL");
365                         }
366
367                         for (n = 0; p->names[n]; n++) {
368                                 /* noop */
369                         }
370
371                         if (scb->sub.num_packages != (n + 1)) {
372                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
373                                                  "Packages num_packages != num_names + 1");
374                         }
375
376                         talloc_free(p);
377                 }
378
379                 if (scpk) {
380                         struct package_PrimaryKerberosBlob *k;
381
382                         k = talloc_zero(scb, struct package_PrimaryKerberosBlob);
383                         if (k == NULL) {
384                                 return ldb_module_oom(module);
385                         }
386
387                         ndr_err = ndr_pull_struct_blob(&scpbk, k, k,
388                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
389                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
390                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
391                                                  "ndr_pull_struct_blob PrimaryKerberos");
392                         }
393
394                         if (k->version != 3) {
395                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
396                                                  "PrimaryKerberos version != 3");
397                         }
398
399                         if (k->ctr.ctr3.salt.string == NULL) {
400                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
401                                                  "PrimaryKerberos salt == NULL");
402                         }
403
404                         if (strlen(k->ctr.ctr3.salt.string) == 0) {
405                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
406                                                  "PrimaryKerberos strlen(salt) == 0");
407                         }
408
409                         if (k->ctr.ctr3.num_keys != 2) {
410                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
411                                                  "PrimaryKerberos num_keys != 2");
412                         }
413
414                         if (k->ctr.ctr3.num_old_keys > k->ctr.ctr3.num_keys) {
415                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
416                                                  "PrimaryKerberos num_old_keys > num_keys");
417                         }
418
419                         if (k->ctr.ctr3.keys[0].keytype != ENCTYPE_DES_CBC_MD5) {
420                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
421                                                  "PrimaryKerberos key[0] != DES_CBC_MD5");
422                         }
423                         if (k->ctr.ctr3.keys[1].keytype != ENCTYPE_DES_CBC_CRC) {
424                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
425                                                  "PrimaryKerberos key[1] != DES_CBC_CRC");
426                         }
427
428                         if (k->ctr.ctr3.keys[0].value_len != 8) {
429                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
430                                                  "PrimaryKerberos key[0] value_len != 8");
431                         }
432                         if (k->ctr.ctr3.keys[1].value_len != 8) {
433                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
434                                                  "PrimaryKerberos key[1] value_len != 8");
435                         }
436
437                         for (i = 0; i < k->ctr.ctr3.num_old_keys; i++) {
438                                 if (k->ctr.ctr3.old_keys[i].keytype ==
439                                     k->ctr.ctr3.keys[i].keytype &&
440                                     k->ctr.ctr3.old_keys[i].value_len ==
441                                     k->ctr.ctr3.keys[i].value_len) {
442                                         continue;
443                                 }
444
445                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
446                                                  "PrimaryKerberos old_keys type/value_len doesn't match");
447                         }
448
449                         talloc_free(k);
450                 }
451
452                 if (scpkn) {
453                         struct package_PrimaryKerberosBlob *k;
454
455                         k = talloc_zero(scb, struct package_PrimaryKerberosBlob);
456                         if (k == NULL) {
457                                 return ldb_module_oom(module);
458                         }
459
460                         ndr_err = ndr_pull_struct_blob(&scpbkn, k, k,
461                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
462                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
463                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
464                                                  "ndr_pull_struct_blob PrimaryKerberosNeverKeys");
465                         }
466
467                         if (k->version != 4) {
468                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
469                                                  "KerberosNerverKeys version != 4");
470                         }
471
472                         if (k->ctr.ctr4.salt.string == NULL) {
473                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
474                                                  "KerberosNewerKeys salt == NULL");
475                         }
476
477                         if (strlen(k->ctr.ctr4.salt.string) == 0) {
478                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
479                                                  "KerberosNewerKeys strlen(salt) == 0");
480                         }
481
482                         if (k->ctr.ctr4.num_keys != 4) {
483                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
484                                                  "KerberosNewerKeys num_keys != 2");
485                         }
486
487                         if (k->ctr.ctr4.num_old_keys > k->ctr.ctr4.num_keys) {
488                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
489                                                  "KerberosNewerKeys num_old_keys > num_keys");
490                         }
491
492                         if (k->ctr.ctr4.num_older_keys > k->ctr.ctr4.num_old_keys) {
493                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
494                                                  "KerberosNewerKeys num_older_keys > num_old_keys");
495                         }
496
497                         if (k->ctr.ctr4.keys[0].keytype != ENCTYPE_AES256_CTS_HMAC_SHA1_96) {
498                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
499                                                  "KerberosNewerKeys key[0] != AES256");
500                         }
501                         if (k->ctr.ctr4.keys[1].keytype != ENCTYPE_AES128_CTS_HMAC_SHA1_96) {
502                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
503                                                  "KerberosNewerKeys key[1] != AES128");
504                         }
505                         if (k->ctr.ctr4.keys[2].keytype != ENCTYPE_DES_CBC_MD5) {
506                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
507                                                  "KerberosNewerKeys key[2] != DES_CBC_MD5");
508                         }
509                         if (k->ctr.ctr4.keys[3].keytype != ENCTYPE_DES_CBC_CRC) {
510                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
511                                                  "KerberosNewerKeys key[3] != DES_CBC_CRC");
512                         }
513
514                         if (k->ctr.ctr4.keys[0].value_len != 32) {
515                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
516                                                  "KerberosNewerKeys key[0] value_len != 32");
517                         }
518                         if (k->ctr.ctr4.keys[1].value_len != 16) {
519                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
520                                                  "KerberosNewerKeys key[1] value_len != 16");
521                         }
522                         if (k->ctr.ctr4.keys[2].value_len != 8) {
523                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
524                                                  "KerberosNewerKeys key[2] value_len != 8");
525                         }
526                         if (k->ctr.ctr4.keys[3].value_len != 8) {
527                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
528                                                  "KerberosNewerKeys key[3] value_len != 8");
529                         }
530
531                         /*
532                          * TODO:
533                          * Maybe we can check old and older keys here.
534                          * But we need to do some tests, if the old keys
535                          * can be taken from the PrimaryKerberos blob
536                          * (with only des keys), when the domain was upgraded
537                          * from w2k3 to w2k8.
538                          */
539
540                         talloc_free(k);
541                 }
542
543                 if (scpct) {
544                         struct package_PrimaryCLEARTEXTBlob *ct;
545
546                         ct = talloc_zero(scb, struct package_PrimaryCLEARTEXTBlob);
547                         if (ct == NULL) {
548                                 return ldb_module_oom(module);
549                         }
550
551                         ndr_err = ndr_pull_struct_blob(&scpbct, ct, ct,
552                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryCLEARTEXTBlob);
553                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
554                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
555                                                  "ndr_pull_struct_blob PrimaryCLEARTEXT");
556                         }
557
558                         if ((ct->cleartext.length % 2) != 0) {
559                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
560                                                  "PrimaryCLEARTEXT length % 2 != 0");
561                         }
562
563                         talloc_free(ct);
564                 }
565
566                 ndr_err = ndr_push_struct_blob(&blob, scb, scb,
567                                 (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
568                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
569                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
570                                          "ndr_pull_struct_blob_all");
571                 }
572
573                 if (sce->values[0].length != blob.length) {
574                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
575                                          "supplementalCredentialsBlob length differ");
576                 }
577
578                 if (memcmp(sce->values[0].data, blob.data, blob.length) != 0) {
579                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
580                                          "supplementalCredentialsBlob memcmp differ");
581                 }
582
583                 talloc_free(scb);
584         }
585
586         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_bypass - validated\n");
587         return ldb_next_request(module, request);
588 }
589
590 /* Get the NT hash, and fill it in as an entry in the password history, 
591    and specify it into io->g.nt_hash */
592
593 static int setup_nt_fields(struct setup_password_fields_io *io)
594 {
595         struct ldb_context *ldb;
596         uint32_t i;
597
598         io->g.nt_hash = io->n.nt_hash;
599         ldb = ldb_module_get_ctx(io->ac->module);
600
601         if (io->ac->status->domain_data.pwdHistoryLength == 0) {
602                 return LDB_SUCCESS;
603         }
604
605         /* We might not have an old NT password */
606         io->g.nt_history = talloc_array(io->ac,
607                                         struct samr_Password,
608                                         io->ac->status->domain_data.pwdHistoryLength);
609         if (!io->g.nt_history) {
610                 return ldb_oom(ldb);
611         }
612
613         for (i = 0; i < MIN(io->ac->status->domain_data.pwdHistoryLength-1,
614                             io->o.nt_history_len); i++) {
615                 io->g.nt_history[i+1] = io->o.nt_history[i];
616         }
617         io->g.nt_history_len = i + 1;
618
619         if (io->g.nt_hash) {
620                 io->g.nt_history[0] = *io->g.nt_hash;
621         } else {
622                 /* 
623                  * TODO: is this correct?
624                  * the simular behavior is correct for the lm history case
625                  */
626                 E_md4hash("", io->g.nt_history[0].hash);
627         }
628
629         return LDB_SUCCESS;
630 }
631
632 /* Get the LANMAN hash, and fill it in as an entry in the password history, 
633    and specify it into io->g.lm_hash */
634
635 static int setup_lm_fields(struct setup_password_fields_io *io)
636 {
637         struct ldb_context *ldb;
638         uint32_t i;
639
640         io->g.lm_hash = io->n.lm_hash;
641         ldb = ldb_module_get_ctx(io->ac->module);
642
643         if (io->ac->status->domain_data.pwdHistoryLength == 0) {
644                 return LDB_SUCCESS;
645         }
646
647         /* We might not have an old LM password */
648         io->g.lm_history = talloc_array(io->ac,
649                                         struct samr_Password,
650                                         io->ac->status->domain_data.pwdHistoryLength);
651         if (!io->g.lm_history) {
652                 return ldb_oom(ldb);
653         }
654
655         for (i = 0; i < MIN(io->ac->status->domain_data.pwdHistoryLength-1,
656                             io->o.lm_history_len); i++) {
657                 io->g.lm_history[i+1] = io->o.lm_history[i];
658         }
659         io->g.lm_history_len = i + 1;
660
661         if (io->g.lm_hash) {
662                 io->g.lm_history[0] = *io->g.lm_hash;
663         } else {
664                 E_deshash("", io->g.lm_history[0].hash);
665         }
666
667         return LDB_SUCCESS;
668 }
669
670 static int setup_kerberos_keys(struct setup_password_fields_io *io)
671 {
672         struct ldb_context *ldb;
673         krb5_error_code krb5_ret;
674         char *salt_principal = NULL;
675         char *salt_data = NULL;
676         krb5_data salt;
677         krb5_keyblock key;
678         krb5_data cleartext_data;
679
680         ldb = ldb_module_get_ctx(io->ac->module);
681         cleartext_data.data = (char *)io->n.cleartext_utf8->data;
682         cleartext_data.length = io->n.cleartext_utf8->length;
683
684         krb5_ret = smb_krb5_salt_principal(io->ac->status->domain_data.realm,
685                                            io->u.sAMAccountName,
686                                            io->u.user_principal_name,
687                                            io->u.is_computer,
688                                            io->ac,
689                                            &salt_principal);
690         if (krb5_ret) {
691                 ldb_asprintf_errstring(ldb,
692                                        "setup_kerberos_keys: "
693                                        "generation of a salting principal failed: %s",
694                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
695                                                                   krb5_ret, io->ac));
696                 return LDB_ERR_OPERATIONS_ERROR;
697         }
698
699         /*
700          * create salt from salt_principal
701          */
702         krb5_ret = smb_krb5_salt_principal2data(io->smb_krb5_context->krb5_context,
703                                                 salt_principal, io->ac, &salt_data);
704         if (krb5_ret) {
705                 ldb_asprintf_errstring(ldb,
706                                        "setup_kerberos_keys: "
707                                        "generation of krb5_salt failed: %s",
708                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
709                                                                   krb5_ret, io->ac));
710                 return LDB_ERR_OPERATIONS_ERROR;
711         }
712         io->g.salt = salt_data;
713
714         /* now use the talloced copy of the salt */
715         salt.data       = discard_const(io->g.salt);
716         salt.length     = strlen(io->g.salt);
717
718         /*
719          * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
720          * the salt and the cleartext password
721          */
722         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
723                                                    NULL,
724                                                    &salt,
725                                                    &cleartext_data,
726                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
727                                                    &key);
728         if (krb5_ret) {
729                 ldb_asprintf_errstring(ldb,
730                                        "setup_kerberos_keys: "
731                                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
732                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
733                                                                   krb5_ret, io->ac));
734                 return LDB_ERR_OPERATIONS_ERROR;
735         }
736         io->g.aes_256 = data_blob_talloc(io->ac,
737                                          KRB5_KEY_DATA(&key),
738                                          KRB5_KEY_LENGTH(&key));
739         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
740         if (!io->g.aes_256.data) {
741                 return ldb_oom(ldb);
742         }
743
744         /*
745          * create ENCTYPE_AES128_CTS_HMAC_SHA1_96 key out of
746          * the salt and the cleartext password
747          */
748         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
749                                                    NULL,
750                                                    &salt,
751                                                    &cleartext_data,
752                                                    ENCTYPE_AES128_CTS_HMAC_SHA1_96,
753                                                    &key);
754         if (krb5_ret) {
755                 ldb_asprintf_errstring(ldb,
756                                        "setup_kerberos_keys: "
757                                        "generation of a aes128-cts-hmac-sha1-96 key failed: %s",
758                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
759                                                                   krb5_ret, io->ac));
760                 return LDB_ERR_OPERATIONS_ERROR;
761         }
762         io->g.aes_128 = data_blob_talloc(io->ac,
763                                          KRB5_KEY_DATA(&key),
764                                          KRB5_KEY_LENGTH(&key));
765         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
766         if (!io->g.aes_128.data) {
767                 return ldb_oom(ldb);
768         }
769
770         /*
771          * create ENCTYPE_DES_CBC_MD5 key out of
772          * the salt and the cleartext password
773          */
774         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
775                                                    NULL,
776                                                    &salt,
777                                                    &cleartext_data,
778                                                    ENCTYPE_DES_CBC_MD5,
779                                                    &key);
780         if (krb5_ret) {
781                 ldb_asprintf_errstring(ldb,
782                                        "setup_kerberos_keys: "
783                                        "generation of a des-cbc-md5 key failed: %s",
784                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
785                                                                   krb5_ret, io->ac));
786                 return LDB_ERR_OPERATIONS_ERROR;
787         }
788         io->g.des_md5 = data_blob_talloc(io->ac,
789                                          KRB5_KEY_DATA(&key),
790                                          KRB5_KEY_LENGTH(&key));
791         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
792         if (!io->g.des_md5.data) {
793                 return ldb_oom(ldb);
794         }
795
796         /*
797          * create ENCTYPE_DES_CBC_CRC key out of
798          * the salt and the cleartext password
799          */
800         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
801                                                    NULL,
802                                                    &salt,
803                                                    &cleartext_data,
804                                                    ENCTYPE_DES_CBC_CRC,
805                                                    &key);
806         if (krb5_ret) {
807                 ldb_asprintf_errstring(ldb,
808                                        "setup_kerberos_keys: "
809                                        "generation of a des-cbc-crc key failed: %s",
810                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
811                                                                   krb5_ret, io->ac));
812                 return LDB_ERR_OPERATIONS_ERROR;
813         }
814         io->g.des_crc = data_blob_talloc(io->ac,
815                                          KRB5_KEY_DATA(&key),
816                                          KRB5_KEY_LENGTH(&key));
817         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
818         if (!io->g.des_crc.data) {
819                 return ldb_oom(ldb);
820         }
821
822         return LDB_SUCCESS;
823 }
824
825 static int setup_primary_kerberos(struct setup_password_fields_io *io,
826                                   const struct supplementalCredentialsBlob *old_scb,
827                                   struct package_PrimaryKerberosBlob *pkb)
828 {
829         struct ldb_context *ldb;
830         struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
831         struct supplementalCredentialsPackage *old_scp = NULL;
832         struct package_PrimaryKerberosBlob _old_pkb;
833         struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
834         uint32_t i;
835         enum ndr_err_code ndr_err;
836
837         ldb = ldb_module_get_ctx(io->ac->module);
838
839         /*
840          * prepare generation of keys
841          *
842          * ENCTYPE_DES_CBC_MD5
843          * ENCTYPE_DES_CBC_CRC
844          */
845         pkb->version            = 3;
846         pkb3->salt.string       = io->g.salt;
847         pkb3->num_keys          = 2;
848         pkb3->keys              = talloc_array(io->ac,
849                                                struct package_PrimaryKerberosKey3,
850                                                pkb3->num_keys);
851         if (!pkb3->keys) {
852                 return ldb_oom(ldb);
853         }
854
855         pkb3->keys[0].keytype   = ENCTYPE_DES_CBC_MD5;
856         pkb3->keys[0].value     = &io->g.des_md5;
857         pkb3->keys[1].keytype   = ENCTYPE_DES_CBC_CRC;
858         pkb3->keys[1].value     = &io->g.des_crc;
859
860         /* initialize the old keys to zero */
861         pkb3->num_old_keys      = 0;
862         pkb3->old_keys          = NULL;
863
864         /* if there're no old keys, then we're done */
865         if (!old_scb) {
866                 return LDB_SUCCESS;
867         }
868
869         for (i=0; i < old_scb->sub.num_packages; i++) {
870                 if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
871                         continue;
872                 }
873
874                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
875                         continue;
876                 }
877
878                 old_scp = &old_scb->sub.packages[i];
879                 break;
880         }
881         /* Primary:Kerberos element of supplementalCredentials */
882         if (old_scp) {
883                 DATA_BLOB blob;
884
885                 blob = strhex_to_data_blob(io->ac, old_scp->data);
886                 if (!blob.data) {
887                         return ldb_oom(ldb);
888                 }
889
890                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
891                 ndr_err = ndr_pull_struct_blob(&blob, io->ac, &_old_pkb,
892                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
893                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
894                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
895                         ldb_asprintf_errstring(ldb,
896                                                "setup_primary_kerberos: "
897                                                "failed to pull old package_PrimaryKerberosBlob: %s",
898                                                nt_errstr(status));
899                         return LDB_ERR_OPERATIONS_ERROR;
900                 }
901
902                 if (_old_pkb.version != 3) {
903                         ldb_asprintf_errstring(ldb,
904                                                "setup_primary_kerberos: "
905                                                "package_PrimaryKerberosBlob version[%u] expected[3]",
906                                                _old_pkb.version);
907                         return LDB_ERR_OPERATIONS_ERROR;
908                 }
909
910                 old_pkb3 = &_old_pkb.ctr.ctr3;
911         }
912
913         /* if we didn't found the old keys we're done */
914         if (!old_pkb3) {
915                 return LDB_SUCCESS;
916         }
917
918         /* fill in the old keys */
919         pkb3->num_old_keys      = old_pkb3->num_keys;
920         pkb3->old_keys          = old_pkb3->keys;
921
922         return LDB_SUCCESS;
923 }
924
925 static int setup_primary_kerberos_newer(struct setup_password_fields_io *io,
926                                         const struct supplementalCredentialsBlob *old_scb,
927                                         struct package_PrimaryKerberosBlob *pkb)
928 {
929         struct ldb_context *ldb;
930         struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4;
931         struct supplementalCredentialsPackage *old_scp = NULL;
932         struct package_PrimaryKerberosBlob _old_pkb;
933         struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL;
934         uint32_t i;
935         enum ndr_err_code ndr_err;
936
937         ldb = ldb_module_get_ctx(io->ac->module);
938
939         /*
940          * prepare generation of keys
941          *
942          * ENCTYPE_AES256_CTS_HMAC_SHA1_96
943          * ENCTYPE_AES128_CTS_HMAC_SHA1_96
944          * ENCTYPE_DES_CBC_MD5
945          * ENCTYPE_DES_CBC_CRC
946          */
947         pkb->version                    = 4;
948         pkb4->salt.string               = io->g.salt;
949         pkb4->default_iteration_count   = 4096;
950         pkb4->num_keys                  = 4;
951
952         pkb4->keys = talloc_array(io->ac,
953                                   struct package_PrimaryKerberosKey4,
954                                   pkb4->num_keys);
955         if (!pkb4->keys) {
956                 return ldb_oom(ldb);
957         }
958
959         pkb4->keys[0].iteration_count   = 4096;
960         pkb4->keys[0].keytype           = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
961         pkb4->keys[0].value             = &io->g.aes_256;
962         pkb4->keys[1].iteration_count   = 4096;
963         pkb4->keys[1].keytype           = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
964         pkb4->keys[1].value             = &io->g.aes_128;
965         pkb4->keys[2].iteration_count   = 4096;
966         pkb4->keys[2].keytype           = ENCTYPE_DES_CBC_MD5;
967         pkb4->keys[2].value             = &io->g.des_md5;
968         pkb4->keys[3].iteration_count   = 4096;
969         pkb4->keys[3].keytype           = ENCTYPE_DES_CBC_CRC;
970         pkb4->keys[3].value             = &io->g.des_crc;
971
972         /* initialize the old keys to zero */
973         pkb4->num_old_keys      = 0;
974         pkb4->old_keys          = NULL;
975         pkb4->num_older_keys    = 0;
976         pkb4->older_keys        = NULL;
977
978         /* if there're no old keys, then we're done */
979         if (!old_scb) {
980                 return LDB_SUCCESS;
981         }
982
983         for (i=0; i < old_scb->sub.num_packages; i++) {
984                 if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) {
985                         continue;
986                 }
987
988                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
989                         continue;
990                 }
991
992                 old_scp = &old_scb->sub.packages[i];
993                 break;
994         }
995         /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
996         if (old_scp) {
997                 DATA_BLOB blob;
998
999                 blob = strhex_to_data_blob(io->ac, old_scp->data);
1000                 if (!blob.data) {
1001                         return ldb_oom(ldb);
1002                 }
1003
1004                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
1005                 ndr_err = ndr_pull_struct_blob(&blob, io->ac,
1006                                                &_old_pkb,
1007                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
1008                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1009                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1010                         ldb_asprintf_errstring(ldb,
1011                                                "setup_primary_kerberos_newer: "
1012                                                "failed to pull old package_PrimaryKerberosBlob: %s",
1013                                                nt_errstr(status));
1014                         return LDB_ERR_OPERATIONS_ERROR;
1015                 }
1016
1017                 if (_old_pkb.version != 4) {
1018                         ldb_asprintf_errstring(ldb,
1019                                                "setup_primary_kerberos_newer: "
1020                                                "package_PrimaryKerberosBlob version[%u] expected[4]",
1021                                                _old_pkb.version);
1022                         return LDB_ERR_OPERATIONS_ERROR;
1023                 }
1024
1025                 old_pkb4 = &_old_pkb.ctr.ctr4;
1026         }
1027
1028         /* if we didn't found the old keys we're done */
1029         if (!old_pkb4) {
1030                 return LDB_SUCCESS;
1031         }
1032
1033         /* fill in the old keys */
1034         pkb4->num_old_keys      = old_pkb4->num_keys;
1035         pkb4->old_keys          = old_pkb4->keys;
1036         pkb4->num_older_keys    = old_pkb4->num_old_keys;
1037         pkb4->older_keys        = old_pkb4->old_keys;
1038
1039         return LDB_SUCCESS;
1040 }
1041
1042 static int setup_primary_wdigest(struct setup_password_fields_io *io,
1043                                  const struct supplementalCredentialsBlob *old_scb,
1044                                  struct package_PrimaryWDigestBlob *pdb)
1045 {
1046         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1047         DATA_BLOB sAMAccountName;
1048         DATA_BLOB sAMAccountName_l;
1049         DATA_BLOB sAMAccountName_u;
1050         const char *user_principal_name = io->u.user_principal_name;
1051         DATA_BLOB userPrincipalName;
1052         DATA_BLOB userPrincipalName_l;
1053         DATA_BLOB userPrincipalName_u;
1054         DATA_BLOB netbios_domain;
1055         DATA_BLOB netbios_domain_l;
1056         DATA_BLOB netbios_domain_u;
1057         DATA_BLOB dns_domain;
1058         DATA_BLOB dns_domain_l;
1059         DATA_BLOB dns_domain_u;
1060         DATA_BLOB digest;
1061         DATA_BLOB delim;
1062         DATA_BLOB backslash;
1063         uint8_t i;
1064         struct {
1065                 DATA_BLOB *user;
1066                 DATA_BLOB *realm;
1067                 DATA_BLOB *nt4dom;
1068         } wdigest[] = {
1069         /*
1070          * See 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction
1071          *     https://msdn.microsoft.com/en-us/library/cc245680.aspx
1072          * for what precalculated hashes are supposed to be stored...
1073          *
1074          * I can't reproduce all values which should contain "Digest" as realm,
1075          * am I doing something wrong or is w2k3 just broken...?
1076          *
1077          * W2K3 fills in following for a user:
1078          *
1079          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1080          * sAMAccountName: NewUser2Sam
1081          * userPrincipalName: NewUser2Princ@sub1.w2k3.vmnet1.vm.base
1082          *
1083          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1084          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1085          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1086          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1087          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1088          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1089          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1090          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1091          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1092          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1093          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1094          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1095          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1096          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1097          * 221c55284451ae9b3aacaa2a3c86f10f => NewUser2Princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1098          * 74e1be668853d4324d38c07e2acfb8ea => (w2k3 has a bug here!) newuser2princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1099          * e1e244ab7f098e3ae1761be7f9229bbb => NEWUSER2PRINC@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1100          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1101          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1102          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1103          * 31dc704d3640335b2123d4ee28aa1f11 => ??? changes with NewUser2Sam => NewUser1Sam
1104          * 36349f5cecd07320fb3bb0e119230c43 => ??? changes with NewUser2Sam => NewUser1Sam
1105          * 12adf019d037fb535c01fd0608e78d9d => ??? changes with NewUser2Sam => NewUser1Sam
1106          * 6feecf8e724906f3ee1105819c5105a1 => ??? changes with NewUser2Princ => NewUser1Princ
1107          * 6c6911f3de6333422640221b9c51ff1f => ??? changes with NewUser2Princ => NewUser1Princ
1108          * 4b279877e742895f9348ac67a8de2f69 => ??? changes with NewUser2Princ => NewUser1Princ
1109          * db0c6bff069513e3ebb9870d29b57490 => ??? changes with NewUser2Sam => NewUser1Sam
1110          * 45072621e56b1c113a4e04a8ff68cd0e => ??? changes with NewUser2Sam => NewUser1Sam
1111          * 11d1220abc44a9c10cf91ef4a9c1de02 => ??? changes with NewUser2Sam => NewUser1Sam
1112          *
1113          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1114          * sAMAccountName: NewUser2Sam
1115          *
1116          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1117          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1118          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1119          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1120          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1121          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1122          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1123          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1124          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1125          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1126          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1127          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1128          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1129          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1130          * 8a140d30b6f0a5912735dc1e3bc993b4 => NewUser2Sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1131          * 86d95b2faae6cae4ec261e7fbaccf093 => (here w2k3 is correct) newuser2sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1132          * dfeff1493110220efcdfc6362e5f5450 => NEWUSER2SAM@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1133          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1134          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1135          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1136          * 31dc704d3640335b2123d4ee28aa1f11 => ???M1   changes with NewUser2Sam => NewUser1Sam
1137          * 36349f5cecd07320fb3bb0e119230c43 => ???M1.L changes with newuser2sam => newuser1sam
1138          * 12adf019d037fb535c01fd0608e78d9d => ???M1.U changes with NEWUSER2SAM => NEWUSER1SAM
1139          * 569b4533f2d9e580211dd040e5e360a8 => ???M2   changes with NewUser2Princ => NewUser1Princ
1140          * 52528bddf310a587c5d7e6a9ae2cbb20 => ???M2.L changes with newuser2princ => newuser1princ
1141          * 4f629a4f0361289ca4255ab0f658fcd5 => ???M3 changes with NewUser2Princ => NewUser1Princ (doesn't depend on case of userPrincipal )
1142          * db0c6bff069513e3ebb9870d29b57490 => ???M4 changes with NewUser2Sam => NewUser1Sam
1143          * 45072621e56b1c113a4e04a8ff68cd0e => ???M5 changes with NewUser2Sam => NewUser1Sam (doesn't depend on case of sAMAccountName)
1144          * 11d1220abc44a9c10cf91ef4a9c1de02 => ???M4.U changes with NEWUSER2SAM => NEWUSER1SAM
1145          */
1146
1147         /*
1148          * sAMAccountName, netbios_domain
1149          */
1150                 {
1151                 .user   = &sAMAccountName,
1152                 .realm  = &netbios_domain,
1153                 },
1154                 {
1155                 .user   = &sAMAccountName_l,
1156                 .realm  = &netbios_domain_l,
1157                 },
1158                 {
1159                 .user   = &sAMAccountName_u,
1160                 .realm  = &netbios_domain_u,
1161                 },
1162                 {
1163                 .user   = &sAMAccountName,
1164                 .realm  = &netbios_domain_u,
1165                 },
1166                 {
1167                 .user   = &sAMAccountName,
1168                 .realm  = &netbios_domain_l,
1169                 },
1170                 {
1171                 .user   = &sAMAccountName_u,
1172                 .realm  = &netbios_domain_l,
1173                 },
1174                 {
1175                 .user   = &sAMAccountName_l,
1176                 .realm  = &netbios_domain_u,
1177                 },
1178         /*
1179          * sAMAccountName, dns_domain
1180          *
1181          * TODO:
1182          * Windows preserves the case of the DNS domain,
1183          * Samba lower cases the domain at provision time
1184          * This means that for mixed case Domains, the WDigest08 hash
1185          * calculated by Samba differs from that calculated by Windows.
1186          * Until we get a real world use case this will remain a known
1187          * bug, as changing the case could have unforeseen impacts.
1188          *
1189          */
1190                 {
1191                 .user   = &sAMAccountName,
1192                 .realm  = &dns_domain,
1193                 },
1194                 {
1195                 .user   = &sAMAccountName_l,
1196                 .realm  = &dns_domain_l,
1197                 },
1198                 {
1199                 .user   = &sAMAccountName_u,
1200                 .realm  = &dns_domain_u,
1201                 },
1202                 {
1203                 .user   = &sAMAccountName,
1204                 .realm  = &dns_domain_u,
1205                 },
1206                 {
1207                 .user   = &sAMAccountName,
1208                 .realm  = &dns_domain_l,
1209                 },
1210                 {
1211                 .user   = &sAMAccountName_u,
1212                 .realm  = &dns_domain_l,
1213                 },
1214                 {
1215                 .user   = &sAMAccountName_l,
1216                 .realm  = &dns_domain_u,
1217                 },
1218         /* 
1219          * userPrincipalName, no realm
1220          */
1221                 {
1222                 .user   = &userPrincipalName,
1223                 },
1224                 {
1225                 /* 
1226                  * NOTE: w2k3 messes this up, if the user has a real userPrincipalName,
1227                  *       the fallback to the sAMAccountName based userPrincipalName is correct
1228                  */
1229                 .user   = &userPrincipalName_l,
1230                 },
1231                 {
1232                 .user   = &userPrincipalName_u,
1233                 },
1234         /* 
1235          * nt4dom\sAMAccountName, no realm
1236          */
1237                 {
1238                 .user   = &sAMAccountName,
1239                 .nt4dom = &netbios_domain
1240                 },
1241                 {
1242                 .user   = &sAMAccountName_l,
1243                 .nt4dom = &netbios_domain_l
1244                 },
1245                 {
1246                 .user   = &sAMAccountName_u,
1247                 .nt4dom = &netbios_domain_u
1248                 },
1249
1250         /*
1251          * the following ones are guessed depending on the technet2 article
1252          * but not reproducable on a w2k3 server
1253          */
1254         /* sAMAccountName with "Digest" realm */
1255                 {
1256                 .user   = &sAMAccountName,
1257                 .realm  = &digest
1258                 },
1259                 {
1260                 .user   = &sAMAccountName_l,
1261                 .realm  = &digest
1262                 },
1263                 {
1264                 .user   = &sAMAccountName_u,
1265                 .realm  = &digest
1266                 },
1267         /* userPrincipalName with "Digest" realm */
1268                 {
1269                 .user   = &userPrincipalName,
1270                 .realm  = &digest
1271                 },
1272                 {
1273                 .user   = &userPrincipalName_l,
1274                 .realm  = &digest
1275                 },
1276                 {
1277                 .user   = &userPrincipalName_u,
1278                 .realm  = &digest
1279                 },
1280         /* nt4dom\\sAMAccountName with "Digest" realm */
1281                 {
1282                 .user   = &sAMAccountName,
1283                 .nt4dom = &netbios_domain,
1284                 .realm  = &digest
1285                 },
1286                 {
1287                 .user   = &sAMAccountName_l,
1288                 .nt4dom = &netbios_domain_l,
1289                 .realm  = &digest
1290                 },
1291                 {
1292                 .user   = &sAMAccountName_u,
1293                 .nt4dom = &netbios_domain_u,
1294                 .realm  = &digest
1295                 },
1296         };
1297
1298         /* prepare DATA_BLOB's used in the combinations array */
1299         sAMAccountName          = data_blob_string_const(io->u.sAMAccountName);
1300         sAMAccountName_l        = data_blob_string_const(strlower_talloc(io->ac, io->u.sAMAccountName));
1301         if (!sAMAccountName_l.data) {
1302                 return ldb_oom(ldb);
1303         }
1304         sAMAccountName_u        = data_blob_string_const(strupper_talloc(io->ac, io->u.sAMAccountName));
1305         if (!sAMAccountName_u.data) {
1306                 return ldb_oom(ldb);
1307         }
1308
1309         /* if the user doesn't have a userPrincipalName, create one (with lower case realm) */
1310         if (!user_principal_name) {
1311                 user_principal_name = talloc_asprintf(io->ac, "%s@%s",
1312                                                       io->u.sAMAccountName,
1313                                                       io->ac->status->domain_data.dns_domain);
1314                 if (!user_principal_name) {
1315                         return ldb_oom(ldb);
1316                 }       
1317         }
1318         userPrincipalName       = data_blob_string_const(user_principal_name);
1319         userPrincipalName_l     = data_blob_string_const(strlower_talloc(io->ac, user_principal_name));
1320         if (!userPrincipalName_l.data) {
1321                 return ldb_oom(ldb);
1322         }
1323         userPrincipalName_u     = data_blob_string_const(strupper_talloc(io->ac, user_principal_name));
1324         if (!userPrincipalName_u.data) {
1325                 return ldb_oom(ldb);
1326         }
1327
1328         netbios_domain          = data_blob_string_const(io->ac->status->domain_data.netbios_domain);
1329         netbios_domain_l        = data_blob_string_const(strlower_talloc(io->ac,
1330                                                                          io->ac->status->domain_data.netbios_domain));
1331         if (!netbios_domain_l.data) {
1332                 return ldb_oom(ldb);
1333         }
1334         netbios_domain_u        = data_blob_string_const(strupper_talloc(io->ac,
1335                                                                          io->ac->status->domain_data.netbios_domain));
1336         if (!netbios_domain_u.data) {
1337                 return ldb_oom(ldb);
1338         }
1339
1340         dns_domain              = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1341         dns_domain_l            = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1342         dns_domain_u            = data_blob_string_const(io->ac->status->domain_data.realm);
1343
1344         digest                  = data_blob_string_const("Digest");
1345
1346         delim                   = data_blob_string_const(":");
1347         backslash               = data_blob_string_const("\\");
1348
1349         pdb->num_hashes = ARRAY_SIZE(wdigest);
1350         pdb->hashes     = talloc_array(io->ac, struct package_PrimaryWDigestHash,
1351                                        pdb->num_hashes);
1352         if (!pdb->hashes) {
1353                 return ldb_oom(ldb);
1354         }
1355
1356         for (i=0; i < ARRAY_SIZE(wdigest); i++) {
1357                 MD5_CTX md5;
1358                 MD5Init(&md5);
1359                 if (wdigest[i].nt4dom) {
1360                         MD5Update(&md5, wdigest[i].nt4dom->data, wdigest[i].nt4dom->length);
1361                         MD5Update(&md5, backslash.data, backslash.length);
1362                 }
1363                 MD5Update(&md5, wdigest[i].user->data, wdigest[i].user->length);
1364                 MD5Update(&md5, delim.data, delim.length);
1365                 if (wdigest[i].realm) {
1366                         MD5Update(&md5, wdigest[i].realm->data, wdigest[i].realm->length);
1367                 }
1368                 MD5Update(&md5, delim.data, delim.length);
1369                 MD5Update(&md5, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length);
1370                 MD5Final(pdb->hashes[i].hash, &md5);
1371         }
1372
1373         return LDB_SUCCESS;
1374 }
1375
1376 #define SHA_SALT_PERMITTED_CHARS "abcdefghijklmnopqrstuvwxyz" \
1377                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
1378                                  "0123456789./"
1379 #define SHA_SALT_SIZE 16
1380 #define SHA_256_SCHEME "CryptSHA256"
1381 #define SHA_512_SCHEME "CryptSHA512"
1382 #define CRYPT "{CRYPT}"
1383 #define SHA_ID_LEN 3
1384 #define SHA_256_ALGORITHM_ID 5
1385 #define SHA_512_ALGORITHM_ID 6
1386 #define ROUNDS_PARAMETER "rounds="
1387
1388 /*
1389  * Extract the crypt (3) algorithm number and number of hash rounds from the
1390  * supplied scheme string
1391  */
1392 static bool parse_scheme(const char *scheme, int *algorithm, int *rounds) {
1393
1394         const char *rp = NULL; /* Pointer to the 'rounds=' option */
1395         char digits[21];       /* digits extracted from the rounds option */
1396         int i = 0;             /* loop index variable */
1397
1398         if (strncasecmp(SHA_256_SCHEME, scheme, strlen(SHA_256_SCHEME)) == 0) {
1399                 *algorithm = SHA_256_ALGORITHM_ID;
1400         } else if (strncasecmp(SHA_512_SCHEME, scheme, strlen(SHA_256_SCHEME))
1401                    == 0) {
1402                 *algorithm = SHA_512_ALGORITHM_ID;
1403         } else {
1404                 return false;
1405         }
1406
1407         rp = strcasestr(scheme, ROUNDS_PARAMETER);
1408         if (rp == NULL) {
1409                 /* No options specified, use crypt default number of rounds */
1410                 *rounds = 0;
1411                 return true;
1412         }
1413         rp += strlen(ROUNDS_PARAMETER);
1414         for (i = 0; isdigit(rp[i]) && i < (sizeof(digits) - 1); i++) {
1415                 digits[i] = rp[i];
1416         }
1417         digits[i] = '\0';
1418         *rounds = atoi(digits);
1419         return true;
1420 }
1421
1422 /*
1423  * Calculate the password hash specified by scheme, and return it in
1424  * hash_value
1425  */
1426 static int setup_primary_userPassword_hash(
1427         TALLOC_CTX *ctx,
1428         struct setup_password_fields_io *io,
1429         const char* scheme,
1430         struct package_PrimaryUserPasswordValue *hash_value)
1431 {
1432         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1433         const char *salt = NULL;        /* Randomly generated salt */
1434         const char *cmd = NULL;         /* command passed to crypt */
1435         const char *hash = NULL;        /* password hash generated by crypt */
1436         int algorithm = 0;              /* crypt hash algorithm number */
1437         int rounds = 0;                 /* The number of hash rounds */
1438         DATA_BLOB *hash_blob = NULL;
1439         TALLOC_CTX *frame = talloc_stackframe();
1440 #ifdef HAVE_CRYPT_R
1441         struct crypt_data crypt_data;   /* working storage used by crypt */
1442 #endif
1443
1444         /* Genrate a random password salt */
1445         salt = generate_random_str_list(frame,
1446                                         SHA_SALT_SIZE,
1447                                         SHA_SALT_PERMITTED_CHARS);
1448         if (salt == NULL) {
1449                 TALLOC_FREE(frame);
1450                 return ldb_oom(ldb);
1451         }
1452
1453         /* determine the hashing algoritm and number of rounds*/
1454         if (!parse_scheme(scheme, &algorithm, &rounds)) {
1455                 ldb_asprintf_errstring(
1456                         ldb,
1457                         "setup_primary_userPassword: Invalid scheme of [%s] "
1458                         "specified for 'password hash userPassword schemes' in "
1459                         "samba.conf",
1460                         scheme);
1461                 TALLOC_FREE(frame);
1462                 return LDB_ERR_OPERATIONS_ERROR;
1463         }
1464         hash_value->scheme = talloc_strdup(ctx, CRYPT);
1465         hash_value->scheme_len = strlen(CRYPT) + 1;
1466
1467         /* generate the id/salt parameter used by crypt */
1468         if (rounds) {
1469                 cmd = talloc_asprintf(frame,
1470                                       "$%d$rounds=%d$%s",
1471                                       algorithm,
1472                                       rounds,
1473                                       salt);
1474         } else {
1475                 cmd = talloc_asprintf(frame, "$%d$%s", algorithm, salt);
1476         }
1477
1478         /*
1479          * Relies on the assertion that cleartext_utf8->data is a zero
1480          * terminated UTF-8 string
1481          */
1482 #ifdef HAVE_CRYPT_R
1483         hash = crypt_r((char *)io->n.cleartext_utf8->data, cmd, &crypt_data);
1484 #else
1485         /*
1486          * No crypt_r falling back to crypt, which is NOT thread safe
1487          * Thread safety MT-Unsafe race:crypt
1488          */
1489         hash = crypt((char *)io->n.cleartext_utf8->data, cmd);
1490 #endif
1491         if (hash == NULL) {
1492                 char buf[1024];
1493                 int err = strerror_r(errno, buf, sizeof(buf));
1494                 if (err != 0) {
1495                         strlcpy(buf, "Unknown error", sizeof(buf)-1);
1496                 }
1497                 ldb_asprintf_errstring(
1498                         ldb,
1499                         "setup_primary_userPassword: generation of a %s "
1500                         "password hash failed: (%s)",
1501                         scheme,
1502                         buf);
1503                 TALLOC_FREE(frame);
1504                 return LDB_ERR_OPERATIONS_ERROR;
1505         }
1506
1507         hash_blob = talloc_zero(ctx, DATA_BLOB);
1508
1509         if (hash_blob == NULL) {
1510                 TALLOC_FREE(frame);
1511                 return ldb_oom(ldb);
1512         }
1513
1514         *hash_blob =  data_blob_talloc(hash_blob,
1515                                        (const uint8_t *)hash,
1516                                        strlen(hash));
1517         if (hash_blob->data == NULL) {
1518                 TALLOC_FREE(frame);
1519                 return ldb_oom(ldb);
1520         }
1521         hash_value->value = hash_blob;
1522         TALLOC_FREE(frame);
1523         return LDB_SUCCESS;
1524 }
1525
1526 /*
1527  * Calculate the desired extra password hashes
1528  */
1529 static int setup_primary_userPassword(
1530         struct setup_password_fields_io *io,
1531         const struct supplementalCredentialsBlob *old_scb,
1532         struct package_PrimaryUserPasswordBlob *p_userPassword_b)
1533 {
1534         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1535         TALLOC_CTX *frame = talloc_stackframe();
1536         int i;
1537         int ret;
1538
1539         /*
1540          * Save the current nt_hash, use this to determine if the password
1541          * has been changed by windows. Which will invalidate the userPassword
1542          * hash. Note once NTLM-Strong-NOWTF becomes available it should be
1543          * used in preference to the NT password hash
1544          */
1545         if (io->g.nt_hash == NULL) {
1546                 ldb_asprintf_errstring(ldb,
1547                         "No NT Hash, unable to calculate userPassword hashes");
1548                         return LDB_ERR_UNWILLING_TO_PERFORM;
1549         }
1550         p_userPassword_b->current_nt_hash = *io->g.nt_hash;
1551
1552         /*
1553          * Determine the number of hashes
1554          * Note: that currently there is no limit on the number of hashes
1555          *       no checking is done on the number of schemes specified
1556          *       or for uniqueness.
1557          */
1558         p_userPassword_b->num_hashes = 0;
1559         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1560                 p_userPassword_b->num_hashes++;
1561         }
1562
1563         p_userPassword_b->hashes
1564                 = talloc_array(io->ac,
1565                                struct package_PrimaryUserPasswordValue,
1566                                p_userPassword_b->num_hashes);
1567         if (p_userPassword_b->hashes == NULL) {
1568                 TALLOC_FREE(frame);
1569                 return ldb_oom(ldb);
1570         }
1571
1572         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1573                 ret = setup_primary_userPassword_hash(
1574                         p_userPassword_b->hashes,
1575                         io,
1576                         io->ac->userPassword_schemes[i],
1577                         &p_userPassword_b->hashes[i]);
1578                 if (ret != LDB_SUCCESS) {
1579                         TALLOC_FREE(frame);
1580                         return ret;
1581                 }
1582         }
1583         return LDB_SUCCESS;
1584 }
1585
1586
1587 static int setup_primary_samba_gpg(struct setup_password_fields_io *io,
1588                                    struct package_PrimarySambaGPGBlob *pgb)
1589 {
1590         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1591 #ifdef ENABLE_GPGME
1592         gpgme_error_t gret;
1593         gpgme_ctx_t ctx = NULL;
1594         size_t num_keys = str_list_length(io->ac->gpg_key_ids);
1595         gpgme_key_t keys[num_keys+1];
1596         size_t ki = 0;
1597         size_t kr = 0;
1598         gpgme_data_t plain_data = NULL;
1599         gpgme_data_t crypt_data = NULL;
1600         size_t crypt_length = 0;
1601         char *crypt_mem = NULL;
1602
1603         gret = gpgme_new(&ctx);
1604         if (gret != GPG_ERR_NO_ERROR) {
1605                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1606                           "%s:%s: gret[%u] %s\n",
1607                           __location__, __func__,
1608                           gret, gpgme_strerror(gret));
1609                 return ldb_module_operr(io->ac->module);
1610         }
1611
1612         gpgme_set_armor(ctx, 1);
1613
1614         gret = gpgme_data_new_from_mem(&plain_data,
1615                                        (const char *)io->n.cleartext_utf16->data,
1616                                        io->n.cleartext_utf16->length,
1617                                        0 /* no copy */);
1618         if (gret != GPG_ERR_NO_ERROR) {
1619                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1620                           "%s:%s: gret[%u] %s\n",
1621                           __location__, __func__,
1622                           gret, gpgme_strerror(gret));
1623                 gpgme_release(ctx);
1624                 return ldb_module_operr(io->ac->module);
1625         }
1626         gret = gpgme_data_new(&crypt_data);
1627         if (gret != GPG_ERR_NO_ERROR) {
1628                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1629                           "%s:%s: gret[%u] %s\n",
1630                           __location__, __func__,
1631                           gret, gpgme_strerror(gret));
1632                 gpgme_data_release(plain_data);
1633                 gpgme_release(ctx);
1634                 return ldb_module_operr(io->ac->module);
1635         }
1636
1637         for (ki = 0; ki < num_keys; ki++) {
1638                 const char *key_id = io->ac->gpg_key_ids[ki];
1639                 size_t len = strlen(key_id);
1640
1641                 keys[ki] = NULL;
1642
1643                 if (len < 16) {
1644                         ldb_debug(ldb, LDB_DEBUG_FATAL,
1645                                   "%s:%s: ki[%zu] key_id[%s] strlen < 16, "
1646                                   "please specify at least the 64bit key id\n",
1647                                   __location__, __func__,
1648                                   ki, key_id);
1649                         for (kr = 0; keys[kr] != NULL; kr++) {
1650                                 gpgme_key_release(keys[kr]);
1651                         }
1652                         gpgme_data_release(crypt_data);
1653                         gpgme_data_release(plain_data);
1654                         gpgme_release(ctx);
1655                         return ldb_module_operr(io->ac->module);
1656                 }
1657
1658                 gret = gpgme_get_key(ctx, key_id, &keys[ki], 0 /* public key */);
1659                 if (gret != GPG_ERR_NO_ERROR) {
1660                         keys[ki] = NULL;
1661                         if (gpg_err_source(gret) == GPG_ERR_SOURCE_GPGME
1662                             && gpg_err_code(gret) == GPG_ERR_EOF) {
1663                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1664                                           "Invalid "
1665                                           "'password hash gpg key ids': "
1666                                           "Public Key ID [%s] "
1667                                           "not found in keyring\n",
1668                                           key_id);
1669
1670                         } else {
1671                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1672                                           "%s:%s: ki[%zu] key_id[%s] "
1673                                           "gret[%u] %s\n",
1674                                           __location__, __func__,
1675                                           ki, key_id,
1676                                           gret, gpgme_strerror(gret));
1677                         }
1678                         for (kr = 0; keys[kr] != NULL; kr++) {
1679                                 gpgme_key_release(keys[kr]);
1680                         }
1681                         gpgme_data_release(crypt_data);
1682                         gpgme_data_release(plain_data);
1683                         gpgme_release(ctx);
1684                         return ldb_module_operr(io->ac->module);
1685                 }
1686         }
1687         keys[ki] = NULL;
1688
1689         gret = gpgme_op_encrypt(ctx, keys,
1690                                 GPGME_ENCRYPT_ALWAYS_TRUST,
1691                                 plain_data, crypt_data);
1692         gpgme_data_release(plain_data);
1693         plain_data = NULL;
1694         for (kr = 0; keys[kr] != NULL; kr++) {
1695                 gpgme_key_release(keys[kr]);
1696                 keys[kr] = NULL;
1697         }
1698         gpgme_release(ctx);
1699         ctx = NULL;
1700         if (gret != GPG_ERR_NO_ERROR) {
1701                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1702                           "%s:%s: gret[%u] %s\n",
1703                           __location__, __func__,
1704                           gret, gpgme_strerror(gret));
1705                 gpgme_data_release(crypt_data);
1706                 return ldb_module_operr(io->ac->module);
1707         }
1708
1709         crypt_mem = gpgme_data_release_and_get_mem(crypt_data, &crypt_length);
1710         crypt_data = NULL;
1711         if (crypt_mem == NULL) {
1712                 return ldb_module_oom(io->ac->module);
1713         }
1714
1715         pgb->gpg_blob = data_blob_talloc(io->ac,
1716                                          (const uint8_t *)crypt_mem,
1717                                          crypt_length);
1718         gpgme_free(crypt_mem);
1719         crypt_mem = NULL;
1720         crypt_length = 0;
1721         if (pgb->gpg_blob.data == NULL) {
1722                 return ldb_module_oom(io->ac->module);
1723         }
1724
1725         return LDB_SUCCESS;
1726 #else /* ENABLE_GPGME */
1727         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
1728                       "You configured 'password hash gpg key ids', "
1729                       "but GPGME support is missing. (%s:%d)",
1730                       __FILE__, __LINE__);
1731         return LDB_ERR_UNWILLING_TO_PERFORM;
1732 #endif /* else ENABLE_GPGME */
1733 }
1734
1735 #define NUM_PACKAGES 6
1736 static int setup_supplemental_field(struct setup_password_fields_io *io)
1737 {
1738         struct ldb_context *ldb;
1739         struct supplementalCredentialsBlob scb;
1740         struct supplementalCredentialsBlob *old_scb = NULL;
1741         /*
1742          * Packages +
1743          * ( Kerberos-Newer-Keys, Kerberos,
1744          *   WDigest, CLEARTEXT, userPassword, SambaGPG)
1745          */
1746         uint32_t num_names = 0;
1747         const char *names[1+NUM_PACKAGES];
1748         uint32_t num_packages = 0;
1749         struct supplementalCredentialsPackage packages[1+NUM_PACKAGES];
1750         struct supplementalCredentialsPackage *pp = packages;
1751         int ret;
1752         enum ndr_err_code ndr_err;
1753         bool do_newer_keys = false;
1754         bool do_cleartext = false;
1755         bool do_samba_gpg = false;
1756
1757         ZERO_STRUCT(names);
1758         ZERO_STRUCT(packages);
1759
1760         ldb = ldb_module_get_ctx(io->ac->module);
1761
1762         if (!io->n.cleartext_utf8) {
1763                 /*
1764                  * when we don't have a cleartext password
1765                  * we can't setup a supplementalCredential value
1766                  */
1767                 return LDB_SUCCESS;
1768         }
1769
1770         /* if there's an old supplementaCredentials blob then use it */
1771         if (io->o.supplemental) {
1772                 if (io->o.scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
1773                         old_scb = &io->o.scb;
1774                 } else {
1775                         ldb_debug(ldb, LDB_DEBUG_ERROR,
1776                                   "setup_supplemental_field: "
1777                                   "supplementalCredentialsBlob "
1778                                   "signature[0x%04X] expected[0x%04X]",
1779                                   io->o.scb.sub.signature,
1780                                   SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
1781                 }
1782         }
1783         /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
1784
1785
1786
1787         /*
1788          * The ordering is this
1789          *
1790          * Primary:Kerberos-Newer-Keys (optional)
1791          * Primary:Kerberos
1792          * Primary:WDigest
1793          * Primary:CLEARTEXT (optional)
1794          * Primary:userPassword
1795          * Primary:SambaGPG (optional)
1796          *
1797          * And the 'Packages' package is insert before the last
1798          * other package.
1799          *
1800          * Note: it's important that Primary:SambaGPG is added as
1801          * the last element. This is the indication that it matches
1802          * the current password. When a password change happens on
1803          * a Windows DC, it will keep the old Primary:SambaGPG value,
1804          * but as the first element.
1805          */
1806         do_newer_keys = (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008);
1807         if (do_newer_keys) {
1808                 struct package_PrimaryKerberosBlob pknb;
1809                 DATA_BLOB pknb_blob;
1810                 char *pknb_hexstr;
1811                 /*
1812                  * setup 'Primary:Kerberos-Newer-Keys' element
1813                  */
1814                 names[num_names++] = "Kerberos-Newer-Keys";
1815
1816                 ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
1817                 if (ret != LDB_SUCCESS) {
1818                         return ret;
1819                 }
1820
1821                 ndr_err = ndr_push_struct_blob(
1822                         &pknb_blob, io->ac,
1823                         &pknb,
1824                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1825                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1826                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1827                         ldb_asprintf_errstring(
1828                                 ldb,
1829                                 "setup_supplemental_field: "
1830                                 "failed to push "
1831                                 "package_PrimaryKerberosNeverBlob: %s",
1832                                 nt_errstr(status));
1833                         return LDB_ERR_OPERATIONS_ERROR;
1834                 }
1835                 pknb_hexstr = data_blob_hex_string_upper(io->ac, &pknb_blob);
1836                 if (!pknb_hexstr) {
1837                         return ldb_oom(ldb);
1838                 }
1839                 pp->name        = "Primary:Kerberos-Newer-Keys";
1840                 pp->reserved    = 1;
1841                 pp->data        = pknb_hexstr;
1842                 pp++;
1843                 num_packages++;
1844         }
1845
1846         {
1847                 /*
1848                  * setup 'Primary:Kerberos' element
1849                  */
1850                 /* Primary:Kerberos */
1851                 struct package_PrimaryKerberosBlob pkb;
1852                 DATA_BLOB pkb_blob;
1853                 char *pkb_hexstr;
1854
1855                 names[num_names++] = "Kerberos";
1856
1857                 ret = setup_primary_kerberos(io, old_scb, &pkb);
1858                 if (ret != LDB_SUCCESS) {
1859                         return ret;
1860                 }
1861
1862                 ndr_err = ndr_push_struct_blob(
1863                         &pkb_blob, io->ac,
1864                         &pkb,
1865                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1866                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1867                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1868                         ldb_asprintf_errstring(
1869                                 ldb,
1870                                 "setup_supplemental_field: "
1871                                 "failed to push package_PrimaryKerberosBlob: %s",
1872                                 nt_errstr(status));
1873                         return LDB_ERR_OPERATIONS_ERROR;
1874                 }
1875                 pkb_hexstr = data_blob_hex_string_upper(io->ac, &pkb_blob);
1876                 if (!pkb_hexstr) {
1877                         return ldb_oom(ldb);
1878                 }
1879                 pp->name        = "Primary:Kerberos";
1880                 pp->reserved    = 1;
1881                 pp->data        = pkb_hexstr;
1882                 pp++;
1883                 num_packages++;
1884         }
1885
1886         {
1887                 /*
1888                  * setup 'Primary:WDigest' element
1889                  */
1890                 struct package_PrimaryWDigestBlob pdb;
1891                 DATA_BLOB pdb_blob;
1892                 char *pdb_hexstr;
1893
1894                 names[num_names++] = "WDigest";
1895
1896                 ret = setup_primary_wdigest(io, old_scb, &pdb);
1897                 if (ret != LDB_SUCCESS) {
1898                         return ret;
1899                 }
1900
1901                 ndr_err = ndr_push_struct_blob(
1902                         &pdb_blob, io->ac,
1903                         &pdb,
1904                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryWDigestBlob);
1905                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1906                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1907                         ldb_asprintf_errstring(
1908                                 ldb,
1909                                 "setup_supplemental_field: "
1910                                 "failed to push package_PrimaryWDigestBlob: %s",
1911                                 nt_errstr(status));
1912                         return LDB_ERR_OPERATIONS_ERROR;
1913                 }
1914                 pdb_hexstr = data_blob_hex_string_upper(io->ac, &pdb_blob);
1915                 if (!pdb_hexstr) {
1916                         return ldb_oom(ldb);
1917                 }
1918                 pp->name        = "Primary:WDigest";
1919                 pp->reserved    = 1;
1920                 pp->data        = pdb_hexstr;
1921                 pp++;
1922                 num_packages++;
1923         }
1924
1925         /*
1926          * setup 'Primary:CLEARTEXT' element
1927          */
1928         if (io->ac->status->domain_data.store_cleartext &&
1929             (io->u.userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
1930                 do_cleartext = true;
1931         }
1932         if (do_cleartext) {
1933                 struct package_PrimaryCLEARTEXTBlob pcb;
1934                 DATA_BLOB pcb_blob;
1935                 char *pcb_hexstr;
1936
1937                 names[num_names++] = "CLEARTEXT";
1938
1939                 pcb.cleartext   = *io->n.cleartext_utf16;
1940
1941                 ndr_err = ndr_push_struct_blob(
1942                         &pcb_blob, io->ac,
1943                         &pcb,
1944                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryCLEARTEXTBlob);
1945                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1946                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1947                         ldb_asprintf_errstring(
1948                                 ldb,
1949                                 "setup_supplemental_field: "
1950                                 "failed to push package_PrimaryCLEARTEXTBlob: %s",
1951                                 nt_errstr(status));
1952                         return LDB_ERR_OPERATIONS_ERROR;
1953                 }
1954                 pcb_hexstr = data_blob_hex_string_upper(io->ac, &pcb_blob);
1955                 if (!pcb_hexstr) {
1956                         return ldb_oom(ldb);
1957                 }
1958                 pp->name        = "Primary:CLEARTEXT";
1959                 pp->reserved    = 1;
1960                 pp->data        = pcb_hexstr;
1961                 pp++;
1962                 num_packages++;
1963         }
1964
1965         if (io->ac->userPassword_schemes) {
1966                 /*
1967                  * setup 'Primary:userPassword' element
1968                  */
1969                 struct package_PrimaryUserPasswordBlob
1970                         p_userPassword_b;
1971                 DATA_BLOB p_userPassword_b_blob;
1972                 char *p_userPassword_b_hexstr;
1973
1974                 names[num_names++] = "userPassword";
1975
1976                 ret = setup_primary_userPassword(io,
1977                                                  old_scb,
1978                                                  &p_userPassword_b);
1979                 if (ret != LDB_SUCCESS) {
1980                         return ret;
1981                 }
1982
1983                 ndr_err = ndr_push_struct_blob(
1984                         &p_userPassword_b_blob,
1985                         io->ac,
1986                         &p_userPassword_b,
1987                         (ndr_push_flags_fn_t)
1988                         ndr_push_package_PrimaryUserPasswordBlob);
1989                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1990                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1991                         ldb_asprintf_errstring(
1992                                 ldb,
1993                                 "setup_supplemental_field: failed to push "
1994                                 "package_PrimaryUserPasswordBlob: %s",
1995                                 nt_errstr(status));
1996                         return LDB_ERR_OPERATIONS_ERROR;
1997                 }
1998                 p_userPassword_b_hexstr
1999                         = data_blob_hex_string_upper(
2000                                 io->ac,
2001                                 &p_userPassword_b_blob);
2002                 if (!p_userPassword_b_hexstr) {
2003                         return ldb_oom(ldb);
2004                 }
2005                 pp->name     = "Primary:userPassword";
2006                 pp->reserved = 1;
2007                 pp->data     = p_userPassword_b_hexstr;
2008                 pp++;
2009                 num_packages++;
2010         }
2011
2012         /*
2013          * setup 'Primary:SambaGPG' element
2014          */
2015         if (io->ac->gpg_key_ids != NULL) {
2016                 do_samba_gpg = true;
2017         }
2018         if (do_samba_gpg) {
2019                 struct package_PrimarySambaGPGBlob pgb;
2020                 DATA_BLOB pgb_blob;
2021                 char *pgb_hexstr;
2022
2023                 names[num_names++] = "SambaGPG";
2024
2025                 ret = setup_primary_samba_gpg(io, &pgb);
2026                 if (ret != LDB_SUCCESS) {
2027                         return ret;
2028                 }
2029
2030                 ndr_err = ndr_push_struct_blob(&pgb_blob, io->ac, &pgb,
2031                         (ndr_push_flags_fn_t)ndr_push_package_PrimarySambaGPGBlob);
2032                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2033                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2034                         ldb_asprintf_errstring(ldb,
2035                                         "setup_supplemental_field: failed to "
2036                                         "push package_PrimarySambaGPGBlob: %s",
2037                                         nt_errstr(status));
2038                         return LDB_ERR_OPERATIONS_ERROR;
2039                 }
2040                 pgb_hexstr = data_blob_hex_string_upper(io->ac, &pgb_blob);
2041                 if (!pgb_hexstr) {
2042                         return ldb_oom(ldb);
2043                 }
2044                 pp->name        = "Primary:SambaGPG";
2045                 pp->reserved    = 1;
2046                 pp->data        = pgb_hexstr;
2047                 pp++;
2048                 num_packages++;
2049         }
2050
2051         /*
2052          * setup 'Packages' element
2053          */
2054         {
2055                 struct package_PackagesBlob pb;
2056                 DATA_BLOB pb_blob;
2057                 char *pb_hexstr;
2058
2059                 pb.names = names;
2060                 ndr_err = ndr_push_struct_blob(
2061                         &pb_blob, io->ac,
2062                         &pb,
2063                         (ndr_push_flags_fn_t)ndr_push_package_PackagesBlob);
2064                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2065                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2066                         ldb_asprintf_errstring(
2067                                 ldb,
2068                                 "setup_supplemental_field: "
2069                                 "failed to push package_PackagesBlob: %s",
2070                                 nt_errstr(status));
2071                         return LDB_ERR_OPERATIONS_ERROR;
2072                 }
2073                 pb_hexstr = data_blob_hex_string_upper(io->ac, &pb_blob);
2074                 if (!pb_hexstr) {
2075                         return ldb_oom(ldb);
2076                 }
2077                 pp->name        = "Packages";
2078                 pp->reserved    = 2;
2079                 pp->data        = pb_hexstr;
2080                 num_packages++;
2081                 /*
2082                  * We don't increment pp so it's pointing to the last package
2083                  */
2084         }
2085
2086         /*
2087          * setup 'supplementalCredentials' value
2088          */
2089         {
2090                 /*
2091                  * The 'Packages' element needs to be the second last element
2092                  * in supplementalCredentials
2093                  */
2094                 struct supplementalCredentialsPackage temp;
2095                 struct supplementalCredentialsPackage *prev;
2096
2097                 prev = pp-1;
2098                 temp = *prev;
2099                 *prev = *pp;
2100                 *pp = temp;
2101
2102                 ZERO_STRUCT(scb);
2103                 scb.sub.signature       = SUPPLEMENTAL_CREDENTIALS_SIGNATURE;
2104                 scb.sub.num_packages    = num_packages;
2105                 scb.sub.packages        = packages;
2106
2107                 ndr_err = ndr_push_struct_blob(
2108                         &io->g.supplemental, io->ac,
2109                         &scb,
2110                         (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2111                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2112                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2113                         ldb_asprintf_errstring(
2114                                 ldb,
2115                                 "setup_supplemental_field: "
2116                                 "failed to push supplementalCredentialsBlob: %s",
2117                                 nt_errstr(status));
2118                         return LDB_ERR_OPERATIONS_ERROR;
2119                 }
2120         }
2121
2122         return LDB_SUCCESS;
2123 }
2124
2125 static int setup_last_set_field(struct setup_password_fields_io *io)
2126 {
2127         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2128         const struct ldb_message *msg = NULL;
2129         struct timeval tv = { .tv_sec = 0 };
2130         const struct ldb_val *old_val = NULL;
2131         const struct ldb_val *new_val = NULL;
2132         int ret;
2133
2134         switch (io->ac->req->operation) {
2135         case LDB_ADD:
2136                 msg = io->ac->req->op.add.message;
2137                 break;
2138         case LDB_MODIFY:
2139                 msg = io->ac->req->op.mod.message;
2140                 break;
2141         default:
2142                 return LDB_ERR_OPERATIONS_ERROR;
2143                 break;
2144         }
2145
2146         if (io->ac->pwd_last_set_bypass) {
2147                 struct ldb_message_element *el1 = NULL;
2148                 struct ldb_message_element *el2 = NULL;
2149
2150                 if (msg == NULL) {
2151                         return LDB_ERR_CONSTRAINT_VIOLATION;
2152                 }
2153
2154                 el1 = dsdb_get_single_valued_attr(msg, "pwdLastSet",
2155                                                   io->ac->req->operation);
2156                 if (el1 == NULL) {
2157                         return LDB_ERR_CONSTRAINT_VIOLATION;
2158                 }
2159                 el2 = ldb_msg_find_element(msg, "pwdLastSet");
2160                 if (el2 == NULL) {
2161                         return LDB_ERR_CONSTRAINT_VIOLATION;
2162                 }
2163                 if (el1 != el2) {
2164                         return LDB_ERR_CONSTRAINT_VIOLATION;
2165                 }
2166
2167                 io->g.last_set = samdb_result_nttime(msg, "pwdLastSet", 0);
2168                 return LDB_SUCCESS;
2169         }
2170
2171         ret = msg_find_old_and_new_pwd_val(msg, "pwdLastSet",
2172                                            io->ac->req->operation,
2173                                            &new_val, &old_val);
2174         if (ret != LDB_SUCCESS) {
2175                 return ret;
2176         }
2177
2178         if (old_val != NULL && new_val == NULL) {
2179                 ldb_set_errstring(ldb,
2180                                   "'pwdLastSet' deletion is not allowed!");
2181                 return LDB_ERR_UNWILLING_TO_PERFORM;
2182         }
2183
2184         io->g.last_set = UINT64_MAX;
2185         if (new_val != NULL) {
2186                 struct ldb_message *tmp_msg = NULL;
2187
2188                 tmp_msg = ldb_msg_new(io->ac);
2189                 if (tmp_msg == NULL) {
2190                         return ldb_module_oom(io->ac->module);
2191                 }
2192
2193                 if (old_val != NULL) {
2194                         NTTIME old_last_set = 0;
2195
2196                         ret = ldb_msg_add_value(tmp_msg, "oldval",
2197                                                 old_val, NULL);
2198                         if (ret != LDB_SUCCESS) {
2199                                 return ret;
2200                         }
2201
2202                         old_last_set = samdb_result_nttime(tmp_msg,
2203                                                            "oldval",
2204                                                            1);
2205                         if (io->u.pwdLastSet != old_last_set) {
2206                                 return dsdb_module_werror(io->ac->module,
2207                                         LDB_ERR_NO_SUCH_ATTRIBUTE,
2208                                         WERR_DS_CANT_REM_MISSING_ATT_VAL,
2209                                         "setup_last_set_field: old pwdLastSet "
2210                                         "value not found!");
2211                         }
2212                 }
2213
2214                 ret = ldb_msg_add_value(tmp_msg, "newval",
2215                                         new_val, NULL);
2216                 if (ret != LDB_SUCCESS) {
2217                         return ret;
2218                 }
2219
2220                 io->g.last_set = samdb_result_nttime(tmp_msg,
2221                                                      "newval",
2222                                                      1);
2223         } else if (ldb_msg_find_element(msg, "pwdLastSet")) {
2224                 ldb_set_errstring(ldb,
2225                                   "'pwdLastSet' deletion is not allowed!");
2226                 return LDB_ERR_UNWILLING_TO_PERFORM;
2227         } else if (io->ac->smartcard_reset) {
2228                 /*
2229                  * adding UF_SMARTCARD_REQUIRED doesn't update
2230                  * pwdLastSet implicitly.
2231                  */
2232                 io->ac->update_lastset = false;
2233         }
2234
2235         /* only 0 or -1 (0xFFFFFFFFFFFFFFFF) are allowed */
2236         switch (io->g.last_set) {
2237         case 0:
2238                 if (!io->ac->pwd_last_set_default) {
2239                         break;
2240                 }
2241                 if (!io->ac->update_password) {
2242                         break;
2243                 }
2244                 /* fall through */
2245         case UINT64_MAX:
2246                 if (!io->ac->update_password &&
2247                     io->u.pwdLastSet != 0 &&
2248                     io->u.pwdLastSet != UINT64_MAX)
2249                 {
2250                         /*
2251                          * Just setting pwdLastSet to -1, while not changing
2252                          * any password field has no effect if pwdLastSet
2253                          * is already non-zero.
2254                          */
2255                         io->ac->update_lastset = false;
2256                         break;
2257                 }
2258                 /* -1 means set it as now */
2259                 GetTimeOfDay(&tv);
2260                 io->g.last_set = timeval_to_nttime(&tv);
2261                 break;
2262         default:
2263                 return dsdb_module_werror(io->ac->module,
2264                                           LDB_ERR_OTHER,
2265                                           WERR_INVALID_PARAMETER,
2266                                           "setup_last_set_field: "
2267                                           "pwdLastSet must be 0 or -1 only!");
2268         }
2269
2270         if (io->ac->req->operation == LDB_ADD) {
2271                 /*
2272                  * We always need to store the value on add
2273                  * operations.
2274                  */
2275                 return LDB_SUCCESS;
2276         }
2277
2278         if (io->g.last_set == io->u.pwdLastSet) {
2279                 /*
2280                  * Just setting pwdLastSet to 0, is no-op if it's already 0.
2281                  */
2282                 io->ac->update_lastset = false;
2283         }
2284
2285         return LDB_SUCCESS;
2286 }
2287
2288 static int setup_given_passwords(struct setup_password_fields_io *io,
2289                                  struct setup_password_fields_given *g)
2290 {
2291         struct ldb_context *ldb;
2292         bool ok;
2293
2294         ldb = ldb_module_get_ctx(io->ac->module);
2295
2296         if (g->cleartext_utf8) {
2297                 struct ldb_val *cleartext_utf16_blob;
2298
2299                 cleartext_utf16_blob = talloc(io->ac, struct ldb_val);
2300                 if (!cleartext_utf16_blob) {
2301                         return ldb_oom(ldb);
2302                 }
2303                 if (!convert_string_talloc(io->ac,
2304                                            CH_UTF8, CH_UTF16,
2305                                            g->cleartext_utf8->data,
2306                                            g->cleartext_utf8->length,
2307                                            (void *)&cleartext_utf16_blob->data,
2308                                            &cleartext_utf16_blob->length)) {
2309                         if (g->cleartext_utf8->length != 0) {
2310                                 talloc_free(cleartext_utf16_blob);
2311                                 ldb_asprintf_errstring(ldb,
2312                                                        "setup_password_fields: "
2313                                                        "failed to generate UTF16 password from cleartext UTF8 one for user '%s'!",
2314                                                        io->u.sAMAccountName);
2315                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2316                         } else {
2317                                 /* passwords with length "0" are valid! */
2318                                 cleartext_utf16_blob->data = NULL;
2319                                 cleartext_utf16_blob->length = 0;
2320                         }
2321                 }
2322                 g->cleartext_utf16 = cleartext_utf16_blob;
2323         } else if (g->cleartext_utf16) {
2324                 struct ldb_val *cleartext_utf8_blob;
2325
2326                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
2327                 if (!cleartext_utf8_blob) {
2328                         return ldb_oom(ldb);
2329                 }
2330                 if (!convert_string_talloc(io->ac,
2331                                            CH_UTF16MUNGED, CH_UTF8,
2332                                            g->cleartext_utf16->data,
2333                                            g->cleartext_utf16->length,
2334                                            (void *)&cleartext_utf8_blob->data,
2335                                            &cleartext_utf8_blob->length)) {
2336                         if (g->cleartext_utf16->length != 0) {
2337                                 /* We must bail out here, the input wasn't even
2338                                  * a multiple of 2 bytes */
2339                                 talloc_free(cleartext_utf8_blob);
2340                                 ldb_asprintf_errstring(ldb,
2341                                                        "setup_password_fields: "
2342                                                        "failed to generate UTF8 password from cleartext UTF 16 one for user '%s' - the latter had odd length (length must be a multiple of 2)!",
2343                                                        io->u.sAMAccountName);
2344                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2345                         } else {
2346                                 /* passwords with length "0" are valid! */
2347                                 cleartext_utf8_blob->data = NULL;
2348                                 cleartext_utf8_blob->length = 0;
2349                         }
2350                 }
2351                 g->cleartext_utf8 = cleartext_utf8_blob;
2352         }
2353
2354         if (g->cleartext_utf16) {
2355                 struct samr_Password *nt_hash;
2356
2357                 nt_hash = talloc(io->ac, struct samr_Password);
2358                 if (!nt_hash) {
2359                         return ldb_oom(ldb);
2360                 }
2361                 g->nt_hash = nt_hash;
2362
2363                 /* compute the new nt hash */
2364                 mdfour(nt_hash->hash,
2365                        g->cleartext_utf16->data,
2366                        g->cleartext_utf16->length);
2367         }
2368
2369         if (g->cleartext_utf8) {
2370                 struct samr_Password *lm_hash;
2371
2372                 lm_hash = talloc(io->ac, struct samr_Password);
2373                 if (!lm_hash) {
2374                         return ldb_oom(ldb);
2375                 }
2376
2377                 /* compute the new lm hash */
2378                 ok = E_deshash((char *)g->cleartext_utf8->data, lm_hash->hash);
2379                 if (ok) {
2380                         g->lm_hash = lm_hash;
2381                 } else {
2382                         talloc_free(lm_hash);
2383                 }
2384         }
2385
2386         return LDB_SUCCESS;
2387 }
2388
2389 static int setup_password_fields(struct setup_password_fields_io *io)
2390 {
2391         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2392         struct loadparm_context *lp_ctx =
2393                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
2394                                          struct loadparm_context);
2395         int ret;
2396
2397         ret = setup_last_set_field(io);
2398         if (ret != LDB_SUCCESS) {
2399                 return ret;
2400         }
2401
2402         if (!io->ac->update_password) {
2403                 return LDB_SUCCESS;
2404         }
2405
2406         /* transform the old password (for password changes) */
2407         ret = setup_given_passwords(io, &io->og);
2408         if (ret != LDB_SUCCESS) {
2409                 return ret;
2410         }
2411
2412         /* transform the new password */
2413         ret = setup_given_passwords(io, &io->n);
2414         if (ret != LDB_SUCCESS) {
2415                 return ret;
2416         }
2417
2418         if (io->n.cleartext_utf8) {
2419                 ret = setup_kerberos_keys(io);
2420                 if (ret != LDB_SUCCESS) {
2421                         return ret;
2422                 }
2423         }
2424
2425         ret = setup_nt_fields(io);
2426         if (ret != LDB_SUCCESS) {
2427                 return ret;
2428         }
2429
2430         if (lpcfg_lanman_auth(lp_ctx)) {
2431                 ret = setup_lm_fields(io);
2432                 if (ret != LDB_SUCCESS) {
2433                         return ret;
2434                 }
2435         } else {
2436                 io->g.lm_hash = NULL;
2437                 io->g.lm_history_len = 0;
2438         }
2439
2440         ret = setup_supplemental_field(io);
2441         if (ret != LDB_SUCCESS) {
2442                 return ret;
2443         }
2444
2445         return LDB_SUCCESS;
2446 }
2447
2448 static int setup_smartcard_reset(struct setup_password_fields_io *io)
2449 {
2450         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2451         struct loadparm_context *lp_ctx = talloc_get_type(
2452                 ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
2453         struct supplementalCredentialsBlob scb = { .__ndr_size = 0 };
2454         enum ndr_err_code ndr_err;
2455
2456         if (!io->ac->smartcard_reset) {
2457                 return LDB_SUCCESS;
2458         }
2459
2460         io->g.nt_hash = talloc(io->ac, struct samr_Password);
2461         if (io->g.nt_hash == NULL) {
2462                 return ldb_module_oom(io->ac->module);
2463         }
2464         generate_secret_buffer(io->g.nt_hash->hash,
2465                                sizeof(io->g.nt_hash->hash));
2466         io->g.nt_history_len = 0;
2467
2468         if (lpcfg_lanman_auth(lp_ctx)) {
2469                 io->g.lm_hash = talloc(io->ac, struct samr_Password);
2470                 if (io->g.lm_hash == NULL) {
2471                         return ldb_module_oom(io->ac->module);
2472                 }
2473                 generate_secret_buffer(io->g.lm_hash->hash,
2474                                        sizeof(io->g.lm_hash->hash));
2475         } else {
2476                 io->g.lm_hash = NULL;
2477         }
2478         io->g.lm_history_len = 0;
2479
2480         /*
2481          * We take the "old" value and store it
2482          * with num_packages = 0.
2483          *
2484          * On "add" we have scb.sub.signature == 0, which
2485          * results in:
2486          *
2487          * [0000] 00 00 00 00 00 00 00 00   00 00 00 00 00
2488          *
2489          * On modify it's likely to be scb.sub.signature ==
2490          * SUPPLEMENTAL_CREDENTIALS_SIGNATURE (0x0050), which results in
2491          * something like:
2492          *
2493          * [0000] 00 00 00 00 62 00 00 00   00 00 00 00 20 00 20 00
2494          * [0010] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2495          * [0020] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2496          * [0030] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2497          * [0040] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2498          * [0050] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2499          * [0060] 20 00 20 00 20 00 20 00   20 00 20 00 50 00 00
2500          *
2501          * See https://bugzilla.samba.org/show_bug.cgi?id=11441
2502          * and ndr_{push,pull}_supplementalCredentialsSubBlob().
2503          */
2504         scb = io->o.scb;
2505         scb.sub.num_packages = 0;
2506
2507         /*
2508          * setup 'supplementalCredentials' value without packages
2509          */
2510         ndr_err = ndr_push_struct_blob(&io->g.supplemental, io->ac,
2511                                        &scb,
2512                                        (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2513         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2514                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2515                 ldb_asprintf_errstring(ldb,
2516                                        "setup_smartcard_reset: "
2517                                        "failed to push supplementalCredentialsBlob: %s",
2518                                        nt_errstr(status));
2519                 return LDB_ERR_OPERATIONS_ERROR;
2520         }
2521
2522         io->ac->update_password = true;
2523         return LDB_SUCCESS;
2524 }
2525
2526 static int make_error_and_update_badPwdCount(struct setup_password_fields_io *io, WERROR *werror)
2527 {
2528         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2529         struct ldb_message *mod_msg = NULL;
2530         NTSTATUS status;
2531         int ret;
2532
2533         status = dsdb_update_bad_pwd_count(io->ac, ldb,
2534                                            io->ac->search_res->message,
2535                                            io->ac->dom_res->message,
2536                                            &mod_msg);
2537         if (!NT_STATUS_IS_OK(status)) {
2538                 goto done;
2539         }
2540
2541         if (mod_msg == NULL) {
2542                 goto done;
2543         }
2544
2545         /*
2546          * OK, horrible semantics ahead.
2547          *
2548          * - We need to abort any existing transaction
2549          * - create a transaction arround the badPwdCount update
2550          * - re-open the transaction so the upper layer
2551          *   doesn't know what happened.
2552          *
2553          * This is needed because returning an error to the upper
2554          * layer will cancel the transaction and undo the badPwdCount
2555          * update.
2556          */
2557
2558         /*
2559          * Checking errors here is a bit pointless.
2560          * What can we do if we can't end the transaction?
2561          */
2562         ret = ldb_next_del_trans(io->ac->module);
2563         if (ret != LDB_SUCCESS) {
2564                 ldb_debug(ldb, LDB_DEBUG_FATAL,
2565                           "Failed to abort transaction prior to update of badPwdCount of %s: %s",
2566                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2567                           ldb_errstring(ldb));
2568                 /*
2569                  * just return the original error
2570                  */
2571                 goto done;
2572         }
2573
2574         /* Likewise, what should we do if we can't open a new transaction? */
2575         ret = ldb_next_start_trans(io->ac->module);
2576         if (ret != LDB_SUCCESS) {
2577                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2578                           "Failed to open transaction to update badPwdCount of %s: %s",
2579                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2580                           ldb_errstring(ldb));
2581                 /*
2582                  * just return the original error
2583                  */
2584                 goto done;
2585         }
2586
2587         ret = dsdb_module_modify(io->ac->module, mod_msg,
2588                                  DSDB_FLAG_NEXT_MODULE,
2589                                  io->ac->req);
2590         if (ret != LDB_SUCCESS) {
2591                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2592                           "Failed to update badPwdCount of %s: %s",
2593                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2594                           ldb_errstring(ldb));
2595                 /*
2596                  * We can only ignore this...
2597                  */
2598         }
2599
2600         ret = ldb_next_end_trans(io->ac->module);
2601         if (ret != LDB_SUCCESS) {
2602                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2603                           "Failed to close transaction to update badPwdCount of %s: %s",
2604                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2605                           ldb_errstring(ldb));
2606                 /*
2607                  * We can only ignore this...
2608                  */
2609         }
2610
2611         ret = ldb_next_start_trans(io->ac->module);
2612         if (ret != LDB_SUCCESS) {
2613                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2614                           "Failed to open transaction after update of badPwdCount of %s: %s",
2615                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2616                           ldb_errstring(ldb));
2617                 /*
2618                  * We can only ignore this...
2619                  */
2620         }
2621
2622 done:
2623         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2624         *werror = WERR_INVALID_PASSWORD;
2625         ldb_asprintf_errstring(ldb,
2626                                "%08X: %s - check_password_restrictions: "
2627                                "The old password specified doesn't match!",
2628                                W_ERROR_V(*werror),
2629                                ldb_strerror(ret));
2630         return ret;
2631 }
2632
2633 static int check_password_restrictions(struct setup_password_fields_io *io, WERROR *werror)
2634 {
2635         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2636         int ret;
2637         struct loadparm_context *lp_ctx =
2638                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
2639                                          struct loadparm_context);
2640
2641         *werror = WERR_INVALID_PARAMETER;
2642
2643         if (!io->ac->update_password) {
2644                 return LDB_SUCCESS;
2645         }
2646
2647         /* First check the old password is correct, for password changes */
2648         if (!io->ac->pwd_reset) {
2649                 bool nt_hash_checked = false;
2650
2651                 /* we need the old nt or lm hash given by the client */
2652                 if (!io->og.nt_hash && !io->og.lm_hash) {
2653                         ldb_asprintf_errstring(ldb,
2654                                 "check_password_restrictions: "
2655                                 "You need to provide the old password in order "
2656                                 "to change it!");
2657                         return LDB_ERR_UNWILLING_TO_PERFORM;
2658                 }
2659
2660                 /* The password modify through the NT hash is encouraged and
2661                    has no problems at all */
2662                 if (io->og.nt_hash) {
2663                         if (!io->o.nt_hash || memcmp(io->og.nt_hash->hash, io->o.nt_hash->hash, 16) != 0) {
2664                                 return make_error_and_update_badPwdCount(io, werror);
2665                         }
2666
2667                         nt_hash_checked = true;
2668                 }
2669
2670                 /* But it is also possible to change a password by the LM hash
2671                  * alone for compatibility reasons. This check is optional if
2672                  * the NT hash was already checked - otherwise it's mandatory.
2673                  * (as the SAMR operations request it). */
2674                 if (io->og.lm_hash) {
2675                         if ((!io->o.lm_hash && !nt_hash_checked)
2676                             || (io->o.lm_hash && memcmp(io->og.lm_hash->hash, io->o.lm_hash->hash, 16) != 0)) {
2677                                 return make_error_and_update_badPwdCount(io, werror);
2678                         }
2679                 }
2680         }
2681
2682         if (io->u.restrictions == 0) {
2683                 /* FIXME: Is this right? */
2684                 return LDB_SUCCESS;
2685         }
2686
2687         /* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */
2688         if ((io->u.pwdLastSet - io->ac->status->domain_data.minPwdAge > io->g.last_set) &&
2689             !io->ac->pwd_reset)
2690         {
2691                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2692                 *werror = WERR_PASSWORD_RESTRICTION;
2693                 ldb_asprintf_errstring(ldb,
2694                         "%08X: %s - check_password_restrictions: "
2695                         "password is too young to change!",
2696                         W_ERROR_V(*werror),
2697                         ldb_strerror(ret));
2698                 return ret;
2699         }
2700
2701         /*
2702          * Fundamental password checks done by the call
2703          * "samdb_check_password".
2704          * It is also in use by "dcesrv_samr_ValidatePassword".
2705          */
2706         if (io->n.cleartext_utf8 != NULL) {
2707                 enum samr_ValidationStatus vstat;
2708                 vstat = samdb_check_password(io->ac, lp_ctx,
2709                                              io->n.cleartext_utf8,
2710                                              io->ac->status->domain_data.pwdProperties,
2711                                              io->ac->status->domain_data.minPwdLength);
2712                 switch (vstat) {
2713                 case SAMR_VALIDATION_STATUS_SUCCESS:
2714                                 /* perfect -> proceed! */
2715                         break;
2716
2717                 case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT:
2718                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2719                         *werror = WERR_PASSWORD_RESTRICTION;
2720                         ldb_asprintf_errstring(ldb,
2721                                 "%08X: %s - check_password_restrictions: "
2722                                 "the password is too short. It should be equal or longer than %u characters!",
2723                                 W_ERROR_V(*werror),
2724                                 ldb_strerror(ret),
2725                                 io->ac->status->domain_data.minPwdLength);
2726                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PASSWORD_TOO_SHORT;
2727                         return ret;
2728
2729                 case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH:
2730                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2731                         *werror = WERR_PASSWORD_RESTRICTION;
2732                         ldb_asprintf_errstring(ldb,
2733                                 "%08X: %s - check_password_restrictions: "
2734                                 "the password does not meet the complexity criteria!",
2735                                 W_ERROR_V(*werror),
2736                                 ldb_strerror(ret));
2737                         io->ac->status->reject_reason = SAM_PWD_CHANGE_NOT_COMPLEX;
2738                         return ret;
2739
2740                 default:
2741                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2742                         *werror = WERR_PASSWORD_RESTRICTION;
2743                         ldb_asprintf_errstring(ldb,
2744                                 "%08X: %s - check_password_restrictions: "
2745                                 "the password doesn't fit due to a miscellaneous restriction!",
2746                                 W_ERROR_V(*werror),
2747                                 ldb_strerror(ret));
2748                         return ret;
2749                 }
2750         }
2751
2752         if (io->ac->pwd_reset) {
2753                 *werror = WERR_OK;
2754                 return LDB_SUCCESS;
2755         }
2756
2757         if (io->n.nt_hash) {
2758                 uint32_t i;
2759
2760                 /* checks the NT hash password history */
2761                 for (i = 0; i < io->o.nt_history_len; i++) {
2762                         ret = memcmp(io->n.nt_hash, io->o.nt_history[i].hash, 16);
2763                         if (ret == 0) {
2764                                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2765                                 *werror = WERR_PASSWORD_RESTRICTION;
2766                                 ldb_asprintf_errstring(ldb,
2767                                         "%08X: %s - check_password_restrictions: "
2768                                         "the password was already used (in history)!",
2769                                         W_ERROR_V(*werror),
2770                                         ldb_strerror(ret));
2771                                 io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
2772                                 return ret;
2773                         }
2774                 }
2775         }
2776
2777         if (io->n.lm_hash) {
2778                 uint32_t i;
2779
2780                 /* checks the LM hash password history */
2781                 for (i = 0; i < io->o.lm_history_len; i++) {
2782                         ret = memcmp(io->n.lm_hash, io->o.lm_history[i].hash, 16);
2783                         if (ret == 0) {
2784                                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2785                                 *werror = WERR_PASSWORD_RESTRICTION;
2786                                 ldb_asprintf_errstring(ldb,
2787                                         "%08X: %s - check_password_restrictions: "
2788                                         "the password was already used (in history)!",
2789                                         W_ERROR_V(*werror),
2790                                         ldb_strerror(ret));
2791                                 io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
2792                                 return ret;
2793                         }
2794                 }
2795         }
2796
2797         /* are all password changes disallowed? */
2798         if (io->ac->status->domain_data.pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
2799                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2800                 *werror = WERR_PASSWORD_RESTRICTION;
2801                 ldb_asprintf_errstring(ldb,
2802                         "%08X: %s - check_password_restrictions: "
2803                         "password changes disabled!",
2804                         W_ERROR_V(*werror),
2805                         ldb_strerror(ret));
2806                 return ret;
2807         }
2808
2809         /* can this user change the password? */
2810         if (io->u.userAccountControl & UF_PASSWD_CANT_CHANGE) {
2811                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2812                 *werror = WERR_PASSWORD_RESTRICTION;
2813                 ldb_asprintf_errstring(ldb,
2814                         "%08X: %s - check_password_restrictions: "
2815                         "password can't be changed on this account!",
2816                         W_ERROR_V(*werror),
2817                         ldb_strerror(ret));
2818                 return ret;
2819         }
2820
2821         return LDB_SUCCESS;
2822 }
2823
2824 static int check_password_restrictions_and_log(struct setup_password_fields_io *io)
2825 {
2826         WERROR werror;
2827         int ret = check_password_restrictions(io, &werror);
2828         struct ph_context *ac = io->ac;
2829         /*
2830          * Password resets are not authentication events, and if the
2831          * upper layer checked the password and supplied the hash
2832          * values as proof, then this is also not an authentication
2833          * even at this layer (already logged).  This is to log LDAP
2834          * password changes.
2835          */
2836
2837         /* Do not record a failure in the auth log below in the success case */
2838         if (ret == LDB_SUCCESS) {
2839                 werror = WERR_OK;
2840         }
2841
2842         if (ac->pwd_reset == false && ac->change == NULL) {
2843                 struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
2844                 struct imessaging_context *msg_ctx;
2845                 struct loadparm_context *lp_ctx
2846                         = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
2847                                                 struct loadparm_context);
2848                 NTSTATUS status = werror_to_ntstatus(werror);
2849                 const char *domain_name = lpcfg_sam_name(lp_ctx);
2850                 void *opaque_remote_address = NULL;
2851                 /*
2852                  * Forcing this via the NTLM auth structure is not ideal, but
2853                  * it is the most practical option right now, and ensures the
2854                  * logs are consistent, even if some elements are always NULL.
2855                  */
2856                 struct auth_usersupplied_info ui = {
2857                         .mapped_state = true,
2858                         .was_mapped = true,
2859                         .client = {
2860                                 .account_name = io->u.sAMAccountName,
2861                                 .domain_name = domain_name,
2862                         },
2863                         .mapped = {
2864                                 .account_name = io->u.sAMAccountName,
2865                                 .domain_name = domain_name,
2866                         },
2867                         .service_description = "LDAP Password Change",
2868                         .auth_description = "LDAP Modify",
2869                         .password_type = "plaintext"
2870                 };
2871
2872                 opaque_remote_address = ldb_get_opaque(ldb,
2873                                                        "remoteAddress");
2874                 if (opaque_remote_address == NULL) {
2875                         ldb_asprintf_errstring(ldb,
2876                                                "Failed to obtain remote address for "
2877                                                "the LDAP client while changing the "
2878                                                "password");
2879                         return LDB_ERR_OPERATIONS_ERROR;
2880                 }
2881                 ui.remote_host = talloc_get_type(opaque_remote_address,
2882                                                  struct tsocket_address);
2883
2884                 msg_ctx = imessaging_client_init(ac, lp_ctx,
2885                                                  ldb_get_event_context(ldb));
2886                 if (!msg_ctx) {
2887                         ldb_asprintf_errstring(ldb,
2888                                                "Failed to generate client messaging context in %s",
2889                                                lpcfg_imessaging_path(ac, lp_ctx));
2890                         return LDB_ERR_OPERATIONS_ERROR;
2891                 }
2892                 log_authentication_event(msg_ctx,
2893                                          lp_ctx,
2894                                          &ui,
2895                                          status,
2896                                          domain_name,
2897                                          io->u.sAMAccountName,
2898                                          NULL,
2899                                          io->u.account_sid);
2900
2901         }
2902         return ret;
2903 }
2904
2905 static int update_final_msg(struct setup_password_fields_io *io)
2906 {
2907         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2908         int ret;
2909         int el_flags = 0;
2910         bool update_password = io->ac->update_password;
2911         bool update_scb = io->ac->update_password;
2912
2913         /*
2914          * If we add a user without initial password,
2915          * we need to add replication meta data for
2916          * following attributes:
2917          * - unicodePwd
2918          * - dBCSPwd
2919          * - ntPwdHistory
2920          * - lmPwdHistory
2921          *
2922          * If we add a user with initial password or a
2923          * password is changed of an existing user,
2924          * we need to replace the following attributes
2925          * with a forced meta data update, e.g. also
2926          * when updating an empty attribute with an empty value:
2927          * - unicodePwd
2928          * - dBCSPwd
2929          * - ntPwdHistory
2930          * - lmPwdHistory
2931          * - supplementalCredentials
2932          */
2933
2934         switch (io->ac->req->operation) {
2935         case LDB_ADD:
2936                 update_password = true;
2937                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
2938                 break;
2939         case LDB_MODIFY:
2940                 el_flags |= LDB_FLAG_MOD_REPLACE;
2941                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
2942                 break;
2943         default:
2944                 return ldb_module_operr(io->ac->module);
2945         }
2946
2947         if (update_password) {
2948                 ret = ldb_msg_add_empty(io->ac->update_msg,
2949                                         "unicodePwd",
2950                                         el_flags, NULL);
2951                 if (ret != LDB_SUCCESS) {
2952                         return ret;
2953                 }
2954                 ret = ldb_msg_add_empty(io->ac->update_msg,
2955                                         "dBCSPwd",
2956                                         el_flags, NULL);
2957                 if (ret != LDB_SUCCESS) {
2958                         return ret;
2959                 }
2960                 ret = ldb_msg_add_empty(io->ac->update_msg,
2961                                         "ntPwdHistory",
2962                                         el_flags, NULL);
2963                 if (ret != LDB_SUCCESS) {
2964                         return ret;
2965                 }
2966                 ret = ldb_msg_add_empty(io->ac->update_msg,
2967                                         "lmPwdHistory",
2968                                         el_flags, NULL);
2969                 if (ret != LDB_SUCCESS) {
2970                         return ret;
2971                 }
2972         }
2973         if (update_scb) {
2974                 ret = ldb_msg_add_empty(io->ac->update_msg,
2975                                         "supplementalCredentials",
2976                                         el_flags, NULL);
2977                 if (ret != LDB_SUCCESS) {
2978                         return ret;
2979                 }
2980         }
2981         if (io->ac->update_lastset) {
2982                 ret = ldb_msg_add_empty(io->ac->update_msg,
2983                                         "pwdLastSet",
2984                                         el_flags, NULL);
2985                 if (ret != LDB_SUCCESS) {
2986                         return ret;
2987                 }
2988         }
2989
2990         if (io->g.nt_hash != NULL) {
2991                 ret = samdb_msg_add_hash(ldb, io->ac,
2992