password_hash: generate and store Primary:userPassword
[metze/samba/wip.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         krb5_principal salt_principal;
675         krb5_data salt;
676         krb5_keyblock key;
677         krb5_data cleartext_data;
678
679         ldb = ldb_module_get_ctx(io->ac->module);
680         cleartext_data.data = (char *)io->n.cleartext_utf8->data;
681         cleartext_data.length = io->n.cleartext_utf8->length;
682
683         /* Many, many thanks to lukeh@padl.com for this
684          * algorithm, described in his Nov 10 2004 mail to
685          * samba-technical@lists.samba.org */
686
687         /*
688          * Determine a salting principal
689          */
690         if (io->u.is_computer) {
691                 char *name;
692                 char *saltbody;
693
694                 name = strlower_talloc(io->ac, io->u.sAMAccountName);
695                 if (!name) {
696                         return ldb_oom(ldb);
697                 }
698
699                 if (name[strlen(name)-1] == '$') {
700                         name[strlen(name)-1] = '\0';
701                 }
702
703                 saltbody = talloc_asprintf(io->ac, "%s.%s", name,
704                                            io->ac->status->domain_data.dns_domain);
705                 if (!saltbody) {
706                         return ldb_oom(ldb);
707                 }
708                 
709                 krb5_ret = smb_krb5_make_principal(io->smb_krb5_context->krb5_context,
710                                                &salt_principal,
711                                                io->ac->status->domain_data.realm,
712                                                "host", saltbody, NULL);
713         } else if (io->u.user_principal_name) {
714                 char *user_principal_name;
715                 char *p;
716
717                 user_principal_name = talloc_strdup(io->ac, io->u.user_principal_name);
718                 if (!user_principal_name) {
719                         return ldb_oom(ldb);
720                 }
721
722                 p = strchr(user_principal_name, '@');
723                 if (p) {
724                         p[0] = '\0';
725                 }
726
727                 krb5_ret = smb_krb5_make_principal(io->smb_krb5_context->krb5_context,
728                                                &salt_principal,
729                                                io->ac->status->domain_data.realm,
730                                                user_principal_name, NULL);
731         } else {
732                 krb5_ret = smb_krb5_make_principal(io->smb_krb5_context->krb5_context,
733                                                &salt_principal,
734                                                io->ac->status->domain_data.realm,
735                                                io->u.sAMAccountName, NULL);
736         }
737         if (krb5_ret) {
738                 ldb_asprintf_errstring(ldb,
739                                        "setup_kerberos_keys: "
740                                        "generation of a salting principal failed: %s",
741                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
742                                                                   krb5_ret, io->ac));
743                 return LDB_ERR_OPERATIONS_ERROR;
744         }
745
746         /*
747          * create salt from salt_principal
748          */
749         krb5_ret = smb_krb5_get_pw_salt(io->smb_krb5_context->krb5_context,
750                                     salt_principal, &salt);
751         krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
752         if (krb5_ret) {
753                 ldb_asprintf_errstring(ldb,
754                                        "setup_kerberos_keys: "
755                                        "generation of krb5_salt failed: %s",
756                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
757                                                                   krb5_ret, io->ac));
758                 return LDB_ERR_OPERATIONS_ERROR;
759         }
760         /* create a talloc copy */
761         io->g.salt = talloc_strndup(io->ac,
762                                     (char *)salt.data,
763                                     salt.length);
764         smb_krb5_free_data_contents(io->smb_krb5_context->krb5_context, &salt);
765         if (!io->g.salt) {
766                 return ldb_oom(ldb);
767         }
768         /* now use the talloced copy of the salt */
769         salt.data       = discard_const(io->g.salt);
770         salt.length     = strlen(io->g.salt);
771
772         /*
773          * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
774          * the salt and the cleartext password
775          */
776         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
777                                                    NULL,
778                                                    &salt,
779                                                    &cleartext_data,
780                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
781                                                    &key);
782         if (krb5_ret) {
783                 ldb_asprintf_errstring(ldb,
784                                        "setup_kerberos_keys: "
785                                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
786                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
787                                                                   krb5_ret, io->ac));
788                 return LDB_ERR_OPERATIONS_ERROR;
789         }
790         io->g.aes_256 = data_blob_talloc(io->ac,
791                                          KRB5_KEY_DATA(&key),
792                                          KRB5_KEY_LENGTH(&key));
793         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
794         if (!io->g.aes_256.data) {
795                 return ldb_oom(ldb);
796         }
797
798         /*
799          * create ENCTYPE_AES128_CTS_HMAC_SHA1_96 key out of
800          * the salt and the cleartext password
801          */
802         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
803                                                    NULL,
804                                                    &salt,
805                                                    &cleartext_data,
806                                                    ENCTYPE_AES128_CTS_HMAC_SHA1_96,
807                                                    &key);
808         if (krb5_ret) {
809                 ldb_asprintf_errstring(ldb,
810                                        "setup_kerberos_keys: "
811                                        "generation of a aes128-cts-hmac-sha1-96 key failed: %s",
812                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
813                                                                   krb5_ret, io->ac));
814                 return LDB_ERR_OPERATIONS_ERROR;
815         }
816         io->g.aes_128 = data_blob_talloc(io->ac,
817                                          KRB5_KEY_DATA(&key),
818                                          KRB5_KEY_LENGTH(&key));
819         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
820         if (!io->g.aes_128.data) {
821                 return ldb_oom(ldb);
822         }
823
824         /*
825          * create ENCTYPE_DES_CBC_MD5 key out of
826          * the salt and the cleartext password
827          */
828         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
829                                                    NULL,
830                                                    &salt,
831                                                    &cleartext_data,
832                                                    ENCTYPE_DES_CBC_MD5,
833                                                    &key);
834         if (krb5_ret) {
835                 ldb_asprintf_errstring(ldb,
836                                        "setup_kerberos_keys: "
837                                        "generation of a des-cbc-md5 key failed: %s",
838                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
839                                                                   krb5_ret, io->ac));
840                 return LDB_ERR_OPERATIONS_ERROR;
841         }
842         io->g.des_md5 = data_blob_talloc(io->ac,
843                                          KRB5_KEY_DATA(&key),
844                                          KRB5_KEY_LENGTH(&key));
845         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
846         if (!io->g.des_md5.data) {
847                 return ldb_oom(ldb);
848         }
849
850         /*
851          * create ENCTYPE_DES_CBC_CRC key out of
852          * the salt and the cleartext password
853          */
854         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
855                                                    NULL,
856                                                    &salt,
857                                                    &cleartext_data,
858                                                    ENCTYPE_DES_CBC_CRC,
859                                                    &key);
860         if (krb5_ret) {
861                 ldb_asprintf_errstring(ldb,
862                                        "setup_kerberos_keys: "
863                                        "generation of a des-cbc-crc key failed: %s",
864                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
865                                                                   krb5_ret, io->ac));
866                 return LDB_ERR_OPERATIONS_ERROR;
867         }
868         io->g.des_crc = data_blob_talloc(io->ac,
869                                          KRB5_KEY_DATA(&key),
870                                          KRB5_KEY_LENGTH(&key));
871         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
872         if (!io->g.des_crc.data) {
873                 return ldb_oom(ldb);
874         }
875
876         return LDB_SUCCESS;
877 }
878
879 static int setup_primary_kerberos(struct setup_password_fields_io *io,
880                                   const struct supplementalCredentialsBlob *old_scb,
881                                   struct package_PrimaryKerberosBlob *pkb)
882 {
883         struct ldb_context *ldb;
884         struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
885         struct supplementalCredentialsPackage *old_scp = NULL;
886         struct package_PrimaryKerberosBlob _old_pkb;
887         struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
888         uint32_t i;
889         enum ndr_err_code ndr_err;
890
891         ldb = ldb_module_get_ctx(io->ac->module);
892
893         /*
894          * prepare generation of keys
895          *
896          * ENCTYPE_DES_CBC_MD5
897          * ENCTYPE_DES_CBC_CRC
898          */
899         pkb->version            = 3;
900         pkb3->salt.string       = io->g.salt;
901         pkb3->num_keys          = 2;
902         pkb3->keys              = talloc_array(io->ac,
903                                                struct package_PrimaryKerberosKey3,
904                                                pkb3->num_keys);
905         if (!pkb3->keys) {
906                 return ldb_oom(ldb);
907         }
908
909         pkb3->keys[0].keytype   = ENCTYPE_DES_CBC_MD5;
910         pkb3->keys[0].value     = &io->g.des_md5;
911         pkb3->keys[1].keytype   = ENCTYPE_DES_CBC_CRC;
912         pkb3->keys[1].value     = &io->g.des_crc;
913
914         /* initialize the old keys to zero */
915         pkb3->num_old_keys      = 0;
916         pkb3->old_keys          = NULL;
917
918         /* if there're no old keys, then we're done */
919         if (!old_scb) {
920                 return LDB_SUCCESS;
921         }
922
923         for (i=0; i < old_scb->sub.num_packages; i++) {
924                 if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
925                         continue;
926                 }
927
928                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
929                         continue;
930                 }
931
932                 old_scp = &old_scb->sub.packages[i];
933                 break;
934         }
935         /* Primary:Kerberos element of supplementalCredentials */
936         if (old_scp) {
937                 DATA_BLOB blob;
938
939                 blob = strhex_to_data_blob(io->ac, old_scp->data);
940                 if (!blob.data) {
941                         return ldb_oom(ldb);
942                 }
943
944                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
945                 ndr_err = ndr_pull_struct_blob(&blob, io->ac, &_old_pkb,
946                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
947                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
948                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
949                         ldb_asprintf_errstring(ldb,
950                                                "setup_primary_kerberos: "
951                                                "failed to pull old package_PrimaryKerberosBlob: %s",
952                                                nt_errstr(status));
953                         return LDB_ERR_OPERATIONS_ERROR;
954                 }
955
956                 if (_old_pkb.version != 3) {
957                         ldb_asprintf_errstring(ldb,
958                                                "setup_primary_kerberos: "
959                                                "package_PrimaryKerberosBlob version[%u] expected[3]",
960                                                _old_pkb.version);
961                         return LDB_ERR_OPERATIONS_ERROR;
962                 }
963
964                 old_pkb3 = &_old_pkb.ctr.ctr3;
965         }
966
967         /* if we didn't found the old keys we're done */
968         if (!old_pkb3) {
969                 return LDB_SUCCESS;
970         }
971
972         /* fill in the old keys */
973         pkb3->num_old_keys      = old_pkb3->num_keys;
974         pkb3->old_keys          = old_pkb3->keys;
975
976         return LDB_SUCCESS;
977 }
978
979 static int setup_primary_kerberos_newer(struct setup_password_fields_io *io,
980                                         const struct supplementalCredentialsBlob *old_scb,
981                                         struct package_PrimaryKerberosBlob *pkb)
982 {
983         struct ldb_context *ldb;
984         struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4;
985         struct supplementalCredentialsPackage *old_scp = NULL;
986         struct package_PrimaryKerberosBlob _old_pkb;
987         struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL;
988         uint32_t i;
989         enum ndr_err_code ndr_err;
990
991         ldb = ldb_module_get_ctx(io->ac->module);
992
993         /*
994          * prepare generation of keys
995          *
996          * ENCTYPE_AES256_CTS_HMAC_SHA1_96
997          * ENCTYPE_AES128_CTS_HMAC_SHA1_96
998          * ENCTYPE_DES_CBC_MD5
999          * ENCTYPE_DES_CBC_CRC
1000          */
1001         pkb->version                    = 4;
1002         pkb4->salt.string               = io->g.salt;
1003         pkb4->default_iteration_count   = 4096;
1004         pkb4->num_keys                  = 4;
1005
1006         pkb4->keys = talloc_array(io->ac,
1007                                   struct package_PrimaryKerberosKey4,
1008                                   pkb4->num_keys);
1009         if (!pkb4->keys) {
1010                 return ldb_oom(ldb);
1011         }
1012
1013         pkb4->keys[0].iteration_count   = 4096;
1014         pkb4->keys[0].keytype           = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1015         pkb4->keys[0].value             = &io->g.aes_256;
1016         pkb4->keys[1].iteration_count   = 4096;
1017         pkb4->keys[1].keytype           = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1018         pkb4->keys[1].value             = &io->g.aes_128;
1019         pkb4->keys[2].iteration_count   = 4096;
1020         pkb4->keys[2].keytype           = ENCTYPE_DES_CBC_MD5;
1021         pkb4->keys[2].value             = &io->g.des_md5;
1022         pkb4->keys[3].iteration_count   = 4096;
1023         pkb4->keys[3].keytype           = ENCTYPE_DES_CBC_CRC;
1024         pkb4->keys[3].value             = &io->g.des_crc;
1025
1026         /* initialize the old keys to zero */
1027         pkb4->num_old_keys      = 0;
1028         pkb4->old_keys          = NULL;
1029         pkb4->num_older_keys    = 0;
1030         pkb4->older_keys        = NULL;
1031
1032         /* if there're no old keys, then we're done */
1033         if (!old_scb) {
1034                 return LDB_SUCCESS;
1035         }
1036
1037         for (i=0; i < old_scb->sub.num_packages; i++) {
1038                 if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) {
1039                         continue;
1040                 }
1041
1042                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
1043                         continue;
1044                 }
1045
1046                 old_scp = &old_scb->sub.packages[i];
1047                 break;
1048         }
1049         /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
1050         if (old_scp) {
1051                 DATA_BLOB blob;
1052
1053                 blob = strhex_to_data_blob(io->ac, old_scp->data);
1054                 if (!blob.data) {
1055                         return ldb_oom(ldb);
1056                 }
1057
1058                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
1059                 ndr_err = ndr_pull_struct_blob(&blob, io->ac,
1060                                                &_old_pkb,
1061                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
1062                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1063                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1064                         ldb_asprintf_errstring(ldb,
1065                                                "setup_primary_kerberos_newer: "
1066                                                "failed to pull old package_PrimaryKerberosBlob: %s",
1067                                                nt_errstr(status));
1068                         return LDB_ERR_OPERATIONS_ERROR;
1069                 }
1070
1071                 if (_old_pkb.version != 4) {
1072                         ldb_asprintf_errstring(ldb,
1073                                                "setup_primary_kerberos_newer: "
1074                                                "package_PrimaryKerberosBlob version[%u] expected[4]",
1075                                                _old_pkb.version);
1076                         return LDB_ERR_OPERATIONS_ERROR;
1077                 }
1078
1079                 old_pkb4 = &_old_pkb.ctr.ctr4;
1080         }
1081
1082         /* if we didn't found the old keys we're done */
1083         if (!old_pkb4) {
1084                 return LDB_SUCCESS;
1085         }
1086
1087         /* fill in the old keys */
1088         pkb4->num_old_keys      = old_pkb4->num_keys;
1089         pkb4->old_keys          = old_pkb4->keys;
1090         pkb4->num_older_keys    = old_pkb4->num_old_keys;
1091         pkb4->older_keys        = old_pkb4->old_keys;
1092
1093         return LDB_SUCCESS;
1094 }
1095
1096 static int setup_primary_wdigest(struct setup_password_fields_io *io,
1097                                  const struct supplementalCredentialsBlob *old_scb,
1098                                  struct package_PrimaryWDigestBlob *pdb)
1099 {
1100         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1101         DATA_BLOB sAMAccountName;
1102         DATA_BLOB sAMAccountName_l;
1103         DATA_BLOB sAMAccountName_u;
1104         const char *user_principal_name = io->u.user_principal_name;
1105         DATA_BLOB userPrincipalName;
1106         DATA_BLOB userPrincipalName_l;
1107         DATA_BLOB userPrincipalName_u;
1108         DATA_BLOB netbios_domain;
1109         DATA_BLOB netbios_domain_l;
1110         DATA_BLOB netbios_domain_u;
1111         DATA_BLOB dns_domain;
1112         DATA_BLOB dns_domain_l;
1113         DATA_BLOB dns_domain_u;
1114         DATA_BLOB digest;
1115         DATA_BLOB delim;
1116         DATA_BLOB backslash;
1117         uint8_t i;
1118         struct {
1119                 DATA_BLOB *user;
1120                 DATA_BLOB *realm;
1121                 DATA_BLOB *nt4dom;
1122         } wdigest[] = {
1123         /*
1124          * See 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction
1125          *     https://msdn.microsoft.com/en-us/library/cc245680.aspx
1126          * for what precalculated hashes are supposed to be stored...
1127          *
1128          * I can't reproduce all values which should contain "Digest" as realm,
1129          * am I doing something wrong or is w2k3 just broken...?
1130          *
1131          * W2K3 fills in following for a user:
1132          *
1133          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1134          * sAMAccountName: NewUser2Sam
1135          * userPrincipalName: NewUser2Princ@sub1.w2k3.vmnet1.vm.base
1136          *
1137          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1138          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1139          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1140          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1141          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1142          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1143          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1144          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1145          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1146          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1147          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1148          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1149          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1150          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1151          * 221c55284451ae9b3aacaa2a3c86f10f => NewUser2Princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1152          * 74e1be668853d4324d38c07e2acfb8ea => (w2k3 has a bug here!) newuser2princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1153          * e1e244ab7f098e3ae1761be7f9229bbb => NEWUSER2PRINC@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1154          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1155          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1156          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1157          * 31dc704d3640335b2123d4ee28aa1f11 => ??? changes with NewUser2Sam => NewUser1Sam
1158          * 36349f5cecd07320fb3bb0e119230c43 => ??? changes with NewUser2Sam => NewUser1Sam
1159          * 12adf019d037fb535c01fd0608e78d9d => ??? changes with NewUser2Sam => NewUser1Sam
1160          * 6feecf8e724906f3ee1105819c5105a1 => ??? changes with NewUser2Princ => NewUser1Princ
1161          * 6c6911f3de6333422640221b9c51ff1f => ??? changes with NewUser2Princ => NewUser1Princ
1162          * 4b279877e742895f9348ac67a8de2f69 => ??? changes with NewUser2Princ => NewUser1Princ
1163          * db0c6bff069513e3ebb9870d29b57490 => ??? changes with NewUser2Sam => NewUser1Sam
1164          * 45072621e56b1c113a4e04a8ff68cd0e => ??? changes with NewUser2Sam => NewUser1Sam
1165          * 11d1220abc44a9c10cf91ef4a9c1de02 => ??? changes with NewUser2Sam => NewUser1Sam
1166          *
1167          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1168          * sAMAccountName: NewUser2Sam
1169          *
1170          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1171          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1172          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1173          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1174          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1175          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1176          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1177          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1178          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1179          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1180          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1181          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1182          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1183          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1184          * 8a140d30b6f0a5912735dc1e3bc993b4 => NewUser2Sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1185          * 86d95b2faae6cae4ec261e7fbaccf093 => (here w2k3 is correct) newuser2sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1186          * dfeff1493110220efcdfc6362e5f5450 => NEWUSER2SAM@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1187          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1188          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1189          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1190          * 31dc704d3640335b2123d4ee28aa1f11 => ???M1   changes with NewUser2Sam => NewUser1Sam
1191          * 36349f5cecd07320fb3bb0e119230c43 => ???M1.L changes with newuser2sam => newuser1sam
1192          * 12adf019d037fb535c01fd0608e78d9d => ???M1.U changes with NEWUSER2SAM => NEWUSER1SAM
1193          * 569b4533f2d9e580211dd040e5e360a8 => ???M2   changes with NewUser2Princ => NewUser1Princ
1194          * 52528bddf310a587c5d7e6a9ae2cbb20 => ???M2.L changes with newuser2princ => newuser1princ
1195          * 4f629a4f0361289ca4255ab0f658fcd5 => ???M3 changes with NewUser2Princ => NewUser1Princ (doesn't depend on case of userPrincipal )
1196          * db0c6bff069513e3ebb9870d29b57490 => ???M4 changes with NewUser2Sam => NewUser1Sam
1197          * 45072621e56b1c113a4e04a8ff68cd0e => ???M5 changes with NewUser2Sam => NewUser1Sam (doesn't depend on case of sAMAccountName)
1198          * 11d1220abc44a9c10cf91ef4a9c1de02 => ???M4.U changes with NEWUSER2SAM => NEWUSER1SAM
1199          */
1200
1201         /*
1202          * sAMAccountName, netbios_domain
1203          */
1204                 {
1205                 .user   = &sAMAccountName,
1206                 .realm  = &netbios_domain,
1207                 },
1208                 {
1209                 .user   = &sAMAccountName_l,
1210                 .realm  = &netbios_domain_l,
1211                 },
1212                 {
1213                 .user   = &sAMAccountName_u,
1214                 .realm  = &netbios_domain_u,
1215                 },
1216                 {
1217                 .user   = &sAMAccountName,
1218                 .realm  = &netbios_domain_u,
1219                 },
1220                 {
1221                 .user   = &sAMAccountName,
1222                 .realm  = &netbios_domain_l,
1223                 },
1224                 {
1225                 .user   = &sAMAccountName_u,
1226                 .realm  = &netbios_domain_l,
1227                 },
1228                 {
1229                 .user   = &sAMAccountName_l,
1230                 .realm  = &netbios_domain_u,
1231                 },
1232         /* 
1233          * sAMAccountName, dns_domain
1234          */
1235                 {
1236                 .user   = &sAMAccountName,
1237                 .realm  = &dns_domain,
1238                 },
1239                 {
1240                 .user   = &sAMAccountName_l,
1241                 .realm  = &dns_domain_l,
1242                 },
1243                 {
1244                 .user   = &sAMAccountName_u,
1245                 .realm  = &dns_domain_u,
1246                 },
1247                 {
1248                 .user   = &sAMAccountName,
1249                 .realm  = &dns_domain_u,
1250                 },
1251                 {
1252                 .user   = &sAMAccountName,
1253                 .realm  = &dns_domain_l,
1254                 },
1255                 {
1256                 .user   = &sAMAccountName_u,
1257                 .realm  = &dns_domain_l,
1258                 },
1259                 {
1260                 .user   = &sAMAccountName_l,
1261                 .realm  = &dns_domain_u,
1262                 },
1263         /* 
1264          * userPrincipalName, no realm
1265          */
1266                 {
1267                 .user   = &userPrincipalName,
1268                 },
1269                 {
1270                 /* 
1271                  * NOTE: w2k3 messes this up, if the user has a real userPrincipalName,
1272                  *       the fallback to the sAMAccountName based userPrincipalName is correct
1273                  */
1274                 .user   = &userPrincipalName_l,
1275                 },
1276                 {
1277                 .user   = &userPrincipalName_u,
1278                 },
1279         /* 
1280          * nt4dom\sAMAccountName, no realm
1281          */
1282                 {
1283                 .user   = &sAMAccountName,
1284                 .nt4dom = &netbios_domain
1285                 },
1286                 {
1287                 .user   = &sAMAccountName_l,
1288                 .nt4dom = &netbios_domain_l
1289                 },
1290                 {
1291                 .user   = &sAMAccountName_u,
1292                 .nt4dom = &netbios_domain_u
1293                 },
1294
1295         /*
1296          * the following ones are guessed depending on the technet2 article
1297          * but not reproducable on a w2k3 server
1298          */
1299         /* sAMAccountName with "Digest" realm */
1300                 {
1301                 .user   = &sAMAccountName,
1302                 .realm  = &digest
1303                 },
1304                 {
1305                 .user   = &sAMAccountName_l,
1306                 .realm  = &digest
1307                 },
1308                 {
1309                 .user   = &sAMAccountName_u,
1310                 .realm  = &digest
1311                 },
1312         /* userPrincipalName with "Digest" realm */
1313                 {
1314                 .user   = &userPrincipalName,
1315                 .realm  = &digest
1316                 },
1317                 {
1318                 .user   = &userPrincipalName_l,
1319                 .realm  = &digest
1320                 },
1321                 {
1322                 .user   = &userPrincipalName_u,
1323                 .realm  = &digest
1324                 },
1325         /* nt4dom\\sAMAccountName with "Digest" realm */
1326                 {
1327                 .user   = &sAMAccountName,
1328                 .nt4dom = &netbios_domain,
1329                 .realm  = &digest
1330                 },
1331                 {
1332                 .user   = &sAMAccountName_l,
1333                 .nt4dom = &netbios_domain_l,
1334                 .realm  = &digest
1335                 },
1336                 {
1337                 .user   = &sAMAccountName_u,
1338                 .nt4dom = &netbios_domain_u,
1339                 .realm  = &digest
1340                 },
1341         };
1342
1343         /* prepare DATA_BLOB's used in the combinations array */
1344         sAMAccountName          = data_blob_string_const(io->u.sAMAccountName);
1345         sAMAccountName_l        = data_blob_string_const(strlower_talloc(io->ac, io->u.sAMAccountName));
1346         if (!sAMAccountName_l.data) {
1347                 return ldb_oom(ldb);
1348         }
1349         sAMAccountName_u        = data_blob_string_const(strupper_talloc(io->ac, io->u.sAMAccountName));
1350         if (!sAMAccountName_u.data) {
1351                 return ldb_oom(ldb);
1352         }
1353
1354         /* if the user doesn't have a userPrincipalName, create one (with lower case realm) */
1355         if (!user_principal_name) {
1356                 user_principal_name = talloc_asprintf(io->ac, "%s@%s",
1357                                                       io->u.sAMAccountName,
1358                                                       io->ac->status->domain_data.dns_domain);
1359                 if (!user_principal_name) {
1360                         return ldb_oom(ldb);
1361                 }       
1362         }
1363         userPrincipalName       = data_blob_string_const(user_principal_name);
1364         userPrincipalName_l     = data_blob_string_const(strlower_talloc(io->ac, user_principal_name));
1365         if (!userPrincipalName_l.data) {
1366                 return ldb_oom(ldb);
1367         }
1368         userPrincipalName_u     = data_blob_string_const(strupper_talloc(io->ac, user_principal_name));
1369         if (!userPrincipalName_u.data) {
1370                 return ldb_oom(ldb);
1371         }
1372
1373         netbios_domain          = data_blob_string_const(io->ac->status->domain_data.netbios_domain);
1374         netbios_domain_l        = data_blob_string_const(strlower_talloc(io->ac,
1375                                                                          io->ac->status->domain_data.netbios_domain));
1376         if (!netbios_domain_l.data) {
1377                 return ldb_oom(ldb);
1378         }
1379         netbios_domain_u        = data_blob_string_const(strupper_talloc(io->ac,
1380                                                                          io->ac->status->domain_data.netbios_domain));
1381         if (!netbios_domain_u.data) {
1382                 return ldb_oom(ldb);
1383         }
1384
1385         dns_domain              = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1386         dns_domain_l            = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1387         dns_domain_u            = data_blob_string_const(io->ac->status->domain_data.realm);
1388
1389         digest                  = data_blob_string_const("Digest");
1390
1391         delim                   = data_blob_string_const(":");
1392         backslash               = data_blob_string_const("\\");
1393
1394         pdb->num_hashes = ARRAY_SIZE(wdigest);
1395         pdb->hashes     = talloc_array(io->ac, struct package_PrimaryWDigestHash,
1396                                        pdb->num_hashes);
1397         if (!pdb->hashes) {
1398                 return ldb_oom(ldb);
1399         }
1400
1401         for (i=0; i < ARRAY_SIZE(wdigest); i++) {
1402                 MD5_CTX md5;
1403                 MD5Init(&md5);
1404                 if (wdigest[i].nt4dom) {
1405                         MD5Update(&md5, wdigest[i].nt4dom->data, wdigest[i].nt4dom->length);
1406                         MD5Update(&md5, backslash.data, backslash.length);
1407                 }
1408                 MD5Update(&md5, wdigest[i].user->data, wdigest[i].user->length);
1409                 MD5Update(&md5, delim.data, delim.length);
1410                 if (wdigest[i].realm) {
1411                         MD5Update(&md5, wdigest[i].realm->data, wdigest[i].realm->length);
1412                 }
1413                 MD5Update(&md5, delim.data, delim.length);
1414                 MD5Update(&md5, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length);
1415                 MD5Final(pdb->hashes[i].hash, &md5);
1416         }
1417
1418         return LDB_SUCCESS;
1419 }
1420
1421 #define SHA_SALT_PERMITTED_CHARS "abcdefghijklmnopqrstuvwxyz" \
1422                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
1423                                  "0123456789./"
1424 #define SHA_SALT_SIZE 16
1425 #define SHA_256_SCHEME "CryptSHA256"
1426 #define SHA_512_SCHEME "CryptSHA512"
1427 #define CRYPT "{CRYPT}"
1428 #define SHA_ID_LEN 3
1429 #define SHA_256_ALGORITHM_ID 5
1430 #define SHA_512_ALGORITHM_ID 6
1431 #define ROUNDS_PARAMETER "rounds="
1432
1433 /*
1434  * Extract the crypt (3) algorithm number and number of hash rounds from the
1435  * supplied scheme string
1436  */
1437 static bool parse_scheme(const char *scheme, int *algorithm, int *rounds) {
1438
1439         const char *rp = NULL; /* Pointer to the 'rounds=' option */
1440         char digits[21];       /* digits extracted from the rounds option */
1441         int i = 0;             /* loop index variable */
1442
1443         if (strncasecmp(SHA_256_SCHEME, scheme, strlen(SHA_256_SCHEME)) == 0) {
1444                 *algorithm = SHA_256_ALGORITHM_ID;
1445         } else if (strncasecmp(SHA_512_SCHEME, scheme, strlen(SHA_256_SCHEME))
1446                    == 0) {
1447                 *algorithm = SHA_512_ALGORITHM_ID;
1448         } else {
1449                 return false;
1450         }
1451
1452         rp = strcasestr(scheme, ROUNDS_PARAMETER);
1453         if (rp == NULL) {
1454                 /* No options specified, use crypt default number of rounds */
1455                 *rounds = 0;
1456                 return true;
1457         }
1458         rp += strlen(ROUNDS_PARAMETER);
1459         for (i = 0; isdigit(rp[i]) && i < (sizeof(digits) - 1); i++) {
1460                 digits[i] = rp[i];
1461         }
1462         digits[i] = '\0';
1463         *rounds = atoi(digits);
1464         return true;
1465 }
1466
1467 /*
1468  * Calculate the password hash specified by scheme, and return it in
1469  * hash_value
1470  */
1471 static int setup_primary_userPassword_hash(
1472         TALLOC_CTX *ctx,
1473         struct setup_password_fields_io *io,
1474         const char* scheme,
1475         struct package_PrimaryUserPasswordValue *hash_value)
1476 {
1477         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1478         const char *salt = NULL;        /* Randomly generated salt */
1479         const char *cmd = NULL;         /* command passed to crypt */
1480         const char *hash = NULL;        /* password hash generated by crypt */
1481         struct crypt_data crypt_data;   /* working storage used by crypt */
1482         int algorithm = 0;              /* crypt hash algorithm number */
1483         int rounds = 0;                 /* The number of hash rounds */
1484         DATA_BLOB *hash_blob = NULL;
1485         TALLOC_CTX *frame = talloc_stackframe();
1486
1487         /* Genrate a random password salt */
1488         salt = generate_random_str_list(frame,
1489                                         SHA_SALT_SIZE,
1490                                         SHA_SALT_PERMITTED_CHARS);
1491         if (salt == NULL) {
1492                 TALLOC_FREE(frame);
1493                 return ldb_oom(ldb);
1494         }
1495
1496         /* determine the hashing algoritm and number of rounds*/
1497         if (!parse_scheme(scheme, &algorithm, &rounds)) {
1498                 ldb_asprintf_errstring(
1499                         ldb,
1500                         "setup_primary_userPassword: Invalid scheme of [%s] "
1501                         "specified for 'password hash userPassword schemes' in "
1502                         "samba.conf",
1503                         scheme);
1504                 TALLOC_FREE(frame);
1505                 return LDB_ERR_OPERATIONS_ERROR;
1506         }
1507         hash_value->scheme = talloc_strdup(ctx, CRYPT);
1508         hash_value->scheme_len = strlen(CRYPT) + 1;
1509
1510         /* generate the id/salt parameter used by crypt */
1511         if (rounds) {
1512                 cmd = talloc_asprintf(frame,
1513                                       "$%d$rounds=%d$%s",
1514                                       algorithm,
1515                                       rounds,
1516                                       salt);
1517         } else {
1518                 cmd = talloc_asprintf(frame, "$%d$%s", algorithm, salt);
1519         }
1520
1521         /*
1522          * Relies on the assertion that cleartext_utf8->data is a zero
1523          * terminated UTF-8 string
1524          */
1525         hash = crypt_r((char *)io->n.cleartext_utf8->data, cmd, &crypt_data);
1526         if (hash == NULL) {
1527                 char buf[1024];
1528                 ldb_asprintf_errstring(
1529                         ldb,
1530                         "setup_primary_userPassword: generation of a %s "
1531                         "password hash failed: (%s)",
1532                         scheme,
1533                         strerror_r(errno, buf, sizeof(buf)));
1534                 TALLOC_FREE(frame);
1535                 return LDB_ERR_OPERATIONS_ERROR;
1536         }
1537
1538         hash_blob = talloc_zero(ctx, DATA_BLOB);
1539
1540         if (hash_blob == NULL) {
1541                 TALLOC_FREE(frame);
1542                 return ldb_oom(ldb);
1543         }
1544
1545         *hash_blob =  data_blob_talloc(hash_blob,
1546                                        (const uint8_t *)hash,
1547                                        strlen(hash));
1548         if (hash_blob->data == NULL) {
1549                 TALLOC_FREE(frame);
1550                 return ldb_oom(ldb);
1551         }
1552         hash_value->value = hash_blob;
1553         TALLOC_FREE(frame);
1554         return LDB_SUCCESS;
1555 }
1556
1557 /*
1558  * Calculate the desired extra password hashes
1559  */
1560 static int setup_primary_userPassword(
1561         struct setup_password_fields_io *io,
1562         const struct supplementalCredentialsBlob *old_scb,
1563         struct package_PrimaryUserPasswordBlob *p_userPassword_b)
1564 {
1565         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1566         TALLOC_CTX *frame = talloc_stackframe();
1567         int i;
1568         int ret;
1569
1570         /*
1571          * Save the current nt_hash, use this to determine if the password
1572          * has been changed by windows. Which will invalidate the userPassword
1573          * hash. Note once NTLM-Strong-NOWTF becomes available it should be
1574          * used in preference to the NT password hash
1575          */
1576         if (io->g.nt_hash == NULL) {
1577                 ldb_asprintf_errstring(ldb,
1578                         "No NT Hash, unable to calculate userPassword hashes");
1579                         return LDB_ERR_UNWILLING_TO_PERFORM;
1580         }
1581         p_userPassword_b->current_nt_hash = *io->g.nt_hash;
1582
1583         /*
1584          * Determine the number of hashes
1585          * Note: that currently there is no limit on the number of hashes
1586          *       no checking is done on the number of schemes specified
1587          *       or for uniqueness.
1588          */
1589         p_userPassword_b->num_hashes = 0;
1590         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1591                 p_userPassword_b->num_hashes++;
1592         }
1593
1594         p_userPassword_b->hashes
1595                 = talloc_array(io->ac,
1596                                struct package_PrimaryUserPasswordValue,
1597                                p_userPassword_b->num_hashes);
1598         if (p_userPassword_b->hashes == NULL) {
1599                 TALLOC_FREE(frame);
1600                 return ldb_oom(ldb);
1601         }
1602
1603         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1604                 ret = setup_primary_userPassword_hash(
1605                         p_userPassword_b->hashes,
1606                         io,
1607                         io->ac->userPassword_schemes[i],
1608                         &p_userPassword_b->hashes[i]);
1609                 if (ret != LDB_SUCCESS) {
1610                         TALLOC_FREE(frame);
1611                         return ret;
1612                 }
1613         }
1614         return LDB_SUCCESS;
1615 }
1616
1617
1618 static int setup_primary_samba_gpg(struct setup_password_fields_io *io,
1619                                    struct package_PrimarySambaGPGBlob *pgb)
1620 {
1621         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1622 #ifdef ENABLE_GPGME
1623         gpgme_error_t gret;
1624         gpgme_ctx_t ctx = NULL;
1625         size_t num_keys = str_list_length(io->ac->gpg_key_ids);
1626         gpgme_key_t keys[num_keys+1];
1627         size_t ki = 0;
1628         size_t kr = 0;
1629         gpgme_data_t plain_data = NULL;
1630         gpgme_data_t crypt_data = NULL;
1631         size_t crypt_length = 0;
1632         char *crypt_mem = NULL;
1633
1634         gret = gpgme_new(&ctx);
1635         if (gret != GPG_ERR_NO_ERROR) {
1636                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1637                           "%s:%s: gret[%u] %s\n",
1638                           __location__, __func__,
1639                           gret, gpgme_strerror(gret));
1640                 return ldb_module_operr(io->ac->module);
1641         }
1642
1643         gpgme_set_armor(ctx, 1);
1644
1645         gret = gpgme_data_new_from_mem(&plain_data,
1646                                        (const char *)io->n.cleartext_utf16->data,
1647                                        io->n.cleartext_utf16->length,
1648                                        0 /* no copy */);
1649         if (gret != GPG_ERR_NO_ERROR) {
1650                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1651                           "%s:%s: gret[%u] %s\n",
1652                           __location__, __func__,
1653                           gret, gpgme_strerror(gret));
1654                 gpgme_release(ctx);
1655                 return ldb_module_operr(io->ac->module);
1656         }
1657         gret = gpgme_data_new(&crypt_data);
1658         if (gret != GPG_ERR_NO_ERROR) {
1659                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1660                           "%s:%s: gret[%u] %s\n",
1661                           __location__, __func__,
1662                           gret, gpgme_strerror(gret));
1663                 gpgme_data_release(plain_data);
1664                 gpgme_release(ctx);
1665                 return ldb_module_operr(io->ac->module);
1666         }
1667
1668         for (ki = 0; ki < num_keys; ki++) {
1669                 const char *key_id = io->ac->gpg_key_ids[ki];
1670                 size_t len = strlen(key_id);
1671
1672                 keys[ki] = NULL;
1673
1674                 if (len < 16) {
1675                         ldb_debug(ldb, LDB_DEBUG_FATAL,
1676                                   "%s:%s: ki[%zu] key_id[%s] strlen < 16, "
1677                                   "please specify at least the 64bit key id\n",
1678                                   __location__, __func__,
1679                                   ki, key_id);
1680                         for (kr = 0; keys[kr] != NULL; kr++) {
1681                                 gpgme_key_release(keys[kr]);
1682                         }
1683                         gpgme_data_release(crypt_data);
1684                         gpgme_data_release(plain_data);
1685                         gpgme_release(ctx);
1686                         return ldb_module_operr(io->ac->module);
1687                 }
1688
1689                 gret = gpgme_get_key(ctx, key_id, &keys[ki], 0 /* public key */);
1690                 if (gret != GPG_ERR_NO_ERROR) {
1691                         keys[ki] = NULL;
1692                         ldb_debug(ldb, LDB_DEBUG_ERROR,
1693                                   "%s:%s: ki[%zu] key_id[%s] gret[%u] %s\n",
1694                                   __location__, __func__,
1695                                   ki, key_id,
1696                                   gret, gpgme_strerror(gret));
1697                         for (kr = 0; keys[kr] != NULL; kr++) {
1698                                 gpgme_key_release(keys[kr]);
1699                         }
1700                         gpgme_data_release(crypt_data);
1701                         gpgme_data_release(plain_data);
1702                         gpgme_release(ctx);
1703                         return ldb_module_operr(io->ac->module);
1704                 }
1705         }
1706         keys[ki] = NULL;
1707
1708         gret = gpgme_op_encrypt(ctx, keys,
1709                                 GPGME_ENCRYPT_ALWAYS_TRUST,
1710                                 plain_data, crypt_data);
1711         gpgme_data_release(plain_data);
1712         plain_data = NULL;
1713         for (kr = 0; keys[kr] != NULL; kr++) {
1714                 gpgme_key_release(keys[kr]);
1715                 keys[kr] = NULL;
1716         }
1717         gpgme_release(ctx);
1718         ctx = NULL;
1719         if (gret != GPG_ERR_NO_ERROR) {
1720                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1721                           "%s:%s: gret[%u] %s\n",
1722                           __location__, __func__,
1723                           gret, gpgme_strerror(gret));
1724                 gpgme_data_release(crypt_data);
1725                 return ldb_module_operr(io->ac->module);
1726         }
1727
1728         crypt_mem = gpgme_data_release_and_get_mem(crypt_data, &crypt_length);
1729         crypt_data = NULL;
1730         if (crypt_mem == NULL) {
1731                 return ldb_module_oom(io->ac->module);
1732         }
1733
1734         pgb->gpg_blob = data_blob_talloc(io->ac,
1735                                          (const uint8_t *)crypt_mem,
1736                                          crypt_length);
1737         gpgme_free(crypt_mem);
1738         crypt_mem = NULL;
1739         crypt_length = 0;
1740         if (pgb->gpg_blob.data == NULL) {
1741                 return ldb_module_oom(io->ac->module);
1742         }
1743
1744         return LDB_SUCCESS;
1745 #else /* ENABLE_GPGME */
1746         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
1747                       "You configured 'password hash gpg key ids', "
1748                       "but GPGME support is missing. (%s:%d)",
1749                       __FILE__, __LINE__);
1750         return LDB_ERR_UNWILLING_TO_PERFORM;
1751 #endif /* else ENABLE_GPGME */
1752 }
1753
1754 #define NUM_PACKAGES 6
1755 static int setup_supplemental_field(struct setup_password_fields_io *io)
1756 {
1757         struct ldb_context *ldb;
1758         struct supplementalCredentialsBlob scb;
1759         struct supplementalCredentialsBlob *old_scb = NULL;
1760         /*
1761          * Packages +
1762          * ( Kerberos-Newer-Keys, Kerberos,
1763          *   WDigest, CLEARTEXT, userPassword, SambaGPG)
1764          */
1765         uint32_t num_names = 0;
1766         const char *names[1+NUM_PACKAGES];
1767         uint32_t num_packages = 0;
1768         struct supplementalCredentialsPackage packages[1+NUM_PACKAGES];
1769         struct supplementalCredentialsPackage *pp = packages;
1770         int ret;
1771         enum ndr_err_code ndr_err;
1772         bool do_newer_keys = false;
1773         bool do_cleartext = false;
1774         bool do_samba_gpg = false;
1775
1776         ZERO_STRUCT(names);
1777         ZERO_STRUCT(packages);
1778
1779         ldb = ldb_module_get_ctx(io->ac->module);
1780
1781         if (!io->n.cleartext_utf8) {
1782                 /*
1783                  * when we don't have a cleartext password
1784                  * we can't setup a supplementalCredential value
1785                  */
1786                 return LDB_SUCCESS;
1787         }
1788
1789         /* if there's an old supplementaCredentials blob then use it */
1790         if (io->o.supplemental) {
1791                 if (io->o.scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
1792                         old_scb = &io->o.scb;
1793                 } else {
1794                         ldb_debug(ldb, LDB_DEBUG_ERROR,
1795                                   "setup_supplemental_field: "
1796                                   "supplementalCredentialsBlob "
1797                                   "signature[0x%04X] expected[0x%04X]",
1798                                   io->o.scb.sub.signature,
1799                                   SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
1800                 }
1801         }
1802         /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
1803
1804
1805
1806         /*
1807          * The ordering is this
1808          *
1809          * Primary:Kerberos-Newer-Keys (optional)
1810          * Primary:Kerberos
1811          * Primary:WDigest
1812          * Primary:CLEARTEXT (optional)
1813          * Primary:userPassword
1814          * Primary:SambaGPG (optional)
1815          *
1816          * And the 'Packages' package is insert before the last
1817          * other package.
1818          *
1819          * Note: it's important that Primary:SambaGPG is added as
1820          * the last element. This is the indication that it matches
1821          * the current password. When a password change happens on
1822          * a Windows DC, it will keep the old Primary:SambaGPG value,
1823          * but as the first element.
1824          */
1825         do_newer_keys = (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008);
1826         if (do_newer_keys) {
1827                 struct package_PrimaryKerberosBlob pknb;
1828                 DATA_BLOB pknb_blob;
1829                 char *pknb_hexstr;
1830                 /*
1831                  * setup 'Primary:Kerberos-Newer-Keys' element
1832                  */
1833                 names[num_names++] = "Kerberos-Newer-Keys";
1834
1835                 ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
1836                 if (ret != LDB_SUCCESS) {
1837                         return ret;
1838                 }
1839
1840                 ndr_err = ndr_push_struct_blob(
1841                         &pknb_blob, io->ac,
1842                         &pknb,
1843                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1844                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1845                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1846                         ldb_asprintf_errstring(
1847                                 ldb,
1848                                 "setup_supplemental_field: "
1849                                 "failed to push "
1850                                 "package_PrimaryKerberosNeverBlob: %s",
1851                                 nt_errstr(status));
1852                         return LDB_ERR_OPERATIONS_ERROR;
1853                 }
1854                 pknb_hexstr = data_blob_hex_string_upper(io->ac, &pknb_blob);
1855                 if (!pknb_hexstr) {
1856                         return ldb_oom(ldb);
1857                 }
1858                 pp->name        = "Primary:Kerberos-Newer-Keys";
1859                 pp->reserved    = 1;
1860                 pp->data        = pknb_hexstr;
1861                 pp++;
1862                 num_packages++;
1863         }
1864
1865         {
1866                 /*
1867                  * setup 'Primary:Kerberos' element
1868                  */
1869                 /* Primary:Kerberos */
1870                 struct package_PrimaryKerberosBlob pkb;
1871                 DATA_BLOB pkb_blob;
1872                 char *pkb_hexstr;
1873
1874                 names[num_names++] = "Kerberos";
1875
1876                 ret = setup_primary_kerberos(io, old_scb, &pkb);
1877                 if (ret != LDB_SUCCESS) {
1878                         return ret;
1879                 }
1880
1881                 ndr_err = ndr_push_struct_blob(
1882                         &pkb_blob, io->ac,
1883                         &pkb,
1884                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1885                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1886                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1887                         ldb_asprintf_errstring(
1888                                 ldb,
1889                                 "setup_supplemental_field: "
1890                                 "failed to push package_PrimaryKerberosBlob: %s",
1891                                 nt_errstr(status));
1892                         return LDB_ERR_OPERATIONS_ERROR;
1893                 }
1894                 pkb_hexstr = data_blob_hex_string_upper(io->ac, &pkb_blob);
1895                 if (!pkb_hexstr) {
1896                         return ldb_oom(ldb);
1897                 }
1898                 pp->name        = "Primary:Kerberos";
1899                 pp->reserved    = 1;
1900                 pp->data        = pkb_hexstr;
1901                 pp++;
1902                 num_packages++;
1903         }
1904
1905         {
1906                 /*
1907                  * setup 'Primary:WDigest' element
1908                  */
1909                 struct package_PrimaryWDigestBlob pdb;
1910                 DATA_BLOB pdb_blob;
1911                 char *pdb_hexstr;
1912
1913                 names[num_names++] = "WDigest";
1914
1915                 ret = setup_primary_wdigest(io, old_scb, &pdb);
1916                 if (ret != LDB_SUCCESS) {
1917                         return ret;
1918                 }
1919
1920                 ndr_err = ndr_push_struct_blob(
1921                         &pdb_blob, io->ac,
1922                         &pdb,
1923                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryWDigestBlob);
1924                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1925                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1926                         ldb_asprintf_errstring(
1927                                 ldb,
1928                                 "setup_supplemental_field: "
1929                                 "failed to push package_PrimaryWDigestBlob: %s",
1930                                 nt_errstr(status));
1931                         return LDB_ERR_OPERATIONS_ERROR;
1932                 }
1933                 pdb_hexstr = data_blob_hex_string_upper(io->ac, &pdb_blob);
1934                 if (!pdb_hexstr) {
1935                         return ldb_oom(ldb);
1936                 }
1937                 pp->name        = "Primary:WDigest";
1938                 pp->reserved    = 1;
1939                 pp->data        = pdb_hexstr;
1940                 pp++;
1941                 num_packages++;
1942         }
1943
1944         /*
1945          * setup 'Primary:CLEARTEXT' element
1946          */
1947         if (io->ac->status->domain_data.store_cleartext &&
1948             (io->u.userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
1949                 do_cleartext = true;
1950         }
1951         if (do_cleartext) {
1952                 struct package_PrimaryCLEARTEXTBlob pcb;
1953                 DATA_BLOB pcb_blob;
1954                 char *pcb_hexstr;
1955
1956                 names[num_names++] = "CLEARTEXT";
1957
1958                 pcb.cleartext   = *io->n.cleartext_utf16;
1959
1960                 ndr_err = ndr_push_struct_blob(
1961                         &pcb_blob, io->ac,
1962                         &pcb,
1963                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryCLEARTEXTBlob);
1964                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1965                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1966                         ldb_asprintf_errstring(
1967                                 ldb,
1968                                 "setup_supplemental_field: "
1969                                 "failed to push package_PrimaryCLEARTEXTBlob: %s",
1970                                 nt_errstr(status));
1971                         return LDB_ERR_OPERATIONS_ERROR;
1972                 }
1973                 pcb_hexstr = data_blob_hex_string_upper(io->ac, &pcb_blob);
1974                 if (!pcb_hexstr) {
1975                         return ldb_oom(ldb);
1976                 }
1977                 pp->name        = "Primary:CLEARTEXT";
1978                 pp->reserved    = 1;
1979                 pp->data        = pcb_hexstr;
1980                 pp++;
1981                 num_packages++;
1982         }
1983
1984         if (io->ac->userPassword_schemes) {
1985                 /*
1986                  * setup 'Primary:userPassword' element
1987                  */
1988                 struct package_PrimaryUserPasswordBlob
1989                         p_userPassword_b;
1990                 DATA_BLOB p_userPassword_b_blob;
1991                 char *p_userPassword_b_hexstr;
1992
1993                 names[num_names++] = "userPassword";
1994
1995                 ret = setup_primary_userPassword(io,
1996                                                  old_scb,
1997                                                  &p_userPassword_b);
1998                 if (ret != LDB_SUCCESS) {
1999                         return ret;
2000                 }
2001
2002                 ndr_err = ndr_push_struct_blob(
2003                         &p_userPassword_b_blob,
2004                         io->ac,
2005                         &p_userPassword_b,
2006                         (ndr_push_flags_fn_t)
2007                         ndr_push_package_PrimaryUserPasswordBlob);
2008                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2009                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2010                         ldb_asprintf_errstring(
2011                                 ldb,
2012                                 "setup_supplemental_field: failed to push "
2013                                 "package_PrimaryUserPasswordBlob: %s",
2014                                 nt_errstr(status));
2015                         return LDB_ERR_OPERATIONS_ERROR;
2016                 }
2017                 p_userPassword_b_hexstr
2018                         = data_blob_hex_string_upper(
2019                                 io->ac,
2020                                 &p_userPassword_b_blob);
2021                 if (!p_userPassword_b_hexstr) {
2022                         return ldb_oom(ldb);
2023                 }
2024                 pp->name     = "Primary:userPassword";
2025                 pp->reserved = 1;
2026                 pp->data     = p_userPassword_b_hexstr;
2027                 pp++;
2028                 num_packages++;
2029         }
2030
2031         /*
2032          * setup 'Primary:SambaGPG' element
2033          */
2034         if (io->ac->gpg_key_ids != NULL) {
2035                 do_samba_gpg = true;
2036         }
2037         if (do_samba_gpg) {
2038                 struct package_PrimarySambaGPGBlob pgb;
2039                 DATA_BLOB pgb_blob;
2040                 char *pgb_hexstr;
2041
2042                 names[num_names++] = "SambaGPG";
2043
2044                 ret = setup_primary_samba_gpg(io, &pgb);
2045                 if (ret != LDB_SUCCESS) {
2046                         return ret;
2047                 }
2048
2049                 ndr_err = ndr_push_struct_blob(&pgb_blob, io->ac, &pgb,
2050                         (ndr_push_flags_fn_t)ndr_push_package_PrimarySambaGPGBlob);
2051                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2052                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2053                         ldb_asprintf_errstring(ldb,
2054                                         "setup_supplemental_field: failed to "
2055                                         "push package_PrimarySambaGPGBlob: %s",
2056                                         nt_errstr(status));
2057                         return LDB_ERR_OPERATIONS_ERROR;
2058                 }
2059                 pgb_hexstr = data_blob_hex_string_upper(io->ac, &pgb_blob);
2060                 if (!pgb_hexstr) {
2061                         return ldb_oom(ldb);
2062                 }
2063                 pp->name        = "Primary:SambaGPG";
2064                 pp->reserved    = 1;
2065                 pp->data        = pgb_hexstr;
2066                 pp++;
2067                 num_packages++;
2068         }
2069
2070         /*
2071          * setup 'Packages' element
2072          */
2073         {
2074                 struct package_PackagesBlob pb;
2075                 DATA_BLOB pb_blob;
2076                 char *pb_hexstr;
2077
2078                 pb.names = names;
2079                 ndr_err = ndr_push_struct_blob(
2080                         &pb_blob, io->ac,
2081                         &pb,
2082                         (ndr_push_flags_fn_t)ndr_push_package_PackagesBlob);
2083                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2084                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2085                         ldb_asprintf_errstring(
2086                                 ldb,
2087                                 "setup_supplemental_field: "
2088                                 "failed to push package_PackagesBlob: %s",
2089                                 nt_errstr(status));
2090                         return LDB_ERR_OPERATIONS_ERROR;
2091                 }
2092                 pb_hexstr = data_blob_hex_string_upper(io->ac, &pb_blob);
2093                 if (!pb_hexstr) {
2094                         return ldb_oom(ldb);
2095                 }
2096                 pp->name        = "Packages";
2097                 pp->reserved    = 2;
2098                 pp->data        = pb_hexstr;
2099                 num_packages++;
2100                 /*
2101                  * We don't increment pp so it's pointing to the last package
2102                  */
2103         }
2104
2105         /*
2106          * setup 'supplementalCredentials' value
2107          */
2108         {
2109                 /*
2110                  * The 'Packages' element needs to be the second last element
2111                  * in supplementalCredentials
2112                  */
2113                 struct supplementalCredentialsPackage temp;
2114                 struct supplementalCredentialsPackage *prev;
2115
2116                 prev = pp-1;
2117                 temp = *prev;
2118                 *prev = *pp;
2119                 *pp = temp;
2120
2121                 ZERO_STRUCT(scb);
2122                 scb.sub.signature       = SUPPLEMENTAL_CREDENTIALS_SIGNATURE;
2123                 scb.sub.num_packages    = num_packages;
2124                 scb.sub.packages        = packages;
2125
2126                 ndr_err = ndr_push_struct_blob(
2127                         &io->g.supplemental, io->ac,
2128                         &scb,
2129                         (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2130                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2131                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2132                         ldb_asprintf_errstring(
2133                                 ldb,
2134                                 "setup_supplemental_field: "
2135                                 "failed to push supplementalCredentialsBlob: %s",
2136                                 nt_errstr(status));
2137                         return LDB_ERR_OPERATIONS_ERROR;
2138                 }
2139         }
2140
2141         return LDB_SUCCESS;
2142 }
2143
2144 static int setup_last_set_field(struct setup_password_fields_io *io)
2145 {
2146         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2147         const struct ldb_message *msg = NULL;
2148         struct timeval tv = { .tv_sec = 0 };
2149         const struct ldb_val *old_val = NULL;
2150         const struct ldb_val *new_val = NULL;
2151         int ret;
2152
2153         switch (io->ac->req->operation) {
2154         case LDB_ADD:
2155                 msg = io->ac->req->op.add.message;
2156                 break;
2157         case LDB_MODIFY:
2158                 msg = io->ac->req->op.mod.message;
2159                 break;
2160         default:
2161                 return LDB_ERR_OPERATIONS_ERROR;
2162                 break;
2163         }
2164
2165         if (io->ac->pwd_last_set_bypass) {
2166                 struct ldb_message_element *el1 = NULL;
2167                 struct ldb_message_element *el2 = NULL;
2168
2169                 if (msg == NULL) {
2170                         return LDB_ERR_CONSTRAINT_VIOLATION;
2171                 }
2172
2173                 el1 = dsdb_get_single_valued_attr(msg, "pwdLastSet",
2174                                                   io->ac->req->operation);
2175                 if (el1 == NULL) {
2176                         return LDB_ERR_CONSTRAINT_VIOLATION;
2177                 }
2178                 el2 = ldb_msg_find_element(msg, "pwdLastSet");
2179                 if (el2 == NULL) {
2180                         return LDB_ERR_CONSTRAINT_VIOLATION;
2181                 }
2182                 if (el1 != el2) {
2183                         return LDB_ERR_CONSTRAINT_VIOLATION;
2184                 }
2185
2186                 io->g.last_set = samdb_result_nttime(msg, "pwdLastSet", 0);
2187                 return LDB_SUCCESS;
2188         }
2189
2190         ret = msg_find_old_and_new_pwd_val(msg, "pwdLastSet",
2191                                            io->ac->req->operation,
2192                                            &new_val, &old_val);
2193         if (ret != LDB_SUCCESS) {
2194                 return ret;
2195         }
2196
2197         if (old_val != NULL && new_val == NULL) {
2198                 ldb_set_errstring(ldb,
2199                                   "'pwdLastSet' deletion is not allowed!");
2200                 return LDB_ERR_UNWILLING_TO_PERFORM;
2201         }
2202
2203         io->g.last_set = UINT64_MAX;
2204         if (new_val != NULL) {
2205                 struct ldb_message *tmp_msg = NULL;
2206
2207                 tmp_msg = ldb_msg_new(io->ac);
2208                 if (tmp_msg == NULL) {
2209                         return ldb_module_oom(io->ac->module);
2210                 }
2211
2212                 if (old_val != NULL) {
2213                         NTTIME old_last_set = 0;
2214
2215                         ret = ldb_msg_add_value(tmp_msg, "oldval",
2216                                                 old_val, NULL);
2217                         if (ret != LDB_SUCCESS) {
2218                                 return ret;
2219                         }
2220
2221                         old_last_set = samdb_result_nttime(tmp_msg,
2222                                                            "oldval",
2223                                                            1);
2224                         if (io->u.pwdLastSet != old_last_set) {
2225                                 return dsdb_module_werror(io->ac->module,
2226                                         LDB_ERR_NO_SUCH_ATTRIBUTE,
2227                                         WERR_DS_CANT_REM_MISSING_ATT_VAL,
2228                                         "setup_last_set_field: old pwdLastSet "
2229                                         "value not found!");
2230                         }
2231                 }
2232
2233                 ret = ldb_msg_add_value(tmp_msg, "newval",
2234                                         new_val, NULL);
2235                 if (ret != LDB_SUCCESS) {
2236                         return ret;
2237                 }
2238
2239                 io->g.last_set = samdb_result_nttime(tmp_msg,
2240                                                      "newval",
2241                                                      1);
2242         } else if (ldb_msg_find_element(msg, "pwdLastSet")) {
2243                 ldb_set_errstring(ldb,
2244                                   "'pwdLastSet' deletion is not allowed!");
2245                 return LDB_ERR_UNWILLING_TO_PERFORM;
2246         } else if (io->ac->smartcard_reset) {
2247                 /*
2248                  * adding UF_SMARTCARD_REQUIRED doesn't update
2249                  * pwdLastSet implicitly.
2250                  */
2251                 io->ac->update_lastset = false;
2252         }
2253
2254         /* only 0 or -1 (0xFFFFFFFFFFFFFFFF) are allowed */
2255         switch (io->g.last_set) {
2256         case 0:
2257                 if (!io->ac->pwd_last_set_default) {
2258                         break;
2259                 }
2260                 if (!io->ac->update_password) {
2261                         break;
2262                 }
2263                 /* fall through */
2264         case UINT64_MAX:
2265                 if (!io->ac->update_password &&
2266                     io->u.pwdLastSet != 0 &&
2267                     io->u.pwdLastSet != UINT64_MAX)
2268                 {
2269                         /*
2270                          * Just setting pwdLastSet to -1, while not changing
2271                          * any password field has no effect if pwdLastSet
2272                          * is already non-zero.
2273                          */
2274                         io->ac->update_lastset = false;
2275                         break;
2276                 }
2277                 /* -1 means set it as now */
2278                 GetTimeOfDay(&tv);
2279                 io->g.last_set = timeval_to_nttime(&tv);
2280                 break;
2281         default:
2282                 return dsdb_module_werror(io->ac->module,
2283                                           LDB_ERR_OTHER,
2284                                           WERR_INVALID_PARAMETER,
2285                                           "setup_last_set_field: "
2286                                           "pwdLastSet must be 0 or -1 only!");
2287         }
2288
2289         if (io->ac->req->operation == LDB_ADD) {
2290                 /*
2291                  * We always need to store the value on add
2292                  * operations.
2293                  */
2294                 return LDB_SUCCESS;
2295         }
2296
2297         if (io->g.last_set == io->u.pwdLastSet) {
2298                 /*
2299                  * Just setting pwdLastSet to 0, is no-op if it's already 0.
2300                  */
2301                 io->ac->update_lastset = false;
2302         }
2303
2304         return LDB_SUCCESS;
2305 }
2306
2307 static int setup_given_passwords(struct setup_password_fields_io *io,
2308                                  struct setup_password_fields_given *g)
2309 {
2310         struct ldb_context *ldb;
2311         bool ok;
2312
2313         ldb = ldb_module_get_ctx(io->ac->module);
2314
2315         if (g->cleartext_utf8) {
2316                 struct ldb_val *cleartext_utf16_blob;
2317
2318                 cleartext_utf16_blob = talloc(io->ac, struct ldb_val);
2319                 if (!cleartext_utf16_blob) {
2320                         return ldb_oom(ldb);
2321                 }
2322                 if (!convert_string_talloc(io->ac,
2323                                            CH_UTF8, CH_UTF16,
2324                                            g->cleartext_utf8->data,
2325                                            g->cleartext_utf8->length,
2326                                            (void *)&cleartext_utf16_blob->data,
2327                                            &cleartext_utf16_blob->length)) {
2328                         if (g->cleartext_utf8->length != 0) {
2329                                 talloc_free(cleartext_utf16_blob);
2330                                 ldb_asprintf_errstring(ldb,
2331                                                        "setup_password_fields: "
2332                                                        "failed to generate UTF16 password from cleartext UTF8 one for user '%s'!",
2333                                                        io->u.sAMAccountName);
2334                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2335                         } else {
2336                                 /* passwords with length "0" are valid! */
2337                                 cleartext_utf16_blob->data = NULL;
2338                                 cleartext_utf16_blob->length = 0;
2339                         }
2340                 }
2341                 g->cleartext_utf16 = cleartext_utf16_blob;
2342         } else if (g->cleartext_utf16) {
2343                 struct ldb_val *cleartext_utf8_blob;
2344
2345                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
2346                 if (!cleartext_utf8_blob) {
2347                         return ldb_oom(ldb);
2348                 }
2349                 if (!convert_string_talloc(io->ac,
2350                                            CH_UTF16MUNGED, CH_UTF8,
2351                                            g->cleartext_utf16->data,
2352                                            g->cleartext_utf16->length,
2353                                            (void *)&cleartext_utf8_blob->data,
2354                                            &cleartext_utf8_blob->length)) {
2355                         if (g->cleartext_utf16->length != 0) {
2356                                 /* We must bail out here, the input wasn't even
2357                                  * a multiple of 2 bytes */
2358                                 talloc_free(cleartext_utf8_blob);
2359                                 ldb_asprintf_errstring(ldb,
2360                                                        "setup_password_fields: "
2361                                                        "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)!",
2362                                                        io->u.sAMAccountName);
2363                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2364                         } else {
2365                                 /* passwords with length "0" are valid! */
2366                                 cleartext_utf8_blob->data = NULL;
2367                                 cleartext_utf8_blob->length = 0;
2368                         }
2369                 }
2370                 g->cleartext_utf8 = cleartext_utf8_blob;
2371         }
2372
2373         if (g->cleartext_utf16) {
2374                 struct samr_Password *nt_hash;
2375
2376                 nt_hash = talloc(io->ac, struct samr_Password);
2377                 if (!nt_hash) {
2378                         return ldb_oom(ldb);
2379                 }
2380                 g->nt_hash = nt_hash;
2381
2382                 /* compute the new nt hash */
2383                 mdfour(nt_hash->hash,
2384                        g->cleartext_utf16->data,
2385                        g->cleartext_utf16->length);
2386         }
2387
2388         if (g->cleartext_utf8) {
2389                 struct samr_Password *lm_hash;
2390
2391                 lm_hash = talloc(io->ac, struct samr_Password);
2392                 if (!lm_hash) {
2393                         return ldb_oom(ldb);
2394                 }
2395
2396                 /* compute the new lm hash */
2397                 ok = E_deshash((char *)g->cleartext_utf8->data, lm_hash->hash);
2398                 if (ok) {
2399                         g->lm_hash = lm_hash;
2400                 } else {
2401                         talloc_free(lm_hash);
2402                 }
2403         }
2404
2405         return LDB_SUCCESS;
2406 }
2407
2408 static int setup_password_fields(struct setup_password_fields_io *io)
2409 {
2410         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2411         struct loadparm_context *lp_ctx =
2412                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
2413                                          struct loadparm_context);
2414         int ret;
2415
2416         ret = setup_last_set_field(io);
2417         if (ret != LDB_SUCCESS) {
2418                 return ret;
2419         }
2420
2421         if (!io->ac->update_password) {
2422                 return LDB_SUCCESS;
2423         }
2424
2425         /* transform the old password (for password changes) */
2426         ret = setup_given_passwords(io, &io->og);
2427         if (ret != LDB_SUCCESS) {
2428                 return ret;
2429         }
2430
2431         /* transform the new password */
2432         ret = setup_given_passwords(io, &io->n);
2433         if (ret != LDB_SUCCESS) {
2434                 return ret;
2435         }
2436
2437         if (io->n.cleartext_utf8) {
2438                 ret = setup_kerberos_keys(io);
2439                 if (ret != LDB_SUCCESS) {
2440                         return ret;
2441                 }
2442         }
2443
2444         ret = setup_nt_fields(io);
2445         if (ret != LDB_SUCCESS) {
2446                 return ret;
2447         }
2448
2449         if (lpcfg_lanman_auth(lp_ctx)) {
2450                 ret = setup_lm_fields(io);
2451                 if (ret != LDB_SUCCESS) {
2452                         return ret;
2453                 }
2454         } else {
2455                 io->g.lm_hash = NULL;
2456                 io->g.lm_history_len = 0;
2457         }
2458
2459         ret = setup_supplemental_field(io);
2460         if (ret != LDB_SUCCESS) {
2461                 return ret;
2462         }
2463
2464         return LDB_SUCCESS;
2465 }
2466
2467 static int setup_smartcard_reset(struct setup_password_fields_io *io)
2468 {
2469         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2470         struct loadparm_context *lp_ctx = talloc_get_type(
2471                 ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
2472         struct supplementalCredentialsBlob scb = { .__ndr_size = 0 };
2473         enum ndr_err_code ndr_err;
2474
2475         if (!io->ac->smartcard_reset) {
2476                 return LDB_SUCCESS;
2477         }
2478
2479         io->g.nt_hash = talloc(io->ac, struct samr_Password);
2480         if (io->g.nt_hash == NULL) {
2481                 return ldb_module_oom(io->ac->module);
2482         }
2483         generate_secret_buffer(io->g.nt_hash->hash,
2484                                sizeof(io->g.nt_hash->hash));
2485         io->g.nt_history_len = 0;
2486
2487         if (lpcfg_lanman_auth(lp_ctx)) {
2488                 io->g.lm_hash = talloc(io->ac, struct samr_Password);
2489                 if (io->g.lm_hash == NULL) {
2490                         return ldb_module_oom(io->ac->module);
2491                 }
2492                 generate_secret_buffer(io->g.lm_hash->hash,
2493                                        sizeof(io->g.lm_hash->hash));
2494         } else {
2495                 io->g.lm_hash = NULL;
2496         }
2497         io->g.lm_history_len = 0;
2498
2499         /*
2500          * We take the "old" value and store it
2501          * with num_packages = 0.
2502          *
2503          * On "add" we have scb.sub.signature == 0, which
2504          * results in:
2505          *
2506          * [0000] 00 00 00 00 00 00 00 00   00 00 00 00 00
2507          *
2508          * On modify it's likely to be scb.sub.signature ==
2509          * SUPPLEMENTAL_CREDENTIALS_SIGNATURE (0x0050), which results in
2510          * something like:
2511          *
2512          * [0000] 00 00 00 00 62 00 00 00   00 00 00 00 20 00 20 00
2513          * [0010] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2514          * [0020] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2515          * [0030] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2516          * [0040] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2517          * [0050] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2518          * [0060] 20 00 20 00 20 00 20 00   20 00 20 00 50 00 00
2519          *
2520          * See https://bugzilla.samba.org/show_bug.cgi?id=11441
2521          * and ndr_{push,pull}_supplementalCredentialsSubBlob().
2522          */
2523         scb = io->o.scb;
2524         scb.sub.num_packages = 0;
2525
2526         /*
2527          * setup 'supplementalCredentials' value without packages
2528          */
2529         ndr_err = ndr_push_struct_blob(&io->g.supplemental, io->ac,
2530                                        &scb,
2531                                        (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2532         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2533                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2534                 ldb_asprintf_errstring(ldb,
2535                                        "setup_smartcard_reset: "
2536                                        "failed to push supplementalCredentialsBlob: %s",
2537                                        nt_errstr(status));
2538                 return LDB_ERR_OPERATIONS_ERROR;
2539         }
2540
2541         io->ac->update_password = true;
2542         return LDB_SUCCESS;
2543 }
2544
2545 static int make_error_and_update_badPwdCount(struct setup_password_fields_io *io, WERROR *werror)
2546 {
2547         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2548         struct ldb_message *mod_msg = NULL;
2549         NTSTATUS status;
2550         int ret;
2551
2552         status = dsdb_update_bad_pwd_count(io->ac, ldb,
2553                                            io->ac->search_res->message,
2554                                            io->ac->dom_res->message,
2555                                            &mod_msg);
2556         if (!NT_STATUS_IS_OK(status)) {
2557                 goto done;
2558         }
2559
2560         if (mod_msg == NULL) {
2561                 goto done;
2562         }
2563
2564         /*
2565          * OK, horrible semantics ahead.
2566          *
2567          * - We need to abort any existing transaction
2568          * - create a transaction arround the badPwdCount update
2569          * - re-open the transaction so the upper layer
2570          *   doesn't know what happened.
2571          *
2572          * This is needed because returning an error to the upper
2573          * layer will cancel the transaction and undo the badPwdCount
2574          * update.
2575          */
2576
2577         /*
2578          * Checking errors here is a bit pointless.
2579          * What can we do if we can't end the transaction?
2580          */
2581         ret = ldb_next_del_trans(io->ac->module);
2582         if (ret != LDB_SUCCESS) {
2583                 ldb_debug(ldb, LDB_DEBUG_FATAL,
2584                           "Failed to abort transaction prior to update of badPwdCount of %s: %s",
2585                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2586                           ldb_errstring(ldb));
2587                 /*
2588                  * just return the original error
2589                  */
2590                 goto done;
2591         }
2592
2593         /* Likewise, what should we do if we can't open a new transaction? */
2594         ret = ldb_next_start_trans(io->ac->module);
2595         if (ret != LDB_SUCCESS) {
2596                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2597                           "Failed to open transaction to update badPwdCount of %s: %s",
2598                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2599                           ldb_errstring(ldb));
2600                 /*
2601                  * just return the original error
2602                  */
2603                 goto done;
2604         }
2605
2606         ret = dsdb_module_modify(io->ac->module, mod_msg,
2607                                  DSDB_FLAG_NEXT_MODULE,
2608                                  io->ac->req);
2609         if (ret != LDB_SUCCESS) {
2610                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2611                           "Failed to update badPwdCount of %s: %s",
2612                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2613                           ldb_errstring(ldb));
2614                 /*
2615                  * We can only ignore this...
2616                  */
2617         }
2618
2619         ret = ldb_next_end_trans(io->ac->module);
2620         if (ret != LDB_SUCCESS) {
2621                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2622                           "Failed to close transaction to update badPwdCount of %s: %s",
2623                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2624                           ldb_errstring(ldb));
2625                 /*
2626                  * We can only ignore this...
2627                  */
2628         }
2629
2630         ret = ldb_next_start_trans(io->ac->module);
2631         if (ret != LDB_SUCCESS) {
2632                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2633                           "Failed to open transaction after update of badPwdCount of %s: %s",
2634                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2635                           ldb_errstring(ldb));
2636                 /*
2637                  * We can only ignore this...
2638                  */
2639         }
2640
2641 done:
2642         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2643         *werror = WERR_INVALID_PASSWORD;
2644         ldb_asprintf_errstring(ldb,
2645                                "%08X: %s - check_password_restrictions: "
2646                                "The old password specified doesn't match!",
2647                                W_ERROR_V(*werror),
2648                                ldb_strerror(ret));
2649         return ret;
2650 }
2651
2652 static int check_password_restrictions(struct setup_password_fields_io *io, WERROR *werror)
2653 {
2654         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2655         int ret;
2656         struct loadparm_context *lp_ctx =
2657                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
2658                                          struct loadparm_context);
2659
2660         *werror = WERR_INVALID_PARAMETER;
2661
2662         if (!io->ac->update_password) {
2663                 return LDB_SUCCESS;
2664         }
2665
2666         /* First check the old password is correct, for password changes */
2667         if (!io->ac->pwd_reset) {
2668                 bool nt_hash_checked = false;
2669
2670                 /* we need the old nt or lm hash given by the client */
2671                 if (!io->og.nt_hash && !io->og.lm_hash) {
2672                         ldb_asprintf_errstring(ldb,
2673                                 "check_password_restrictions: "
2674                                 "You need to provide the old password in order "
2675                                 "to change it!");
2676                         return LDB_ERR_UNWILLING_TO_PERFORM;
2677                 }
2678
2679                 /* The password modify through the NT hash is encouraged and
2680                    has no problems at all */
2681                 if (io->og.nt_hash) {
2682                         if (!io->o.nt_hash || memcmp(io->og.nt_hash->hash, io->o.nt_hash->hash, 16) != 0) {
2683                                 return make_error_and_update_badPwdCount(io, werror);
2684                         }
2685
2686                         nt_hash_checked = true;
2687                 }
2688
2689                 /* But it is also possible to change a password by the LM hash
2690                  * alone for compatibility reasons. This check is optional if
2691                  * the NT hash was already checked - otherwise it's mandatory.
2692                  * (as the SAMR operations request it). */
2693                 if (io->og.lm_hash) {
2694                         if ((!io->o.lm_hash && !nt_hash_checked)
2695                             || (io->o.lm_hash && memcmp(io->og.lm_hash->hash, io->o.lm_hash->hash, 16) != 0)) {
2696                                 return make_error_and_update_badPwdCount(io, werror);
2697                         }
2698                 }
2699         }
2700
2701         if (io->u.restrictions == 0) {
2702                 /* FIXME: Is this right? */
2703                 return LDB_SUCCESS;
2704         }
2705
2706         /* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */
2707         if ((io->u.pwdLastSet - io->ac->status->domain_data.minPwdAge > io->g.last_set) &&
2708             !io->ac->pwd_reset)
2709         {
2710                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2711                 *werror = WERR_PASSWORD_RESTRICTION;
2712                 ldb_asprintf_errstring(ldb,
2713                         "%08X: %s - check_password_restrictions: "
2714                         "password is too young to change!",
2715                         W_ERROR_V(*werror),
2716                         ldb_strerror(ret));
2717                 return ret;
2718         }
2719
2720         /*
2721          * Fundamental password checks done by the call
2722          * "samdb_check_password".
2723          * It is also in use by "dcesrv_samr_ValidatePassword".
2724          */
2725         if (io->n.cleartext_utf8 != NULL) {
2726                 enum samr_ValidationStatus vstat;
2727                 vstat = samdb_check_password(io->ac, lp_ctx,
2728                                              io->n.cleartext_utf8,
2729                                              io->ac->status->domain_data.pwdProperties,
2730                                              io->ac->status->domain_data.minPwdLength);
2731                 switch (vstat) {
2732                 case SAMR_VALIDATION_STATUS_SUCCESS:
2733                                 /* perfect -> proceed! */
2734                         break;
2735
2736                 case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT:
2737                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2738                         *werror = WERR_PASSWORD_RESTRICTION;
2739                         ldb_asprintf_errstring(ldb,
2740                                 "%08X: %s - check_password_restrictions: "
2741                                 "the password is too short. It should be equal or longer than %u characters!",
2742                                 W_ERROR_V(*werror),
2743                                 ldb_strerror(ret),
2744                                 io->ac->status->domain_data.minPwdLength);
2745                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PASSWORD_TOO_SHORT;
2746                         return ret;
2747
2748                 case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH:
2749                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2750                         *werror = WERR_PASSWORD_RESTRICTION;
2751                         ldb_asprintf_errstring(ldb,
2752                                 "%08X: %s - check_password_restrictions: "
2753                                 "the password does not meet the complexity criteria!",
2754                                 W_ERROR_V(*werror),
2755                                 ldb_strerror(ret));
2756                         io->ac->status->reject_reason = SAM_PWD_CHANGE_NOT_COMPLEX;
2757                         return ret;
2758
2759                 default:
2760                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2761                         *werror = WERR_PASSWORD_RESTRICTION;
2762                         ldb_asprintf_errstring(ldb,
2763                                 "%08X: %s - check_password_restrictions: "
2764                                 "the password doesn't fit due to a miscellaneous restriction!",
2765                                 W_ERROR_V(*werror),
2766                                 ldb_strerror(ret));
2767                         return ret;
2768                 }
2769         }
2770
2771         if (io->ac->pwd_reset) {
2772                 *werror = WERR_OK;
2773                 return LDB_SUCCESS;
2774         }
2775
2776         if (io->n.nt_hash) {
2777                 uint32_t i;
2778
2779                 /* checks the NT hash password history */
2780                 for (i = 0; i < io->o.nt_history_len; i++) {
2781                         ret = memcmp(io->n.nt_hash, io->o.nt_history[i].hash, 16);
2782                         if (ret == 0) {
2783                                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2784                                 *werror = WERR_PASSWORD_RESTRICTION;
2785                                 ldb_asprintf_errstring(ldb,
2786                                         "%08X: %s - check_password_restrictions: "
2787                                         "the password was already used (in history)!",
2788                                         W_ERROR_V(*werror),
2789                                         ldb_strerror(ret));
2790                                 io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
2791                                 return ret;
2792                         }
2793                 }
2794         }
2795
2796         if (io->n.lm_hash) {
2797                 uint32_t i;
2798
2799                 /* checks the LM hash password history */
2800                 for (i = 0; i < io->o.lm_history_len; i++) {
2801                         ret = memcmp(io->n.lm_hash, io->o.lm_history[i].hash, 16);
2802                         if (ret == 0) {
2803                                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2804                                 *werror = WERR_PASSWORD_RESTRICTION;
2805                                 ldb_asprintf_errstring(ldb,
2806                                         "%08X: %s - check_password_restrictions: "
2807                                         "the password was already used (in history)!",
2808                                         W_ERROR_V(*werror),
2809                                         ldb_strerror(ret));
2810                                 io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
2811                                 return ret;
2812                         }
2813                 }
2814         }
2815
2816         /* are all password changes disallowed? */
2817         if (io->ac->status->domain_data.pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
2818                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2819                 *werror = WERR_PASSWORD_RESTRICTION;
2820                 ldb_asprintf_errstring(ldb,
2821                         "%08X: %s - check_password_restrictions: "
2822                         "password changes disabled!",
2823                         W_ERROR_V(*werror),
2824                         ldb_strerror(ret));
2825                 return ret;
2826         }
2827
2828         /* can this user change the password? */
2829         if (io->u.userAccountControl & UF_PASSWD_CANT_CHANGE) {
2830                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2831                 *werror = WERR_PASSWORD_RESTRICTION;
2832                 ldb_asprintf_errstring(ldb,
2833                         "%08X: %s - check_password_restrictions: "
2834                         "password can't be changed on this account!",
2835                         W_ERROR_V(*werror),
2836                         ldb_strerror(ret));
2837                 return ret;
2838         }
2839
2840         return LDB_SUCCESS;
2841 }
2842
2843 static int check_password_restrictions_and_log(struct setup_password_fields_io *io)
2844 {
2845         WERROR werror;
2846         int ret = check_password_restrictions(io, &werror);
2847         struct ph_context *ac = io->ac;
2848         /*
2849          * Password resets are not authentication events, and if the
2850          * upper layer checked the password and supplied the hash
2851          * values as proof, then this is also not an authentication
2852          * even at this layer (already logged).  This is to log LDAP
2853          * password changes.
2854          */
2855
2856         /* Do not record a failure in the auth log below in the success case */
2857         if (ret == LDB_SUCCESS) {
2858                 werror = WERR_OK;
2859         }
2860
2861         if (ac->pwd_reset == false && ac->change == NULL) {
2862                 struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
2863                 struct imessaging_context *msg_ctx;
2864                 struct loadparm_context *lp_ctx
2865                         = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
2866                                                 struct loadparm_context);
2867                 NTSTATUS status = werror_to_ntstatus(werror);
2868                 const char *domain_name = lpcfg_sam_name(lp_ctx);
2869                 void *opaque_remote_address = NULL;
2870                 /*
2871                  * Forcing this via the NTLM auth structure is not ideal, but
2872                  * it is the most practical option right now, and ensures the
2873                  * logs are consistent, even if some elements are always NULL.
2874                  */
2875                 struct auth_usersupplied_info ui = {
2876                         .mapped_state = true,
2877                         .was_mapped = true,
2878                         .client = {
2879                                 .account_name = io->u.sAMAccountName,
2880                                 .domain_name = domain_name,
2881                         },
2882                         .mapped = {
2883                                 .account_name = io->u.sAMAccountName,
2884                                 .domain_name = domain_name,
2885                         },
2886                         .service_description = "LDAP Password Change",
2887                         .auth_description = "LDAP Modify",
2888                         .password_type = "plaintext"
2889                 };
2890
2891                 opaque_remote_address = ldb_get_opaque(ldb,
2892                                                        "remoteAddress");
2893                 if (opaque_remote_address == NULL) {
2894                         ldb_asprintf_errstring(ldb,
2895                                                "Failed to obtain remote address for "
2896                                                "the LDAP client while changing the "
2897                                                "password");
2898                         return LDB_ERR_OPERATIONS_ERROR;
2899                 }
2900                 ui.remote_host = talloc_get_type(opaque_remote_address,
2901                                                  struct tsocket_address);
2902
2903                 msg_ctx = imessaging_client_init(ac, lp_ctx,
2904                                                  ldb_get_event_context(ldb));
2905                 if (!msg_ctx) {
2906                         ldb_asprintf_errstring(ldb,
2907                                                "Failed to generate client messaging context in %s",
2908                                                lpcfg_imessaging_path(ac, lp_ctx));
2909                         return LDB_ERR_OPERATIONS_ERROR;
2910                 }
2911                 log_authentication_event(msg_ctx,
2912                                          lp_ctx,
2913                                          &ui,
2914                                          status,
2915                                          domain_name,
2916                                          io->u.sAMAccountName,
2917                                          NULL,
2918                                          io->u.account_sid);
2919
2920         }
2921         return ret;
2922 }
2923
2924 static int update_final_msg(struct setup_password_fields_io *io)
2925 {
2926         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2927         int ret;
2928         int el_flags = 0;
2929         bool update_password = io->ac->update_password;
2930         bool update_scb = io->ac->update_password;
2931
2932         /*
2933          * If we add a user without initial password,
2934          * we need to add replication meta data for
2935          * following attributes:
2936          * - unicodePwd
2937          * - dBCSPwd
2938          * - ntPwdHistory
2939          * - lmPwdHistory
2940          *
2941          * If we add a user with initial password or a
2942          * password is changed of an existing user,
2943          * we need to replace the following attributes
2944          * with a forced meta data update, e.g. also
2945          * when updating an empty attribute with an empty value:
2946          * - unicodePwd
2947          * - dBCSPwd
2948          * - ntPwdHistory
2949          * - lmPwdHistory
2950          * - supplementalCredentials
2951          */
2952
2953         switch (io->ac->req->operation) {
2954         case LDB_ADD:
2955                 update_password = true;
2956                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
2957                 break;
2958         case LDB_MODIFY:
2959                 el_flags |= LDB_FLAG_MOD_REPLACE;
2960                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
2961                 break;
2962         default:
2963                 return ldb_module_operr(io->ac->module);
2964         }
2965
2966         if (update_password) {
2967                 ret = ldb_msg_add_empty(io->ac->update_msg,
2968                                         "unicodePwd",
2969                                         el_flags, NULL);
2970                 if (ret != LDB_SUCCESS) {
2971                         return ret;
2972                 }
2973                 ret = ldb_msg_add_empty(io->ac->update_msg,
2974                                         "dBCSPwd",
2975                                         el_flags, NULL);
2976                 if (ret != LDB_SUCCESS) {
2977                         return ret;
2978                 }
2979                 ret = ldb_msg_add_empty(io->ac->update_msg,
2980                                         "ntPwdHistory",
2981                                         el_flags, NULL);
2982                 if (ret != LDB_SUCCESS) {
2983                         return ret;
2984                 }
2985                 ret = ldb_msg_add_empty(io->ac->update_msg,
2986                                         "lmPwdHistory",
2987                                         el_flags, NULL);
2988                 if (ret != LDB_SUCCESS) {
2989                         return ret;
2990                 }
2991         }
2992         if (update_scb) {
2993                 ret = ldb_msg_add_empty(io->ac->update_msg,
2994                                         "supplementalCredentials",
2995                                         el_flags, NULL);
2996                 if (ret != LDB_SUCCESS) {
2997                         return ret;
2998                 }
2999         }
3000         if (io->ac->update_lastset) {
3001                 ret = ldb_msg_add_empty(io->ac->update_msg,
3002                                         "pwdLastSet",
3003                                         el_flags, NULL);
3004                 if (ret != LDB_SUCCESS) {
3005                         return ret;
3006                 }
3007         }
3008
3009         if (io->g.nt_hash != NULL) {
3010                 ret = samdb_msg_add_hash(ldb, io->ac,
3011                                          io->ac->update_msg,
3012                                          "unicodePwd",
3013                                          io->g.nt_hash);
3014                 if (ret != LDB_SUCCESS) {
3015                         return ret;
3016                 }
3017         }
3018         if (io->g.lm_hash != NULL) {
3019                 ret = samdb_msg_add_hash(ldb, io->ac,
3020                                          io->ac->update_msg,
3021                                          "dBCSPwd",
3022                                          io->g.lm_hash);
3023                 if (ret != LDB_SUCCESS) {
3024                         return ret;
3025                 }
3026         }
3027         if (io->g.nt_history_len > 0) {
3028                 ret = samdb_msg_add_hashes(ldb, io->ac,
3029                                            io->ac->update_msg,
3030                                            "ntPwdHistory",
3031                                            io->g.nt_history,
3032                                            io->g.nt_history_len);
3033                 if (ret != LDB_SUCCESS) {
3034                         return ret;
3035                 }
3036         }
3037         if (io->g.lm_history_len > 0) {
3038                 ret = samdb_msg_add_hashes(ldb, io->ac,
3039                                            io->ac->update_msg,
3040                                            "lmPwdHistory",
3041                                            io->g.lm_history,
3042                                            io->g.lm_history_len);
3043                 if (ret != LDB_SUCCESS) {
3044                         return ret;
3045                 }
3046         }
3047         if (io->g.supplemental.length > 0) {
3048                 ret = ldb_msg_add_value(io->ac->update_msg,
3049                                         "supplementalCredentials",
3050                                         &io->g.supplemental, NULL);
3051                 if (ret != LDB_SUCCESS) {
3052                         return ret;
3053                 }
3054         }
3055         if (io->ac->update_lastset) {
3056                 ret = samdb_msg_add_uint64(ldb, io->ac,
3057                                            io->ac->update_msg,
3058                                            "pwdLastSet",
3059                                            io->g.last_set);
3060                 if (ret != LDB_SUCCESS) {
3061                         return ret;
3062                 }
3063         }
3064
3065         return LDB_SUCCESS;
3066 }
3067
3068 /*
3069  * This is intended for use by the "password_hash" module since there
3070  * password changes can be specified through one message element with the
3071  * new password (to set) and another one with the old password (to unset).
3072  *
3073  * The first which sets a password (new value) can have flags
3074  * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
3075  * for entries). The latter (old value) has always specified
3076  * LDB_FLAG_MOD_DELETE.
3077  *
3078  * Returns LDB_ERR_CONSTRAINT_VIOLATION and LDB_ERR_UNWILLING_TO_PERFORM if
3079  * matching message elements are malformed in respect to the set/change rules.
3080  * Otherwise it returns LDB_SUCCESS.
3081  */
3082 static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
3083                                         const char *name,
3084                                         enum ldb_request_type operation,
3085                                         const struct ldb_val **new_val,
3086                                         const struct ldb_val **old_val)
3087 {
3088         unsigned int i;
3089
3090         *new_val = NULL;
3091         *old_val = NULL;
3092
3093         if (msg == NULL) {
3094                 return LDB_SUCCESS;
3095         }
3096
3097         for (i = 0; i < msg->num_elements; i++) {
3098                 if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
3099                         continue;
3100                 }
3101
3102                 if ((operation == LDB_MODIFY) &&
3103                     (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE)) {
3104                         /* 0 values are allowed */
3105                         if (msg->elements[i].num_values == 1) {
3106                                 *old_val = &msg->elements[i].values[0];
3107                         } else if (msg->elements[i].num_values > 1) {
3108                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3109                         }
3110                 } else if ((operation == LDB_MODIFY) &&
3111                            (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE)) {
3112                         if (msg->elements[i].num_values > 0) {
3113                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3114                         } else {
3115                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3116                         }
3117                 } else {
3118                         /* Add operations and LDB_FLAG_MOD_ADD */
3119                         if (msg->elements[i].num_values > 0) {
3120                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3121                         } else {
3122                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3123                         }
3124                 }
3125         }
3126
3127         return LDB_SUCCESS;
3128 }
3129
3130 static int setup_io(struct ph_context *ac, 
3131                     const struct ldb_message *client_msg,
3132                     const struct ldb_message *existing_msg,
3133                     struct setup_password_fields_io *io) 
3134
3135         const struct ldb_val *quoted_utf16, *old_quoted_utf16, *lm_hash, *old_lm_hash;
3136         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3137         struct loadparm_context *lp_ctx = talloc_get_type(
3138                 ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
3139         int ret;
3140         const struct ldb_message *info_msg = NULL;
3141         struct dom_sid *account_sid = NULL;
3142         int rodc_krbtgt = 0;
3143
3144         ZERO_STRUCTP(io);
3145
3146         /* Some operations below require kerberos contexts */
3147
3148         if (existing_msg != NULL) {
3149                 /*
3150                  * This is a modify operation
3151                  */
3152                 info_msg = existing_msg;
3153         } else {
3154                 /*
3155                  * This is an add operation
3156                  */
3157                 info_msg = client_msg;
3158         }
3159
3160         if (smb_krb5_init_context(ac,
3161                                   (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
3162                                   &io->smb_krb5_context) != 0) {
3163                 return ldb_operr(ldb);
3164         }
3165
3166         io->ac                          = ac;
3167
3168         io->u.userAccountControl        = ldb_msg_find_attr_as_uint(info_msg,
3169                                                                     "userAccountControl", 0);
3170         if (info_msg == existing_msg) {
3171                 /*
3172                  * We only take pwdLastSet from the existing object
3173                  * otherwise we leave it as 0.
3174                  *
3175                  * If no attribute is available, e.g. on deleted objects
3176                  * we remember that as UINT64_MAX.
3177                  */
3178                 io->u.pwdLastSet = samdb_result_nttime(info_msg, "pwdLastSet",
3179                                                        UINT64_MAX);
3180         }
3181         io->u.sAMAccountName            = ldb_msg_find_attr_as_string(info_msg,
3182                                                                       "sAMAccountName", NULL);
3183         io->u.user_principal_name       = ldb_msg_find_attr_as_string(info_msg,
3184                                                                       "userPrincipalName", NULL);
3185         io->u.is_computer               = ldb_msg_check_string_attribute(info_msg, "objectClass", "computer");
3186
3187         /* Ensure it has an objectSID too */
3188         io->u.account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
3189         if (io->u.account_sid != NULL) {
3190                 NTSTATUS status;
3191                 uint32_t rid = 0;
3192
3193                 status = dom_sid_split_rid(account_sid, io->u.account_sid, NULL, &rid);
3194                 if (NT_STATUS_IS_OK(status)) {
3195                         if (rid == DOMAIN_RID_KRBTGT) {
3196                                 io->u.is_krbtgt = true;
3197                         }
3198                 }
3199         }
3200
3201         rodc_krbtgt = ldb_msg_find_attr_as_int(info_msg,
3202                         "msDS-SecondaryKrbTgtNumber", 0);
3203         if (rodc_krbtgt != 0) {
3204                 io->u.is_krbtgt = true;
3205         }
3206
3207         if (io->u.sAMAccountName == NULL) {
3208                 ldb_asprintf_errstring(ldb,
3209                                        "setup_io: sAMAccountName attribute is missing on %s for attempted password set/change",
3210                                        ldb_dn_get_linearized(info_msg->dn));
3211
3212                 return LDB_ERR_CONSTRAINT_VIOLATION;
3213         }
3214
3215         if (io->u.userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
3216                 struct ldb_control *permit_trust = ldb_request_get_control(ac->req,
3217                                 DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
3218
3219                 if (permit_trust == NULL) {
3220                         ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
3221                         ldb_asprintf_errstring(ldb,
3222                                 "%08X: %s - setup_io: changing the interdomain trust password "
3223                                 "on %s not allowed via LDAP. Use LSA or NETLOGON",
3224                                 W_ERROR_V(WERR_ACCESS_DENIED),
3225                                 ldb_strerror(ret),
3226                                 ldb_dn_get_linearized(info_msg->dn));
3227                         return ret;
3228                 }
3229         }
3230
3231         /* Only non-trust accounts have restrictions (possibly this test is the
3232          * wrong way around, but we like to be restrictive if possible */
3233         io->u.restrictions = !(io->u.userAccountControl
3234                 & (UF_INTERDOMAIN_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT
3235                         | UF_SERVER_TRUST_ACCOUNT));
3236
3237         if (io->u.is_krbtgt) {
3238                 io->u.restrictions = 0;
3239                 io->ac->status->domain_data.pwdHistoryLength =
3240                         MAX(io->ac->status->domain_data.pwdHistoryLength, 3);
3241         }
3242
3243         if (ac->userPassword) {
3244                 ret = msg_find_old_and_new_pwd_val(client_msg, "userPassword",
3245                                                    ac->req->operation,
3246                                                    &io->n.cleartext_utf8,
3247                                                    &io->og.cleartext_utf8);
3248                 if (ret != LDB_SUCCESS) {
3249                         ldb_asprintf_errstring(ldb,
3250                                 "setup_io: "
3251                                 "it's only allowed to set the old password once!");
3252                         return ret;
3253                 }
3254         }
3255
3256         if (io->n.cleartext_utf8 != NULL) {
3257                 struct ldb_val *cleartext_utf8_blob;
3258                 char *p;
3259
3260                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
3261                 if (!cleartext_utf8_blob) {
3262                         return ldb_oom(ldb);
3263                 }
3264
3265                 *cleartext_utf8_blob = *io->n.cleartext_utf8;
3266
3267                 /* make sure we have a null terminated string */
3268                 p = talloc_strndup(cleartext_utf8_blob,
3269                                    (const char *)io->n.cleartext_utf8->data,
3270                                    io->n.cleartext_utf8->length);
3271                 if ((p == NULL) && (io->n.cleartext_utf8->length > 0)) {
3272                         return ldb_oom(ldb);
3273                 }
3274                 cleartext_utf8_blob->data = (uint8_t *)p;
3275
3276                 io->n.cleartext_utf8 = cleartext_utf8_blob;
3277         }
3278
3279         ret = msg_find_old_and_new_pwd_val(client_msg, "clearTextPassword",
3280                                            ac->req->operation,
3281                                            &io->n.cleartext_utf16,
3282                                            &io->og.cleartext_utf16);
3283         if (ret != LDB_SUCCESS) {
3284                 ldb_asprintf_errstring(ldb,
3285                         "setup_io: "
3286                         "it's only allowed to set the old password once!");
3287                 return ret;
3288         }
3289
3290         /* this rather strange looking piece of code is there to
3291            handle a ldap client setting a password remotely using the
3292            unicodePwd ldap field. The syntax is that the password is
3293            in UTF-16LE, with a " at either end. Unfortunately the
3294            unicodePwd field is also used to store the nt hashes
3295            internally in Samba, and is used in the nt hash format on
3296            the wire in DRS replication, so we have a single name for
3297            two distinct values. The code below leaves us with a small
3298            chance (less than 1 in 2^32) of a mixup, if someone manages
3299            to create a MD4 hash which starts and ends in 0x22 0x00, as
3300            that would then be treated as a UTF16 password rather than
3301            a nthash */
3302
3303         ret = msg_find_old_and_new_pwd_val(client_msg, "unicodePwd",
3304                                            ac->req->operation,
3305                                            &quoted_utf16,
3306                                            &old_quoted_utf16);
3307         if (ret != LDB_SUCCESS) {
3308                 ldb_asprintf_errstring(ldb,
3309                         "setup_io: "
3310                         "it's only allowed to set the old password once!");
3311                 return ret;
3312         }
3313
3314         /* Checks and converts the actual "unicodePwd" attribute */
3315         if (!ac->hash_values &&
3316             quoted_utf16 &&
3317             quoted_utf16->length >= 4 &&
3318             quoted_utf16->data[0] == '"' &&
3319             quoted_utf16->data[1] == 0 &&
3320             quoted_utf16->data[quoted_utf16->length-2] == '"' &&
3321             quoted_utf16->data[quoted_utf16->length-1] == 0) {
3322                 struct ldb_val *quoted_utf16_2;
3323
3324                 if (io->n.cleartext_utf16) {
3325                         /* refuse the change if someone wants to change with
3326                            with both UTF16 possibilities at the same time... */
3327                         ldb_asprintf_errstring(ldb,
3328                                 "setup_io: "
3329                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3330                         return LDB_ERR_UNWILLING_TO_PERFORM;
3331                 }
3332
3333                 /*
3334                  * adapt the quoted UTF16 string to be a real
3335                  * cleartext one
3336                  */
3337                 quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3338                 if (quoted_utf16_2 == NULL) {
3339                         return ldb_oom(ldb);
3340                 }
3341
3342                 quoted_utf16_2->data = quoted_utf16->data + 2;
3343                 quoted_utf16_2->length = quoted_utf16->length-4;
3344                 io->n.cleartext_utf16 = quoted_utf16_2;
3345                 io->n.nt_hash = NULL;
3346
3347         } else if (quoted_utf16) {
3348                 /* We have only the hash available -> so no plaintext here */
3349                 if (!ac->hash_values) {
3350                         /* refuse the change if someone wants to change
3351                            the hash without control specified... */
3352                         ldb_asprintf_errstring(ldb,
3353                                 "setup_io: "
3354                                 "it's not allowed to set the NT hash password directly'");
3355                         /* this looks odd but this is what Windows does:
3356                            returns "UNWILLING_TO_PERFORM" on wrong
3357                            password sets and "CONSTRAINT_VIOLATION" on
3358                            wrong password changes. */
3359                         if (old_quoted_utf16 == NULL) {
3360                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3361                         }
3362
3363                         return LDB_ERR_CONSTRAINT_VIOLATION;
3364                 }
3365
3366                 io->n.nt_hash = talloc(io->ac, struct samr_Password);
3367                 memcpy(io->n.nt_hash->hash, quoted_utf16->data,
3368                        MIN(quoted_utf16->length, sizeof(io->n.nt_hash->hash)));
3369         }
3370
3371         /* Checks and converts the previous "unicodePwd" attribute */
3372         if (!ac->hash_values &&
3373             old_quoted_utf16 &&
3374             old_quoted_utf16->length >= 4 &&
3375             old_quoted_utf16->data[0] == '"' &&
3376             old_quoted_utf16->data[1] == 0 &&
3377             old_quoted_utf16->data[old_quoted_utf16->length-2] == '"' &&
3378             old_quoted_utf16->data[old_quoted_utf16->length-1] == 0) {
3379                 struct ldb_val *old_quoted_utf16_2;
3380
3381                 if (io->og.cleartext_utf16) {
3382                         /* refuse the change if someone wants to change with
3383                            both UTF16 possibilities at the same time... */
3384                         ldb_asprintf_errstring(ldb,
3385                                 "setup_io: "
3386                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3387                         return LDB_ERR_UNWILLING_TO_PERFORM;
3388                 }
3389
3390                 /*
3391                  * adapt the quoted UTF16 string to be a real
3392                  * cleartext one
3393                  */
3394                 old_quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3395                 if (old_quoted_utf16_2 == NULL) {
3396                         return ldb_oom(ldb);
3397                 }
3398
3399                 old_quoted_utf16_2->data = old_quoted_utf16->data + 2;
3400                 old_quoted_utf16_2->length = old_quoted_utf16->length-4;
3401
3402                 io->og.cleartext_utf16 = old_quoted_utf16_2;
3403                 io->og.nt_hash = NULL;
3404         } else if (old_quoted_utf16) {
3405                 /* We have only the hash available -> so no plaintext here */
3406                 if (!ac->hash_values) {
3407                         /* refuse the change if someone wants to change
3408                            the hash without control specified... */
3409                         ldb_asprintf_errstring(ldb,
3410                                 "setup_io: "
3411                                 "it's not allowed to set the NT hash password directly'");
3412                         return LDB_ERR_UNWILLING_TO_PERFORM;
3413                 }
3414
3415                 io->og.nt_hash = talloc(io->ac, struct samr_Password);
3416                 memcpy(io->og.nt_hash->hash, old_quoted_utf16->data,
3417                        MIN(old_quoted_utf16->length, sizeof(io->og.nt_hash->hash)));
3418         }
3419
3420         /* Handles the "dBCSPwd" attribute (LM hash) */
3421         io->n.lm_hash = NULL; io->og.lm_hash = NULL;
3422         ret = msg_find_old_and_new_pwd_val(client_msg, "dBCSPwd",
3423                                            ac->req->operation,
3424                                            &lm_hash, &old_lm_hash);
3425         if (ret != LDB_SUCCESS) {
3426                 ldb_asprintf_errstring(ldb,
3427                         "setup_io: "
3428                         "it's only allowed to set the old password once!");
3429                 return ret;
3430         }
3431
3432         if (((lm_hash != NULL) || (old_lm_hash != NULL)) && (!ac->hash_values)) {
3433                 /* refuse the change if someone wants to change the hash
3434                    without control specified... */
3435                 ldb_asprintf_errstring(ldb,
3436                         "setup_io: "
3437                         "it's not allowed to set the LM hash password directly'");
3438                 return LDB_ERR_UNWILLING_TO_PERFORM;
3439         }
3440
3441         if (lpcfg_lanman_auth(lp_ctx) && (lm_hash != NULL)) {
3442                 io->n.lm_hash = talloc(io->ac, struct samr_Password);
3443                 memcpy(io->n.lm_hash->hash, lm_hash->data, MIN(lm_hash->length,
3444                        sizeof(io->n.lm_hash->hash)));
3445         }
3446         if (lpcfg_lanman_auth(lp_ctx) && (old_lm_hash != NULL)) {
3447                 io->og.lm_hash = talloc(io->ac, struct samr_Password);
3448                 memcpy(io->og.lm_hash->hash, old_lm_hash->data, MIN(old_lm_hash->length,
3449                        sizeof(io->og.lm_hash->hash)));
3450         }
3451
3452         /*
3453          * Handles the password change control if it's specified. It has the
3454          * precedance and overrides already specified old password values of
3455          * change requests (but that shouldn't happen since the control is
3456          * fully internal and only used in conjunction with replace requests!).
3457          */
3458         if (ac->change != NULL) {
3459                 io->og.nt_hash = NULL;
3460                 if (ac->change->old_nt_pwd_hash != NULL) {
3461                         io->og.nt_hash = talloc_memdup(io->ac,
3462                                                        ac->change->old_nt_pwd_hash,
3463                                                        sizeof(struct samr_Password));
3464                 }
3465                 io->og.lm_hash = NULL;
3466                 if (lpcfg_lanman_auth(lp_ctx) && (ac->change->old_lm_pwd_hash != NULL)) {
3467                         io->og.lm_hash = talloc_memdup(io->ac,
3468                                                        ac->change->old_lm_pwd_hash,
3469                                                        sizeof(struct samr_Password));
3470                 }
3471         }
3472
3473         /* refuse the change if someone wants to change the clear-
3474            text and supply his own hashes at the same time... */
3475         if ((io->n.cleartext_utf8 || io->n.cleartext_utf16)
3476                         && (io->n.nt_hash || io->n.lm_hash)) {
3477                 ldb_asprintf_errstring(ldb,
3478                         "setup_io: "
3479                         "it's only allowed to set the password in form of cleartext attributes or as hashes");
3480                 return LDB_ERR_UNWILLING_TO_PERFORM;
3481         }
3482
3483         /* refuse the change if someone wants to change the password
3484            using both plaintext methods (UTF8 and UTF16) at the same time... */
3485         if (io->n.cleartext_utf8 && io->n.cleartext_utf16) {
3486                 ldb_asprintf_errstring(ldb,
3487                         "setup_io: "
3488                         "it's only allowed to set the cleartext password as 'unicodePwd' or as 'userPassword' or as 'clearTextPassword'");
3489                 return LDB_ERR_UNWILLING_TO_PERFORM;
3490         }
3491
3492         /* refuse the change if someone tries to set/change the password by
3493          * the lanman hash alone and we've deactivated that mechanism. This
3494          * would end in an account without any password! */
3495         if (io->ac->update_password
3496             && (!io->n.cleartext_utf8) && (!io->n.cleartext_utf16)
3497             && (!io->n.nt_hash) && (!io->n.lm_hash)) {
3498                 ldb_asprintf_errstring(ldb,
3499                         "setup_io: "
3500                         "It's not possible to delete the password (changes using the LAN Manager hash alone could be deactivated)!");
3501                 /* on "userPassword" and "clearTextPassword" we've to return
3502                  * something different, since these are virtual attributes */
3503                 if ((ldb_msg_find_element(client_msg, "userPassword") != NULL) ||
3504                     (ldb_msg_find_element(client_msg, "clearTextPassword") != NULL)) {
3505                         return LDB_ERR_CONSTRAINT_VIOLATION;
3506                 }
3507                 return LDB_ERR_UNWILLING_TO_PERFORM;
3508         }
3509
3510         /* refuse the change if someone wants to compare against a plaintext
3511            or hash at the same time for a "password modify" operation... */
3512         if ((io->og.cleartext_utf8 || io->og.cleartext_utf16)
3513             && (io->og.nt_hash || io->og.lm_hash)) {
3514                 ldb_asprintf_errstring(ldb,
3515                         "setup_io: "
3516                         "it's only allowed to provide the old password in form of cleartext attributes or as hashes");
3517                 return LDB_ERR_UNWILLING_TO_PERFORM;
3518         }
3519
3520         /* refuse the change if someone wants to compare against both
3521          * plaintexts at the same time for a "password modify" operation... */
3522         if (io->og.cleartext_utf8 && io->og.cleartext_utf16) {
3523                 ldb_asprintf_errstring(ldb,
3524                         "setup_io: "
3525                         "it's only allowed to provide the old cleartext password as 'unicodePwd' or as 'userPassword' or as 'clearTextPassword'");
3526                 return LDB_ERR_UNWILLING_TO_PERFORM;
3527         }
3528
3529         /* Decides if we have a password modify or password reset operation */
3530         if (ac->req->operation == LDB_ADD) {
3531                 /* On "add" we have only "password reset" */
3532                 ac->pwd_reset = true;
3533         } else if (ac->req->operation == LDB_MODIFY) {
3534                 if (io->og.cleartext_utf8 || io->og.cleartext_utf16
3535                     || io->og.nt_hash || io->og.lm_hash) {
3536                         /* If we have an old password specified then for sure it
3537                          * is a user "password change" */
3538                         ac->pwd_reset = false;
3539                 } else {
3540                         /* Otherwise we have also here a "password reset" */
3541                         ac->pwd_reset = true;
3542                 }
3543         } else {
3544                 /* this shouldn't happen */
3545                 return ldb_operr(ldb);
3546         }
3547
3548         if (io->u.is_krbtgt) {
3549                 size_t min = 196;
3550                 size_t max = 255;
3551                 size_t diff = max - min;
3552                 size_t len = max;
3553                 struct ldb_val *krbtgt_utf16 = NULL;
3554
3555                 if (!ac->pwd_reset) {
3556                         return dsdb_module_werror(ac->module,
3557                                         LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
3558                                         WERR_DS_ATT_ALREADY_EXISTS,
3559                                         "Password change on krbtgt not permitted!");
3560                 }
3561
3562                 if (io->n.cleartext_utf16 == NULL) {
3563                         return dsdb_module_werror(ac->module,
3564                                         LDB_ERR_UNWILLING_TO_PERFORM,
3565                                         WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
3566                                         "Password reset on krbtgt requires UTF16!");
3567                 }
3568
3569                 /*
3570                  * Instead of taking the callers value,
3571                  * we just generate a new random value here.
3572                  *
3573                  * Include null termination in the array.
3574                  */
3575                 if (diff > 0) {
3576                         size_t tmp;
3577
3578                         generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
3579
3580                         tmp %= diff;
3581
3582                         len = min + tmp;
3583                 }
3584
3585                 krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
3586                 if (krbtgt_utf16 == NULL) {
3587                         return ldb_oom(ldb);
3588                 }
3589
3590                 *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
3591                                                       (len+1)*2);
3592                 if (krbtgt_utf16->data == NULL) {
3593                         return ldb_oom(ldb);
3594                 }
3595                 krbtgt_utf16->length = len * 2;
3596                 generate_secret_buffer(krbtgt_utf16->data,
3597                                        krbtgt_utf16->length);
3598                 io->n.cleartext_utf16 = krbtgt_utf16;
3599         }
3600
3601         if (existing_msg != NULL) {
3602                 NTSTATUS status;
3603
3604                 if (ac->pwd_reset) {
3605                         /* Get the old password from the database */
3606                         status = samdb_result_passwords_no_lockout(ac,
3607                                                                    lp_ctx,
3608                                                                    existing_msg,
3609                                                                    &io->o.lm_hash,
3610                                                                    &io->o.nt_hash);
3611                 } else {
3612                         /* Get the old password from the database */
3613                         status = samdb_result_passwords(ac,
3614                                                         lp_ctx,
3615                                                         existing_msg,
3616                                                         &io->o.lm_hash,
3617                                                         &io->o.nt_hash);
3618                 }
3619
3620                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_LOCKED_OUT)) {
3621                         return dsdb_module_werror(ac->module,
3622                                                   LDB_ERR_CONSTRAINT_VIOLATION,
3623                                                   WERR_ACCOUNT_LOCKED_OUT,
3624                                                   "Password change not permitted,"
3625                                                   " account locked out!");
3626                 }
3627
3628                 if (!NT_STATUS_IS_OK(status)) {
3629                         /*
3630                          * This only happens if the database has gone weird,
3631                          * not if we are just missing the passwords
3632                          */
3633                         return ldb_operr(ldb);
3634                 }
3635
3636                 io->o.nt_history_len = samdb_result_hashes(ac, existing_msg,
3637                                                            "ntPwdHistory",
3638                                                            &io->o.nt_history);
3639                 io->o.lm_history_len = samdb_result_hashes(ac, existing_msg,
3640                                                            "lmPwdHistory",
3641                                                            &io->o.lm_history);
3642                 io->o.supplemental = ldb_msg_find_ldb_val(existing_msg,
3643                                                           "supplementalCredentials");
3644
3645                 if (io->o.supplemental != NULL) {
3646                         enum ndr_err_code ndr_err;
3647
3648                         ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac,
3649                                         &io->o.scb,
3650                                         (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
3651                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
3652                                 status = ndr_map_error2ntstatus(ndr_err);
3653                                 ldb_asprintf_errstring(ldb,
3654                                                 "setup_io: failed to pull "
3655                                                 "old supplementalCredentialsBlob: %s",
3656                                                 nt_errstr(status));
3657                                 return LDB_ERR_OPERATIONS_ERROR;
3658                         }
3659                 }
3660         }
3661
3662         return LDB_SUCCESS;
3663 }
3664
3665 static struct ph_context *ph_init_context(struct ldb_module *module,
3666                                           struct ldb_request *req,
3667                                           bool userPassword,
3668                                           bool update_password)
3669 {
3670         struct ldb_context *ldb;
3671         struct ph_context *ac;
3672         struct loadparm_context *lp_ctx = NULL;
3673
3674         ldb = ldb_module_get_ctx(module);
3675
3676         ac = talloc_zero(req, struct ph_context);
3677         if (ac == NULL) {
3678                 ldb_set_errstring(ldb, "Out of Memory");
3679                 return NULL;
3680         }
3681
3682         ac->module = module;
3683         ac->req = req;
3684         ac->userPassword = userPassword;
3685         ac->update_password = update_password;
3686         ac->update_lastset = true;
3687
3688         lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
3689                                        struct loadparm_context);
3690         ac->gpg_key_ids = lpcfg_password_hash_gpg_key_ids(lp_ctx);
3691         ac->userPassword_schemes
3692                 = lpcfg_password_hash_userpassword_schemes(lp_ctx);
3693         return ac;
3694 }
3695
3696 static void ph_apply_controls(struct ph_context *ac)
3697 {
3698         struct ldb_control *ctrl;
3699
3700         ac->change_status = false;
3701         ctrl = ldb_request_get_control(ac->req,
3702                                        DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID);
3703         if (ctrl != NULL) {
3704                 ac->change_status = true;
3705
3706                 /* Mark the "change status" control as uncritical (done) */
3707                 ctrl->critical = false;
3708         }
3709
3710         ac->hash_values = false;
3711         ctrl = ldb_request_get_control(ac->req,
3712                                        DSDB_CONTROL_PASSWORD_HASH_VALUES_OID);
3713         if (ctrl != NULL) {
3714                 ac->hash_values = true;
3715
3716                 /* Mark the "hash values" control as uncritical (done) */
3717                 ctrl->critical = false;
3718         }
3719
3720         ctrl = ldb_request_get_control(ac->req,
3721                                        DSDB_CONTROL_PASSWORD_CHANGE_OID);
3722         if (ctrl != NULL) {
3723                 ac->change = (struct dsdb_control_password_change *) ctrl->data;
3724
3725                 /* Mark the "change" control as uncritical (done) */
3726                 ctrl->critical = false;
3727         }
3728
3729         ac->pwd_last_set_bypass = false;
3730         ctrl = ldb_request_get_control(ac->req,
3731                                 DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID);
3732         if (ctrl != NULL) {
3733                 ac->pwd_last_set_bypass = true;
3734
3735                 /* Mark the "bypass pwdLastSet" control as uncritical (done) */
3736                 ctrl->critical = false;
3737         }
3738
3739         ac->pwd_last_set_default = false;
3740         ctrl = ldb_request_get_control(ac->req,
3741                                 DSDB_CONTROL_PASSWORD_DEFAULT_LAST_SET_OID);
3742         if (ctrl != NULL) {
3743                 ac->pwd_last_set_default = true;
3744
3745                 /* Mark the "bypass pwdLastSet" control as uncritical (done) */
3746                 ctrl->critical = false;
3747         }
3748
3749         ac->smartcard_reset = false;
3750         ctrl = ldb_request_get_control(ac->req,
3751                                 DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID);
3752         if (ctrl != NULL) {
3753                 struct dsdb_control_password_user_account_control *uac = NULL;
3754                 uint32_t added_flags = 0;
3755
3756                 uac = talloc_get_type_abort(ctrl->data,
3757                         struct dsdb_control_password_user_account_control);
3758
3759                 added_flags = uac->new_flags & ~uac->old_flags;
3760
3761                 if (added_flags & UF_SMARTCARD_REQUIRED) {
3762                         ac->smartcard_reset = true;
3763                 }
3764
3765                 /* Mark the "smartcard required" control as uncritical (done) */
3766                 ctrl->critical = false;
3767         }
3768 }
3769
3770 static int ph_op_callback(struct ldb_request *req, struct ldb_reply *ares)
3771 {
3772         struct ph_context *ac;
3773
3774         ac = talloc_get_type(req->context, struct ph_context);
3775
3776         if (!ares) {
3777                 return ldb_module_done(ac->req, NULL, NULL,
3778                                         LDB_ERR_OPERATIONS_ERROR);
3779         }
3780
3781         if (ares->type == LDB_REPLY_REFERRAL) {
3782                 return ldb_module_send_referral(ac->req, ares->referral);
3783         }
3784
3785         if ((ares->error != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
3786                 /* On success and trivial errors a status control is being
3787                  * added (used for example by the "samdb_set_password" call) */
3788                 ldb_reply_add_control(ares,
3789                                       DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
3790                                       false,
3791                                       ac->status);
3792         }
3793
3794         if (ares->error != LDB_SUCCESS) {
3795                 return ldb_module_done(ac->req, ares->controls,
3796                                         ares->response, ares->error);
3797         }
3798
3799         if (ares->type != LDB_REPLY_DONE) {
3800                 talloc_free(ares);
3801                 return ldb_module_done(ac->req, NULL, NULL,
3802                                         LDB_ERR_OPERATIONS_ERROR);
3803         }
3804
3805         return ldb_module_done(ac->req, ares->controls,
3806                                 ares->response, ares->error);
3807 }
3808
3809 static int password_hash_add_do_add(struct ph_context *ac);
3810 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares);
3811 static int password_hash_mod_search_self(struct ph_context *ac);
3812 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares);
3813 static int password_hash_mod_do_mod(struct ph_context *ac);
3814
3815 static int get_domain_data_callback(struct ldb_request *req,
3816                                     struct ldb_reply *ares)
3817 {
3818         struct ldb_context *ldb;
3819         struct ph_context *ac;
3820         struct loadparm_context *lp_ctx;
3821         int ret = LDB_SUCCESS;
3822
3823         ac = talloc_get_type(req->context, struct ph_context);
3824         ldb = ldb_module_get_ctx(ac->module);
3825
3826         if (!ares) {
3827                 ret = LDB_ERR_OPERATIONS_ERROR;
3828                 goto done;
3829         }
3830         if (ares->error != LDB_SUCCESS) {
3831                 return ldb_module_done(ac->req, ares->controls,
3832                                         ares->response, ares->error);
3833         }
3834
3835         switch (ares->type) {
3836         case LDB_REPLY_ENTRY:
3837                 if (ac->status != NULL) {
3838                         talloc_free(ares);
3839
3840                         ldb_set_errstring(ldb, "Too many results");
3841                         ret = LDB_ERR_OPERATIONS_ERROR;
3842                         goto done;
3843                 }
3844
3845                 /* Setup the "status" structure (used as control later) */
3846                 ac->status = talloc_zero(ac->req,
3847                                          struct dsdb_control_password_change_status);
3848                 if (ac->status == NULL) {
3849                         talloc_free(ares);
3850
3851                         ldb_oom(ldb);
3852                         ret = LDB_ERR_OPERATIONS_ERROR;
3853                         goto done;
3854                 }
3855
3856                 /* Setup the "domain data" structure */
3857                 ac->status->domain_data.pwdProperties =
3858                         ldb_msg_find_attr_as_uint(ares->message, "pwdProperties", -1);
3859                 ac->status->domain_data.pwdHistoryLength =
3860                         ldb_msg_find_attr_as_uint(ares->message, "pwdHistoryLength", -1);
3861                 ac->status->domain_data.maxPwdAge =
3862                         ldb_msg_find_attr_as_int64(ares->message, "maxPwdAge", -1);
3863                 ac->status->domain_data.minPwdAge =
3864                         ldb_msg_find_attr_as_int64(ares->message, "minPwdAge", -1);
3865                 ac->status->domain_data.minPwdLength =
3866                         ldb_msg_find_attr_as_uint(ares->message, "minPwdLength", -1);
3867                 ac->status->domain_data.store_cleartext =
3868                         ac->status->domain_data.pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT;
3869
3870                 /* For a domain DN, this puts things in dotted notation */
3871                 /* For builtin domains, this will give details for the host,
3872                  * but that doesn't really matter, as it's just used for salt
3873                  * and kerberos principals, which don't exist here */
3874
3875                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
3876                                          struct loadparm_context);
3877
3878                 ac->status->domain_data.dns_domain = lpcfg_dnsdomain(lp_ctx);
3879                 ac->status->domain_data.realm = lpcfg_realm(lp_ctx);
3880                 ac->status->domain_data.netbios_domain = lpcfg_sam_name(lp_ctx);
3881
3882                 ac->status->reject_reason = SAM_PWD_CHANGE_NO_ERROR;
3883
3884                 if (ac->dom_res != NULL) {
3885                         talloc_free(ares);
3886
3887                         ldb_set_errstring(ldb, "Too many results");
3888                         ret = LDB_ERR_OPERATIONS_ERROR;
3889                         goto done;
3890                 }
3891
3892                 ac->dom_res = talloc_steal(ac, ares);
3893                 ret = LDB_SUCCESS;
3894                 break;
3895
3896         case LDB_REPLY_REFERRAL:
3897                 /* ignore */
3898                 talloc_free(ares);
3899                 ret = LDB_SUCCESS;
3900                 break;
3901
3902         case LDB_REPLY_DONE:
3903                 talloc_free(ares);
3904                 /* call the next step */
3905                 switch (ac->req->operation) {
3906                 case LDB_ADD:
3907                         ret = password_hash_add_do_add(ac);
3908                         break;
3909
3910                 case LDB_MODIFY:
3911                         ret = password_hash_mod_do_mod(ac);
3912                         break;
3913
3914                 default:
3915                         ret = LDB_ERR_OPERATIONS_ERROR;
3916                         break;
3917                 }
3918                 break;
3919         }
3920
3921 done:
3922         if (ret != LDB_SUCCESS) {
3923                 struct ldb_reply *new_ares;
3924
3925                 new_ares = talloc_zero(ac->req, struct ldb_reply);
3926                 if (new_ares == NULL) {
3927                         ldb_oom(ldb);
3928                         return ldb_module_done(ac->req, NULL, NULL,
3929                                                LDB_ERR_OPERATIONS_ERROR);
3930                 }
3931
3932                 new_ares->error = ret;
3933                 if ((ret != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
3934                         /* On success and trivial errors a status control is being
3935                          * added (used for example by the "samdb_set_password" call) */
3936                         ldb_reply_add_control(new_ares,
3937                                               DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
3938                                               false,
3939                                               ac->status);
3940                 }
3941
3942                 return ldb_module_done(ac->req, new_ares->controls,
3943                                        new_ares->response, new_ares->error);
3944         }
3945
3946         return LDB_SUCCESS;
3947 }
3948
3949 static int build_domain_data_request(struct ph_context *ac)
3950 {
3951         /* attrs[] is returned from this function in
3952            ac->dom_req->op.search.attrs, so it must be static, as
3953            otherwise the compiler can put it on the stack */
3954         struct ldb_context *ldb;
3955         static const char * const attrs[] = { "pwdProperties",
3956                                               "pwdHistoryLength",
3957                                               "maxPwdAge",
3958                                               "minPwdAge",
3959                                               "minPwdLength",
3960                                               "lockoutThreshold",
3961                                               "lockOutObservationWindow",
3962                                               NULL };
3963         int ret;
3964
3965         ldb = ldb_module_get_ctx(ac->module);
3966
3967         ret = ldb_build_search_req(&ac->dom_req, ldb, ac,
3968                                    ldb_get_default_basedn(ldb),
3969                                    LDB_SCOPE_BASE,
3970                                    NULL, attrs,
3971                                    NULL,
3972                                    ac, get_domain_data_callback,
3973                                    ac->req);
3974         LDB_REQ_SET_LOCATION(ac->dom_req);
3975         return ret;
3976 }
3977
3978 static int password_hash_needed(struct ldb_module *module,
3979                                 struct ldb_request *req,
3980                                 struct ph_context **_ac)
3981 {
3982         struct ldb_context *ldb = ldb_module_get_ctx(module);
3983         const char *operation = NULL;
3984         const struct ldb_message *msg = NULL;
3985         struct ph_context *ac = NULL;
3986         const char *passwordAttrs[] = {
3987                 "userPassword",
3988                 "clearTextPassword",
3989                 "unicodePwd",
3990                 "dBCSPwd",
3991                 NULL
3992         };
3993         const char **a = NULL;
3994         unsigned int attr_cnt = 0;
3995         struct ldb_control *bypass = NULL;
3996         struct ldb_control *uac_ctrl = NULL;
3997         bool userPassword = dsdb_user_password_support(module, req, req);
3998         bool update_password = false;
3999         bool processing_needed = false;
4000
4001         *_ac = NULL;
4002
4003         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_needed\n");
4004
4005         switch (req->operation) {
4006         case LDB_ADD:
4007                 operation = "add";
4008                 msg = req->op.add.message;
4009                 break;
4010         case LDB_MODIFY:
4011                 operation = "modify";
4012                 msg = req->op.mod.message;
4013                 break;
4014         default:
4015                 return ldb_next_request(module, req);
4016         }
4017
4018         if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
4019                 return ldb_next_request(module, req);
4020         }
4021
4022         bypass = ldb_request_get_control(req,
4023                                          DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID);
4024         if (bypass != NULL) {
4025                 /* Mark the "bypass" control as uncritical (done) */
4026                 bypass->critical = false;
4027                 ldb_debug(ldb, LDB_DEBUG_TRACE,
4028                           "password_hash_needed(%s) (bypassing)\n",
4029                           operation);
4030                 return password_hash_bypass(module, req);
4031         }
4032
4033         /* nobody must touch password histories and 'supplementalCredentials' */
4034         if (ldb_msg_find_element(msg, "ntPwdHistory")) {
4035                 return LDB_ERR_UNWILLING_TO_PERFORM;
4036         }
4037         if (ldb_msg_find_element(msg, "lmPwdHistory")) {
4038                 return LDB_ERR_UNWILLING_TO_PERFORM;
4039         }
4040         if (ldb_msg_find_element(msg, "supplementalCredentials")) {
4041                 return LDB_ERR_UNWILLING_TO_PERFORM;
4042         }
4043
4044         /*
4045          * If no part of this touches the 'userPassword' OR 'clearTextPassword'
4046          * OR 'unicodePwd' OR 'dBCSPwd' we don't need to make any changes.
4047          * For password changes/set there should be a 'delete' or a 'modify'
4048          * on these attributes.
4049          */
4050         for (a = passwordAttrs; *a != NULL; a++) {
4051                 if ((!userPassword) && (ldb_attr_cmp(*a, "userPassword") == 0)) {
4052                         continue;
4053                 }
4054
4055                 if (ldb_msg_find_element(msg, *a) != NULL) {
4056                         /* MS-ADTS 3.1.1.3.1.5.2 */
4057                         if ((ldb_attr_cmp(*a, "userPassword") == 0) &&
4058                             (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003)) {
4059                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4060                         }
4061
4062                         ++attr_cnt;
4063                 }
4064         }
4065
4066         if (attr_cnt > 0) {
4067                 update_password = true;
4068                 processing_needed = true;
4069         }
4070
4071         if (ldb_msg_find_element(msg, "pwdLastSet")) {
4072                 processing_needed = true;
4073         }
4074
4075         uac_ctrl = ldb_request_get_control(req,
4076                                 DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID);
4077         if (uac_ctrl != NULL) {
4078                 struct dsdb_control_password_user_account_control *uac = NULL;
4079                 uint32_t added_flags = 0;
4080
4081                 uac = talloc_get_type_abort(uac_ctrl->data,
4082                         struct dsdb_control_password_user_account_control);
4083
4084                 added_flags = uac->new_flags & ~uac->old_flags;
4085
4086                 if (added_flags & UF_SMARTCARD_REQUIRED) {
4087                         processing_needed = true;
4088                 }
4089         }
4090
4091         if (!processing_needed) {
4092                 return ldb_next_request(module, req);
4093         }
4094
4095         ac = ph_init_context(module, req, userPassword, update_password);
4096         if (!ac) {
4097                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
4098                 return ldb_operr(ldb);
4099         }
4100         ph_apply_controls(ac);
4101
4102         /*
4103          * Make a copy in order to apply our modifications
4104          * to the final update
4105          */
4106         ac->update_msg = ldb_msg_copy_shallow(ac, msg);
4107         if (ac->update_msg == NULL) {
4108                 return ldb_oom(ldb);
4109         }
4110
4111         /*
4112          * Remove all password related attributes.
4113          */
4114         if (ac->userPassword) {
4115                 ldb_msg_remove_attr(ac->update_msg, "userPassword");
4116         }
4117         ldb_msg_remove_attr(ac->update_msg, "clearTextPassword");
4118         ldb_msg_remove_attr(ac->update_msg, "unicodePwd");
4119         ldb_msg_remove_attr(ac->update_msg, "ntPwdHistory");
4120         ldb_msg_remove_attr(ac->update_msg, "dBCSPwd");
4121         ldb_msg_remove_attr(ac->update_msg, "lmPwdHistory");
4122         ldb_msg_remove_attr(ac->update_msg, "supplementalCredentials");
4123         ldb_msg_remove_attr(ac->update_msg, "pwdLastSet");
4124
4125         *_ac = ac;
4126         return LDB_SUCCESS;
4127 }
4128
4129 static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
4130 {
4131         struct ldb_context *ldb = ldb_module_get_ctx(module);
4132         struct ph_context *ac = NULL;
4133         int ret;
4134
4135         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_add\n");
4136
4137         ret = password_hash_needed(module, req, &ac);
4138         if (ret != LDB_SUCCESS) {
4139                 return ret;
4140         }
4141         if (ac == NULL) {
4142                 return ret;
4143         }
4144
4145         /* Make sure we are performing the password set action on a (for us)
4146          * valid object. Those are instances of either "user" and/or
4147          * "inetOrgPerson". Otherwise continue with the submodules. */
4148         if ((!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "user"))
4149                 && (!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "inetOrgPerson"))) {
4150
4151                 TALLOC_FREE(ac);
4152
4153                 if (ldb_msg_find_element(req->op.add.message, "clearTextPassword") != NULL) {
4154                         ldb_set_errstring(ldb,
4155                                           "'clearTextPassword' is only allowed on objects of class 'user' and/or 'inetOrgPerson'!");
4156                         return LDB_ERR_NO_SUCH_ATTRIBUTE;
4157                 }
4158
4159                 return ldb_next_request(module, req);
4160         }
4161
4162         /* get user domain data */
4163         ret = build_domain_data_request(ac);
4164         if (ret != LDB_SUCCESS) {
4165                 return ret;
4166         }
4167
4168         return ldb_next_request(module, ac->dom_req);
4169 }
4170
4171 static int password_hash_add_do_add(struct ph_context *ac)
4172 {
4173         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
4174         struct ldb_request *down_req;
4175         struct setup_password_fields_io io;
4176         int ret;
4177
4178         /* Prepare the internal data structure containing the passwords */
4179         ret = setup_io(ac, ac->req->op.add.message, NULL, &io);
4180         if (ret != LDB_SUCCESS) {
4181                 return ret;
4182         }
4183
4184         ret = setup_password_fields(&io);
4185         if (ret != LDB_SUCCESS) {
4186                 return ret;
4187         }
4188
4189         ret = check_password_restrictions_and_log(&io);
4190         if (ret != LDB_SUCCESS) {
4191                 return ret;
4192         }
4193
4194         ret = setup_smartcard_reset(&io);
4195         if (ret != LDB_SUCCESS) {
4196                 return ret;
4197         }
4198
4199         ret = update_final_msg(&io);
4200         if (ret != LDB_SUCCESS) {
4201                 return ret;
4202         }
4203
4204         ret = ldb_build_add_req(&down_req, ldb, ac,
4205                                 ac->update_msg,
4206                                 ac->req->controls,
4207                                 ac, ph_op_callback,
4208                                 ac->req);
4209         LDB_REQ_SET_LOCATION(down_req);
4210         if (ret != LDB_SUCCESS) {
4211                 return ret;
4212         }
4213
4214         return ldb_next_request(ac->module, down_req);
4215 }
4216
4217 static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
4218 {
4219         struct ldb_context *ldb = ldb_module_get_ctx(module);
4220         struct ph_context *ac = NULL;
4221         const char *passwordAttrs[] = { "userPassword", "clearTextPassword",
4222                 "unicodePwd", "dBCSPwd", NULL }, **l;
4223         unsigned int del_attr_cnt, add_attr_cnt, rep_attr_cnt;
4224         struct ldb_message_element *passwordAttr;
4225         struct ldb_message *msg;
4226         struct ldb_request *down_req;
4227         struct ldb_control *restore = NULL;
4228         int ret;
4229         unsigned int i = 0;
4230
4231         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");
4232
4233         ret = password_hash_needed(module, req, &ac);
4234         if (ret != LDB_SUCCESS) {
4235                 return ret;
4236         }
4237         if (ac == NULL) {
4238                 return ret;
4239         }
4240
4241         /* use a new message structure so that we can modify it */
4242         msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
4243         if (msg == NULL) {
4244                 return ldb_oom(ldb);
4245         }
4246
4247         /* - check for single-valued password attributes
4248          *   (if not return "CONSTRAINT_VIOLATION")
4249          * - check that for a password change operation one add and one delete
4250          *   operation exists
4251          *   (if not return "CONSTRAINT_VIOLATION" or "UNWILLING_TO_PERFORM")
4252          * - check that a password change and a password set operation cannot
4253          *   be mixed
4254          *   (if not return "UNWILLING_TO_PERFORM")
4255          * - remove all password attributes modifications from the first change
4256          *   operation (anything without the passwords) - we will make the real
4257          *   modification later */
4258         del_attr_cnt = 0;
4259         add_attr_cnt = 0;
4260         rep_attr_cnt = 0;
4261         for (l = passwordAttrs; *l != NULL; l++) {
4262                 if ((!ac->userPassword) &&
4263                     (ldb_attr_cmp(*l, "userPassword") == 0)) {
4264                         continue;
4265                 }
4266
4267                 while ((passwordAttr = ldb_msg_find_element(msg, *l)) != NULL) {
4268                         if (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_DELETE) {
4269                                 ++del_attr_cnt;
4270                         }
4271                         if (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_ADD) {
4272                                 ++add_attr_cnt;
4273                         }
4274                         if (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_REPLACE) {
4275                                 ++rep_attr_cnt;
4276                         }
4277                         if ((passwordAttr->num_values != 1) &&
4278                             (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_ADD)) {
4279                                 talloc_free(ac);
4280                                 ldb_asprintf_errstring(ldb,
4281                                                        "'%s' attribute must have exactly one value on add operations!",
4282                                                        *l);
4283                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4284                         }
4285                         if ((passwordAttr->num_values > 1) &&
4286                             (LDB_FLAG_MOD_TYPE(passwordAttr->flags) == LDB_FLAG_MOD_DELETE)) {
4287                                 talloc_free(ac);
4288                                 ldb_asprintf_errstring(ldb,
4289                                                        "'%s' attribute must have zero or one value(s) on delete operations!",
4290                                                        *l);
4291                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4292                         }
4293                         ldb_msg_remove_element(msg, passwordAttr);
4294                 }
4295         }
4296         if ((del_attr_cnt == 0) && (add_attr_cnt > 0)) {
4297                 talloc_free(ac);
4298                 ldb_set_errstring(ldb,
4299                                   "Only the add action for a password change specified!");
4300                 return LDB_ERR_UNWILLING_TO_PERFORM;
4301         }
4302         if ((del_attr_cnt > 1) || (add_attr_cnt > 1)) {
4303                 talloc_free(ac);
4304                 ldb_set_errstring(ldb,
4305                                   "Only one delete and one add action for a password change allowed!");
4306                 return LDB_ERR_UNWILLING_TO_PERFORM;
4307         }
4308         if ((rep_attr_cnt > 0) && ((del_attr_cnt > 0) || (add_attr_cnt > 0))) {
4309                 talloc_free(ac);
4310                 ldb_set_errstring(ldb,
4311                                   "Either a password change or a password set operation is allowed!");
4312                 return LDB_ERR_UNWILLING_TO_PERFORM;
4313         }
4314
4315         restore = ldb_request_get_control(req,
4316                                         DSDB_CONTROL_RESTORE_TOMBSTONE_OID);
4317         if (restore == NULL) {
4318                 /*
4319                  * A tomstone reanimation generates a double update
4320                  * of pwdLastSet.
4321                  *
4322                  * So we only remove it without the
4323                  * DSDB_CONTROL_RESTORE_TOMBSTONE_OID control.
4324                  */
4325                 ldb_msg_remove_attr(msg, "pwdLastSet");
4326         }
4327
4328
4329         /* if there was nothing else to be modified skip to next step */
4330         if (msg->num_elements == 0) {
4331                 return password_hash_mod_search_self(ac);
4332         }
4333
4334         /*
4335          * Now we apply all changes remaining in msg
4336          * and remove them from our final update_msg
4337          */
4338
4339         for (i = 0; i < msg->num_elements; i++) {
4340                 ldb_msg_remove_attr(ac->update_msg,
4341                                     msg->elements[i].name);
4342         }
4343
4344         ret = ldb_build_mod_req(&down_req, ldb, ac,
4345                                 msg,
4346                                 req->controls,
4347                                 ac, ph_modify_callback,
4348                                 req);
4349         LDB_REQ_SET_LOCATION(down_req);
4350         if (ret != LDB_SUCCESS) {
4351                 return ret;
4352         }
4353
4354         return ldb_next_request(module, down_req);
4355 }
4356
4357 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
4358 {
4359         struct ph_context *ac;
4360
4361         ac = talloc_get_type(req->context, struct ph_context);
4362
4363         if (!ares) {
4364                 return ldb_module_done(ac->req, NULL, NULL,
4365                                         LDB_ERR_OPERATIONS_ERROR);
4366         }
4367
4368         if (ares->type == LDB_REPLY_REFERRAL) {
4369                 return ldb_module_send_referral(ac->req, ares->referral);
4370         }
4371
4372         if (ares->error != LDB_SUCCESS) {
4373                 return ldb_module_done(ac->req, ares->controls,
4374                                         ares->response, ares->error);
4375         }
4376
4377         if (ares->type != LDB_REPLY_DONE) {
4378                 talloc_free(ares);
4379                 return ldb_module_done(ac->req, NULL, NULL,
4380                                         LDB_ERR_OPERATIONS_ERROR);
4381         }
4382
4383         talloc_free(ares);
4384
4385         return password_hash_mod_search_self(ac);
4386 }
4387
4388 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
4389 {
4390         struct ldb_context *ldb;
4391         struct ph_context *ac;
4392         int ret = LDB_SUCCESS;
4393
4394         ac = talloc_get_type(req->context, struct ph_context);
4395         ldb = ldb_module_get_ctx(ac->module);
4396
4397         if (!ares) {
4398                 ret = LDB_ERR_OPERATIONS_ERROR;
4399                 goto done;
4400         }
4401         if (ares->error != LDB_SUCCESS) {
4402                 return ldb_module_done(ac->req, ares->controls,
4403                                         ares->response, ares->error);
4404         }
4405
4406         /* we are interested only in the single reply (base search) */
4407         switch (ares->type) {
4408         case LDB_REPLY_ENTRY:
4409                 /* Make sure we are performing the password change action on a
4410                  * (for us) valid object. Those are instances of either "user"
4411                  * and/or "inetOrgPerson". Otherwise continue with the
4412                  * submodules. */
4413                 if ((!ldb_msg_check_string_attribute(ares->message, "objectClass", "user"))
4414                         && (!ldb_msg_check_string_attribute(ares->message, "objectClass", "inetOrgPerson"))) {
4415                         talloc_free(ares);
4416
4417                         if (ldb_msg_find_element(ac->req->op.mod.message, "clearTextPassword") != NULL) {
4418                                 ldb_set_errstring(ldb,
4419                                                   "'clearTextPassword' is only allowed on objects of class 'user' and/or 'inetOrgPerson'!");
4420                                 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
4421                                 goto done;
4422                         }
4423
4424                         ret = ldb_next_request(ac->module, ac->req);
4425                         goto done;
4426                 }
4427
4428                 if (ac->search_res != NULL) {
4429                         talloc_free(ares);
4430
4431                         ldb_set_errstring(ldb, "Too many results");
4432                         ret = LDB_ERR_OPERATIONS_ERROR;
4433                         goto done;
4434                 }
4435
4436                 ac->search_res = talloc_steal(ac, ares);
4437                 ret = LDB_SUCCESS;
4438                 break;
4439
4440         case LDB_REPLY_REFERRAL:
4441                 /* ignore anything else for now */
4442                 talloc_free(ares);
4443                 ret = LDB_SUCCESS;
4444                 break;
4445
4446         case LDB_REPLY_DONE:
4447                 talloc_free(ares);
4448
4449                 /* get user domain data */
4450                 ret = build_domain_data_request(ac);
4451                 if (ret != LDB_SUCCESS) {
4452                         return ldb_module_done(ac->req, NULL, NULL, ret);
4453                 }
4454
4455                 ret = ldb_next_request(ac->module, ac->dom_req);
4456                 break;
4457         }
4458
4459 done:
4460         if (ret != LDB_SUCCESS) {
4461                 return ldb_module_done(ac->req, NULL, NULL, ret);
4462         }
4463
4464         return LDB_SUCCESS;
4465 }
4466
4467 static int password_hash_mod_search_self(struct ph_context *ac)
4468 {
4469         struct ldb_context *ldb;
4470         static const char * const attrs[] = { "objectClass",
4471                                               "userAccountControl",
4472                                               "msDS-User-Account-Control-Computed",
4473                                               "pwdLastSet",
4474                                               "sAMAccountName",
4475                                               "objectSid",
4476                                               "userPrincipalName",
4477                                               "supplementalCredentials",
4478                                               "lmPwdHistory",
4479                                               "ntPwdHistory",
4480                                               "dBCSPwd",
4481                                               "unicodePwd",
4482                                               "badPasswordTime",
4483                                               "badPwdCount",
4484                                               "lockoutTime",
4485                                               "msDS-SecondaryKrbTgtNumber",
4486                                               NULL };
4487         struct ldb_request *search_req;
4488         int ret;
4489
4490         ldb = ldb_module_get_ctx(ac->module);
4491
4492         ret = ldb_build_search_req(&search_req, ldb, ac,
4493                                    ac->req->op.mod.message->dn,
4494                                    LDB_SCOPE_BASE,
4495                                    "(objectclass=*)",
4496                                    attrs,
4497                                    NULL,
4498                                    ac, ph_mod_search_callback,
4499                                    ac->req);
4500         LDB_REQ_SET_LOCATION(search_req);
4501         if (ret != LDB_SUCCESS) {
4502                 return ret;
4503         }
4504
4505         return ldb_next_request(ac->module, search_req);
4506 }
4507
4508 static int password_hash_mod_do_mod(struct ph_context *ac)
4509 {
4510         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
4511         struct ldb_request *mod_req;
4512         struct setup_password_fields_io io;
4513         int ret;
4514
4515         /* Prepare the internal data structure containing the passwords */
4516         ret = setup_io(ac, ac->req->op.mod.message,
4517                        ac->search_res->message, &io);
4518         if (ret != LDB_SUCCESS) {
4519                 return ret;
4520         }
4521
4522         ret = setup_password_fields(&io);
4523         if (ret != LDB_SUCCESS) {
4524                 return ret;
4525         }
4526
4527         ret = check_password_restrictions_and_log(&io);
4528         if (ret != LDB_SUCCESS) {
4529                 return ret;
4530         }
4531
4532         ret = setup_smartcard_reset(&io);
4533         if (ret != LDB_SUCCESS) {
4534                 return ret;
4535         }
4536
4537         ret = update_final_msg(&io);
4538         if (ret != LDB_SUCCESS) {
4539                 return ret;
4540         }
4541
4542         ret = ldb_build_mod_req(&mod_req, ldb, ac,
4543                                 ac->update_msg,
4544                                 ac->req->controls,
4545                                 ac, ph_op_callback,
4546                                 ac->req);
4547         LDB_REQ_SET_LOCATION(mod_req);
4548         if (ret != LDB_SUCCESS) {
4549                 return ret;
4550         }
4551
4552         return ldb_next_request(ac->module, mod_req);
4553 }
4554
4555 static const struct ldb_module_ops ldb_password_hash_module_ops = {
4556         .name          = "password_hash",
4557         .add           = password_hash_add,
4558         .modify        = password_hash_modify
4559 };
4560
4561 int ldb_password_hash_module_init(const char *version)
4562 {
4563 #ifdef ENABLE_GPGME
4564         const char *gversion = NULL;
4565 #endif /* ENABLE_GPGME */
4566
4567         LDB_MODULE_CHECK_VERSION(version);
4568
4569 #ifdef ENABLE_GPGME
4570         /*
4571          * Note: this sets a SIGPIPE handler
4572          * if none is active already. See:
4573          * https://www.gnupg.org/documentation/manuals/gpgme/Signal-Handling.html#Signal-Handling
4574          */
4575         gversion = gpgme_check_version(GPGME_VERSION);
4576         if (gversion == NULL) {
4577                 fprintf(stderr, "%s() in %s version[%s]: "
4578                         "gpgme_check_version(%s) not available, "
4579                         "gpgme_check_version(NULL) => '%s'\n",
4580                         __func__, __FILE__, version,
4581                         GPGME_VERSION, gpgme_check_version(NULL));
4582                 return LDB_ERR_UNAVAILABLE;
4583         }
4584 #endif /* ENABLE_GPGME */
4585
4586         return ldb_register_module(&ldb_password_hash_module_ops);
4587 }