5783e67eddf914dbe84244e473502b260bf83f68
[samba.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/md4.h"
46 #include "param/param.h"
47 #include "lib/krb5_wrap/krb5_samba.h"
48 #include "auth/auth_sam.h"
49 #include "auth/common_auth.h"
50 #include "lib/messaging/messaging.h"
51 #include "lib/param/loadparm.h"
52
53 #include "lib/crypto/gnutls_helpers.h"
54 #include <gnutls/crypto.h>
55
56 #include "kdc/db-glue.h"
57
58 #ifdef ENABLE_GPGME
59 #undef class
60 #include <gpgme.h>
61
62 /*
63  * 1.2.0 is what dpkg-shlibdeps generates, based on used symbols and
64  * libgpgme11.symbols
65  * https://salsa.debian.org/debian/gpgme/blob/debian/master/debian/libgpgme11.symbols
66  */
67
68 #define MINIMUM_GPGME_VERSION "1.2.0"
69 #endif
70
71 #undef strncasecmp
72 #undef strcasecmp
73
74 /* If we have decided there is a reason to work on this request, then
75  * setup all the password hash types correctly.
76  *
77  * If we haven't the hashes yet but the password given as plain-text (attributes
78  * 'unicodePwd', 'userPassword' and 'clearTextPassword') we have to check for
79  * the constraints. Once this is done, we calculate the password hashes.
80  *
81  * Notice: unlike the real AD which only supports the UTF16 special based
82  * 'unicodePwd' and the UTF8 based 'userPassword' plaintext attribute we
83  * understand also a UTF16 based 'clearTextPassword' one.
84  * The latter is also accessible through LDAP so it can also be set by external
85  * tools and scripts. But be aware that this isn't portable on non SAMBA 4 ADs!
86  *
87  * Also when the module receives only the password hashes (possible through
88  * specifying an internal LDB control - for security reasons) some checks are
89  * performed depending on the operation mode (see below) (e.g. if the password
90  * has been in use before if the password memory policy was activated).
91  *
92  * Attention: There is a difference between "modify" and "reset" operations
93  * (see MS-ADTS 3.1.1.3.1.5). If the client sends a "add" and "remove"
94  * operation for a password attribute we thread this as a "modify"; if it sends
95  * only a "replace" one we have an (administrative) reset.
96  *
97  * Finally, if the administrator has requested that a password history
98  * be maintained, then this should also be written out.
99  *
100  */
101
102 /* TODO: [consider always MS-ADTS 3.1.1.3.1.5]
103  * - Check for right connection encryption
104  */
105
106 /* Notice: Definition of "dsdb_control_password_change_status" moved into
107  * "samdb.h" */
108
109 struct ph_context {
110         struct ldb_module *module;
111         struct ldb_request *req;
112
113         struct ldb_request *dom_req;
114         struct ldb_reply *dom_res;
115
116         struct ldb_reply *pso_res;
117
118         struct ldb_reply *search_res;
119
120         struct ldb_message *update_msg;
121
122         struct dsdb_control_password_change_status *status;
123         struct dsdb_control_password_change *change;
124
125         const char **gpg_key_ids;
126
127         bool pwd_reset;
128         bool change_status;
129         bool hash_values;
130         bool userPassword;
131         bool update_password;
132         bool update_lastset;
133         bool pwd_last_set_bypass;
134         bool pwd_last_set_default;
135         bool smartcard_reset;
136         const char **userPassword_schemes;
137 };
138
139
140 struct setup_password_fields_io {
141         struct ph_context *ac;
142
143         struct smb_krb5_context *smb_krb5_context;
144
145         /* info about the user account */
146         struct {
147                 uint32_t userAccountControl;
148                 NTTIME pwdLastSet;
149                 const char *sAMAccountName;
150                 const char *user_principal_name;
151                 const char *displayName; /* full name */
152                 bool is_krbtgt;
153                 uint32_t restrictions;
154                 struct dom_sid *account_sid;
155                 bool store_nt_hash;
156         } u;
157
158         /* new credentials and old given credentials */
159         struct setup_password_fields_given {
160                 const struct ldb_val *cleartext_utf8;
161                 const struct ldb_val *cleartext_utf16;
162
163                 struct samr_Password *nt_hash;
164
165                 /*
166                  * The AES256 kerberos key to confirm the previous password was
167                  * not reused (for n) and to prove the old password was known
168                  * (for og).
169                  *
170                  * We don't have any old salts, so we won't catch password reuse
171                  * if said password was used prior to an account rename and
172                  * another password change.
173                  */
174                 DATA_BLOB aes_256;
175         } n, og;
176
177         /* old credentials */
178         struct {
179                 struct samr_Password *nt_hash;
180                 uint32_t nt_history_len;
181                 struct samr_Password *nt_history;
182                 const struct ldb_val *supplemental;
183                 struct supplementalCredentialsBlob scb;
184
185                 /*
186                  * The AES256 kerberos key as stored in the DB.
187                  * Used to confirm the given password was correct
188                  * and in case the previous password was reused.
189                  */
190                 DATA_BLOB aes_256;
191                 DATA_BLOB salt;
192                 uint32_t kvno;
193         } o;
194
195         /* generated credentials */
196         struct {
197                 struct samr_Password *nt_hash;
198                 uint32_t nt_history_len;
199                 struct samr_Password *nt_history;
200                 const char *salt;
201                 DATA_BLOB aes_256;
202                 DATA_BLOB aes_128;
203                 DATA_BLOB des_md5;
204                 DATA_BLOB des_crc;
205                 struct ldb_val supplemental;
206                 NTTIME last_set;
207         } g;
208 };
209
210 static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
211                                         const char *name,
212                                         enum ldb_request_type operation,
213                                         const struct ldb_val **new_val,
214                                         const struct ldb_val **old_val);
215
216 static int password_hash_bypass(struct ldb_module *module, struct ldb_request *request)
217 {
218         struct ldb_context *ldb = ldb_module_get_ctx(module);
219         const struct ldb_message *msg;
220         struct ldb_message_element *nte;
221         struct ldb_message_element *lme;
222         struct ldb_message_element *nthe;
223         struct ldb_message_element *lmhe;
224         struct ldb_message_element *sce;
225         int ret;
226
227         switch (request->operation) {
228         case LDB_ADD:
229                 msg = request->op.add.message;
230                 break;
231         case LDB_MODIFY:
232                 msg = request->op.mod.message;
233                 break;
234         default:
235                 return ldb_next_request(module, request);
236         }
237
238         /* nobody must touch password histories and 'supplementalCredentials' */
239
240 #define GET_VALUES(el, attr) do {  \
241         ret = dsdb_get_expected_new_values(request,             \
242                                            msg,                 \
243                                            attr,                \
244                                            &el,                 \
245                                            request->operation); \
246                                                                 \
247         if (ret != LDB_SUCCESS) {                               \
248                 return ret;                                     \
249         }                                                       \
250 } while(0)
251
252         GET_VALUES(nte, "unicodePwd");
253
254         /*
255          * Even as Samba continues to ignore the LM hash, and reset it
256          * when practical, we keep the constraint that it must be a 16
257          * byte value if specified.
258          */
259         GET_VALUES(lme, "dBCSPwd");
260         GET_VALUES(nthe, "ntPwdHistory");
261         GET_VALUES(lmhe, "lmPwdHistory");
262         GET_VALUES(sce, "supplementalCredentials");
263
264 #undef GET_VALUES
265 #define CHECK_HASH_ELEMENT(e, min, max) do {\
266         if (e && e->num_values) { \
267                 unsigned int _count; \
268                 if (e->num_values != 1) { \
269                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
270                                          "num_values != 1"); \
271                 } \
272                 if ((e->values[0].length % 16) != 0) { \
273                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
274                                          "length % 16 != 0"); \
275                 } \
276                 _count = e->values[0].length / 16; \
277                 if (_count < min) { \
278                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
279                                          "count < min"); \
280                 } \
281                 if (_count > max) { \
282                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION, \
283                                          "count > max"); \
284                 } \
285         } \
286 } while (0)
287
288         CHECK_HASH_ELEMENT(nte, 1, 1);
289         CHECK_HASH_ELEMENT(lme, 1, 1);
290         CHECK_HASH_ELEMENT(nthe, 1, INT32_MAX);
291         CHECK_HASH_ELEMENT(lmhe, 1, INT32_MAX);
292
293         if (sce && sce->num_values) {
294                 enum ndr_err_code ndr_err;
295                 struct supplementalCredentialsBlob *scb;
296                 struct supplementalCredentialsPackage *scpp = NULL;
297                 struct supplementalCredentialsPackage *scpk = NULL;
298                 struct supplementalCredentialsPackage *scpkn = NULL;
299                 struct supplementalCredentialsPackage *scpct = NULL;
300                 DATA_BLOB scpbp = data_blob_null;
301                 DATA_BLOB scpbk = data_blob_null;
302                 DATA_BLOB scpbkn = data_blob_null;
303                 DATA_BLOB scpbct = data_blob_null;
304                 DATA_BLOB blob;
305                 uint32_t i;
306
307                 if (sce->num_values != 1) {
308                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
309                                          "num_values != 1");
310                 }
311
312                 scb = talloc_zero(request, struct supplementalCredentialsBlob);
313                 if (!scb) {
314                         return ldb_module_oom(module);
315                 }
316
317                 ndr_err = ndr_pull_struct_blob_all(&sce->values[0], scb, scb,
318                                 (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
319                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
320                         talloc_free(scb);
321                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
322                                          "ndr_pull_struct_blob_all");
323                 }
324
325                 if (scb->sub.num_packages < 2) {
326                         talloc_free(scb);
327                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
328                                          "num_packages < 2");
329                 }
330
331                 for (i=0; i < scb->sub.num_packages; i++) {
332                         DATA_BLOB subblob;
333
334                         subblob = strhex_to_data_blob(scb, scb->sub.packages[i].data);
335                         if (subblob.data == NULL) {
336                                 talloc_free(scb);
337                                 return ldb_module_oom(module);
338                         }
339
340                         if (strcmp(scb->sub.packages[i].name, "Packages") == 0) {
341                                 if (scpp) {
342                                         talloc_free(scb);
343                                         return ldb_error(ldb,
344                                                          LDB_ERR_CONSTRAINT_VIOLATION,
345                                                          "Packages twice");
346                                 }
347                                 scpp = &scb->sub.packages[i];
348                                 scpbp = subblob;
349                                 continue;
350                         }
351                         if (strcmp(scb->sub.packages[i].name, "Primary:Kerberos") == 0) {
352                                 if (scpk) {
353                                         talloc_free(scb);
354                                         return ldb_error(ldb,
355                                                          LDB_ERR_CONSTRAINT_VIOLATION,
356                                                          "Primary:Kerberos twice");
357                                 }
358                                 scpk = &scb->sub.packages[i];
359                                 scpbk = subblob;
360                                 continue;
361                         }
362                         if (strcmp(scb->sub.packages[i].name, "Primary:Kerberos-Newer-Keys") == 0) {
363                                 if (scpkn) {
364                                         talloc_free(scb);
365                                         return ldb_error(ldb,
366                                                          LDB_ERR_CONSTRAINT_VIOLATION,
367                                                          "Primary:Kerberos-Newer-Keys twice");
368                                 }
369                                 scpkn = &scb->sub.packages[i];
370                                 scpbkn = subblob;
371                                 continue;
372                         }
373                         if (strcmp(scb->sub.packages[i].name, "Primary:CLEARTEXT") == 0) {
374                                 if (scpct) {
375                                         talloc_free(scb);
376                                         return ldb_error(ldb,
377                                                          LDB_ERR_CONSTRAINT_VIOLATION,
378                                                          "Primary:CLEARTEXT twice");
379                                 }
380                                 scpct = &scb->sub.packages[i];
381                                 scpbct = subblob;
382                                 continue;
383                         }
384
385                         data_blob_free(&subblob);
386                 }
387
388                 if (scpp == NULL) {
389                         talloc_free(scb);
390                         return ldb_error(ldb,
391                                          LDB_ERR_CONSTRAINT_VIOLATION,
392                                          "Primary:Packages missing");
393                 }
394
395                 if (scpk == NULL) {
396                         /*
397                          * If Primary:Kerberos is missing w2k8r2 reboots
398                          * when a password is changed.
399                          */
400                         talloc_free(scb);
401                         return ldb_error(ldb,
402                                          LDB_ERR_CONSTRAINT_VIOLATION,
403                                          "Primary:Kerberos missing");
404                 }
405
406                 if (scpp) {
407                         struct package_PackagesBlob *p;
408                         uint32_t n;
409
410                         p = talloc_zero(scb, struct package_PackagesBlob);
411                         if (p == NULL) {
412                                 talloc_free(scb);
413                                 return ldb_module_oom(module);
414                         }
415
416                         ndr_err = ndr_pull_struct_blob(&scpbp, p, p,
417                                         (ndr_pull_flags_fn_t)ndr_pull_package_PackagesBlob);
418                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
419                                 talloc_free(scb);
420                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
421                                                  "ndr_pull_struct_blob Packages");
422                         }
423
424                         if (p->names == NULL) {
425                                 talloc_free(scb);
426                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
427                                                  "Packages names == NULL");
428                         }
429
430                         for (n = 0; p->names[n]; n++) {
431                                 /* noop */
432                         }
433
434                         if (scb->sub.num_packages != (n + 1)) {
435                                 talloc_free(scb);
436                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
437                                                  "Packages num_packages != num_names + 1");
438                         }
439
440                         talloc_free(p);
441                 }
442
443                 if (scpk) {
444                         struct package_PrimaryKerberosBlob *k;
445
446                         k = talloc_zero(scb, struct package_PrimaryKerberosBlob);
447                         if (k == NULL) {
448                                 talloc_free(scb);
449                                 return ldb_module_oom(module);
450                         }
451
452                         ndr_err = ndr_pull_struct_blob(&scpbk, k, k,
453                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
454                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
455                                 talloc_free(scb);
456                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
457                                                  "ndr_pull_struct_blob PrimaryKerberos");
458                         }
459
460                         if (k->version != 3) {
461                                 talloc_free(scb);
462                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
463                                                  "PrimaryKerberos version != 3");
464                         }
465
466                         if (k->ctr.ctr3.salt.string == NULL) {
467                                 talloc_free(scb);
468                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
469                                                  "PrimaryKerberos salt == NULL");
470                         }
471
472                         if (strlen(k->ctr.ctr3.salt.string) == 0) {
473                                 talloc_free(scb);
474                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
475                                                  "PrimaryKerberos strlen(salt) == 0");
476                         }
477
478                         if (k->ctr.ctr3.num_keys != 2) {
479                                 talloc_free(scb);
480                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
481                                                  "PrimaryKerberos num_keys != 2");
482                         }
483
484                         if (k->ctr.ctr3.num_old_keys > k->ctr.ctr3.num_keys) {
485                                 talloc_free(scb);
486                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
487                                                  "PrimaryKerberos num_old_keys > num_keys");
488                         }
489
490                         if (k->ctr.ctr3.keys[0].keytype != ENCTYPE_DES_CBC_MD5) {
491                                 talloc_free(scb);
492                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
493                                                  "PrimaryKerberos key[0] != DES_CBC_MD5");
494                         }
495                         if (k->ctr.ctr3.keys[1].keytype != ENCTYPE_DES_CBC_CRC) {
496                                 talloc_free(scb);
497                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
498                                                  "PrimaryKerberos key[1] != DES_CBC_CRC");
499                         }
500
501                         if (k->ctr.ctr3.keys[0].value_len != 8) {
502                                 talloc_free(scb);
503                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
504                                                  "PrimaryKerberos key[0] value_len != 8");
505                         }
506                         if (k->ctr.ctr3.keys[1].value_len != 8) {
507                                 talloc_free(scb);
508                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
509                                                  "PrimaryKerberos key[1] value_len != 8");
510                         }
511
512                         for (i = 0; i < k->ctr.ctr3.num_old_keys; i++) {
513                                 if (k->ctr.ctr3.old_keys[i].keytype ==
514                                     k->ctr.ctr3.keys[i].keytype &&
515                                     k->ctr.ctr3.old_keys[i].value_len ==
516                                     k->ctr.ctr3.keys[i].value_len) {
517                                         continue;
518                                 }
519
520                                 talloc_free(scb);
521                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
522                                                  "PrimaryKerberos old_keys type/value_len doesn't match");
523                         }
524
525                         talloc_free(k);
526                 }
527
528                 if (scpkn) {
529                         struct package_PrimaryKerberosBlob *k;
530
531                         k = talloc_zero(scb, struct package_PrimaryKerberosBlob);
532                         if (k == NULL) {
533                                 talloc_free(scb);
534                                 return ldb_module_oom(module);
535                         }
536
537                         ndr_err = ndr_pull_struct_blob(&scpbkn, k, k,
538                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
539                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
540                                 talloc_free(scb);
541                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
542                                                  "ndr_pull_struct_blob PrimaryKerberosNewerKeys");
543                         }
544
545                         if (k->version != 4) {
546                                 talloc_free(scb);
547                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
548                                                  "KerberosNewerKeys version != 4");
549                         }
550
551                         if (k->ctr.ctr4.salt.string == NULL) {
552                                 talloc_free(scb);
553                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
554                                                  "KerberosNewerKeys salt == NULL");
555                         }
556
557                         if (strlen(k->ctr.ctr4.salt.string) == 0) {
558                                 talloc_free(scb);
559                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
560                                                  "KerberosNewerKeys strlen(salt) == 0");
561                         }
562
563                         if (k->ctr.ctr4.num_keys != 4) {
564                                 talloc_free(scb);
565                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
566                                                  "KerberosNewerKeys num_keys != 4");
567                         }
568
569                         if (k->ctr.ctr4.num_old_keys > k->ctr.ctr4.num_keys) {
570                                 talloc_free(scb);
571                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
572                                                  "KerberosNewerKeys num_old_keys > num_keys");
573                         }
574
575                         if (k->ctr.ctr4.num_older_keys > k->ctr.ctr4.num_old_keys) {
576                                 talloc_free(scb);
577                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
578                                                  "KerberosNewerKeys num_older_keys > num_old_keys");
579                         }
580
581                         if (k->ctr.ctr4.keys[0].keytype != ENCTYPE_AES256_CTS_HMAC_SHA1_96) {
582                                 talloc_free(scb);
583                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
584                                                  "KerberosNewerKeys key[0] != AES256");
585                         }
586                         if (k->ctr.ctr4.keys[1].keytype != ENCTYPE_AES128_CTS_HMAC_SHA1_96) {
587                                 talloc_free(scb);
588                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
589                                                  "KerberosNewerKeys key[1] != AES128");
590                         }
591                         if (k->ctr.ctr4.keys[2].keytype != ENCTYPE_DES_CBC_MD5) {
592                                 talloc_free(scb);
593                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
594                                                  "KerberosNewerKeys key[2] != DES_CBC_MD5");
595                         }
596                         if (k->ctr.ctr4.keys[3].keytype != ENCTYPE_DES_CBC_CRC) {
597                                 talloc_free(scb);
598                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
599                                                  "KerberosNewerKeys key[3] != DES_CBC_CRC");
600                         }
601
602                         if (k->ctr.ctr4.keys[0].value_len != 32) {
603                                 talloc_free(scb);
604                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
605                                                  "KerberosNewerKeys key[0] value_len != 32");
606                         }
607                         if (k->ctr.ctr4.keys[1].value_len != 16) {
608                                 talloc_free(scb);
609                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
610                                                  "KerberosNewerKeys key[1] value_len != 16");
611                         }
612                         if (k->ctr.ctr4.keys[2].value_len != 8) {
613                                 talloc_free(scb);
614                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
615                                                  "KerberosNewerKeys key[2] value_len != 8");
616                         }
617                         if (k->ctr.ctr4.keys[3].value_len != 8) {
618                                 talloc_free(scb);
619                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
620                                                  "KerberosNewerKeys key[3] value_len != 8");
621                         }
622
623                         /*
624                          * TODO:
625                          * Maybe we can check old and older keys here.
626                          * But we need to do some tests, if the old keys
627                          * can be taken from the PrimaryKerberos blob
628                          * (with only des keys), when the domain was upgraded
629                          * from w2k3 to w2k8.
630                          */
631
632                         talloc_free(k);
633                 }
634
635                 if (scpct) {
636                         struct package_PrimaryCLEARTEXTBlob *ct;
637
638                         ct = talloc_zero(scb, struct package_PrimaryCLEARTEXTBlob);
639                         if (ct == NULL) {
640                                 talloc_free(scb);
641                                 return ldb_module_oom(module);
642                         }
643
644                         ndr_err = ndr_pull_struct_blob(&scpbct, ct, ct,
645                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryCLEARTEXTBlob);
646                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
647                                 talloc_free(scb);
648                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
649                                                  "ndr_pull_struct_blob PrimaryCLEARTEXT");
650                         }
651
652                         if ((ct->cleartext.length % 2) != 0) {
653                                 talloc_free(scb);
654                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
655                                                  "PrimaryCLEARTEXT length % 2 != 0");
656                         }
657
658                         talloc_free(ct);
659                 }
660
661                 ndr_err = ndr_push_struct_blob(&blob, scb, scb,
662                                 (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
663                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
664                         talloc_free(scb);
665                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
666                                          "ndr_push_struct_blob");
667                 }
668
669                 if (sce->values[0].length != blob.length) {
670                         talloc_free(scb);
671                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
672                                          "supplementalCredentialsBlob length differ");
673                 }
674
675                 if (!mem_equal_const_time(sce->values[0].data, blob.data, blob.length)) {
676                         talloc_free(scb);
677                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
678                                          "supplementalCredentialsBlob memcmp differ");
679                 }
680
681                 talloc_free(scb);
682         }
683
684         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_bypass - validated\n");
685         return ldb_next_request(module, request);
686 }
687
688 /* Get the NT hash, and fill it in as an entry in the password history,
689    and specify it into io->g.nt_hash */
690
691 static int setup_nt_fields(struct setup_password_fields_io *io)
692 {
693         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
694         uint32_t i;
695         if (io->u.store_nt_hash) {
696                 io->g.nt_hash = io->n.nt_hash;
697         }
698
699         if (io->ac->status->domain_data.pwdHistoryLength == 0) {
700                 return LDB_SUCCESS;
701         }
702
703         /* We might not have an old NT password */
704
705         if (io->g.nt_hash == NULL) {
706                 /*
707                  * If there was not an NT hash specified, then don't
708                  * store the NT password history.
709                  *
710                  * While the NTLM code on a Windows DC will cope with
711                  * a missing unicodePwd, if it finds a last password
712                  * in the ntPwdHistory, even if the bytes are zero ,
713                  * it will (quite reasonably) treat it as a valid NT
714                  * hash.  NTLM logins with the previous password are
715                  * allowed for a short time after the password is
716                  * changed to allow for password propagation delays.
717                  */
718                 return LDB_SUCCESS;
719         }
720
721         io->g.nt_history = talloc_array(io->ac,
722                                         struct samr_Password,
723                                         io->ac->status->domain_data.pwdHistoryLength);
724         if (!io->g.nt_history) {
725                 return ldb_oom(ldb);
726         }
727
728         for (i = 0; i < MIN(io->ac->status->domain_data.pwdHistoryLength-1,
729                             io->o.nt_history_len); i++) {
730                 io->g.nt_history[i+1] = io->o.nt_history[i];
731         }
732         io->g.nt_history_len = i + 1;
733
734         io->g.nt_history[0] = *io->g.nt_hash;
735
736         return LDB_SUCCESS;
737 }
738
739 static int setup_kerberos_keys(struct setup_password_fields_io *io)
740 {
741         struct ldb_context *ldb;
742         krb5_error_code krb5_ret;
743         krb5_principal salt_principal = NULL;
744         krb5_data salt_data;
745         krb5_data salt;
746         krb5_keyblock key;
747         krb5_data cleartext_data;
748         uint32_t uac_flags = 0;
749
750         ldb = ldb_module_get_ctx(io->ac->module);
751         cleartext_data.data = (char *)io->n.cleartext_utf8->data;
752         cleartext_data.length = io->n.cleartext_utf8->length;
753
754         uac_flags = io->u.userAccountControl & UF_ACCOUNT_TYPE_MASK;
755         krb5_ret = smb_krb5_salt_principal(io->smb_krb5_context->krb5_context,
756                                            io->ac->status->domain_data.realm,
757                                            io->u.sAMAccountName,
758                                            io->u.user_principal_name,
759                                            uac_flags,
760                                            &salt_principal);
761         if (krb5_ret) {
762                 ldb_asprintf_errstring(ldb,
763                                        "setup_kerberos_keys: "
764                                        "generation of a salting principal failed: %s",
765                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
766                                                                   krb5_ret, io->ac));
767                 return LDB_ERR_OPERATIONS_ERROR;
768         }
769
770         /*
771          * create salt from salt_principal
772          */
773         krb5_ret = smb_krb5_get_pw_salt(io->smb_krb5_context->krb5_context,
774                                         salt_principal, &salt_data);
775
776         krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
777         if (krb5_ret) {
778                 ldb_asprintf_errstring(ldb,
779                                        "setup_kerberos_keys: "
780                                        "generation of krb5_salt failed: %s",
781                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
782                                                                   krb5_ret, io->ac));
783                 return LDB_ERR_OPERATIONS_ERROR;
784         }
785
786         /* now use the talloced copy of the salt */
787         salt.data       = talloc_strndup(io->ac,
788                                          (char *)salt_data.data,
789                                          salt_data.length);
790         smb_krb5_free_data_contents(io->smb_krb5_context->krb5_context,
791                                     &salt_data);
792         if (salt.data == NULL) {
793                 return ldb_oom(ldb);
794         }
795         io->g.salt      = salt.data;
796         salt.length     = strlen(io->g.salt);
797
798         /*
799          * create ENCTYPE_AES256_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_AES256_CTS_HMAC_SHA1_96,
807                                                    &key);
808         if (krb5_ret) {
809                 ldb_asprintf_errstring(ldb,
810                                        "setup_kerberos_keys: "
811                                        "generation of a aes256-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_256 = 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_256.data) {
821                 return ldb_oom(ldb);
822         }
823
824         /*
825          * create ENCTYPE_AES128_CTS_HMAC_SHA1_96 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_AES128_CTS_HMAC_SHA1_96,
833                                                    &key);
834         if (krb5_ret) {
835                 ldb_asprintf_errstring(ldb,
836                                        "setup_kerberos_keys: "
837                                        "generation of a aes128-cts-hmac-sha1-96 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.aes_128 = 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.aes_128.data) {
847                 return ldb_oom(ldb);
848         }
849
850         /*
851          * As per RFC-6649 single DES encryption types are no longer considered
852          * secure to be used in Kerberos, we store random keys instead of the
853          * ENCTYPE_DES_CBC_MD5 and ENCTYPE_DES_CBC_CRC keys.
854          */
855         io->g.des_md5 = data_blob_talloc(io->ac, NULL, 8);
856         if (!io->g.des_md5.data) {
857                 return ldb_oom(ldb);
858         }
859         generate_secret_buffer(io->g.des_md5.data, 8);
860
861         io->g.des_crc = data_blob_talloc(io->ac, NULL, 8);
862         if (!io->g.des_crc.data) {
863                 return ldb_oom(ldb);
864         }
865         generate_secret_buffer(io->g.des_crc.data, 8);
866
867         return LDB_SUCCESS;
868 }
869
870 static int setup_kerberos_key_hash(struct setup_password_fields_io *io,
871                                    struct setup_password_fields_given *g)
872 {
873         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
874         krb5_error_code krb5_ret;
875         krb5_data salt;
876         krb5_keyblock key;
877         krb5_data cleartext_data;
878
879         if (io->ac->search_res == NULL) {
880                 /* No old data so nothing to do */
881                 return LDB_SUCCESS;
882         }
883
884         if (io->o.salt.data == NULL) {
885                 /* We didn't fetch the salt in setup_io(), so nothing to do */
886                 return LDB_SUCCESS;
887         }
888
889         salt.data = (char *)io->o.salt.data;
890         salt.length = io->o.salt.length;
891
892         cleartext_data.data = (char *)g->cleartext_utf8->data;
893         cleartext_data.length = g->cleartext_utf8->length;
894
895         /*
896          * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of the salt
897          * and the cleartext password
898          */
899         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
900                                                    NULL,
901                                                    &salt,
902                                                    &cleartext_data,
903                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
904                                                    &key);
905         if (krb5_ret) {
906                 ldb_asprintf_errstring(ldb,
907                                        "setup_kerberos_key_hash: "
908                                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
909                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
910                                                                   krb5_ret, io->ac));
911                 return LDB_ERR_OPERATIONS_ERROR;
912         }
913
914         g->aes_256 = data_blob_talloc(io->ac,
915                                       KRB5_KEY_DATA(&key),
916                                       KRB5_KEY_LENGTH(&key));
917         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
918         if (g->aes_256.data == NULL) {
919                 return ldb_oom(ldb);
920         }
921
922         talloc_keep_secret(g->aes_256.data);
923
924         return LDB_SUCCESS;
925 }
926
927 static int setup_primary_kerberos(struct setup_password_fields_io *io,
928                                   const struct supplementalCredentialsBlob *old_scb,
929                                   struct package_PrimaryKerberosBlob *pkb)
930 {
931         struct ldb_context *ldb;
932         struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
933         struct supplementalCredentialsPackage *old_scp = NULL;
934         struct package_PrimaryKerberosBlob _old_pkb;
935         struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
936         uint32_t i;
937         enum ndr_err_code ndr_err;
938
939         ldb = ldb_module_get_ctx(io->ac->module);
940
941         /*
942          * prepare generation of keys
943          *
944          * ENCTYPE_DES_CBC_MD5
945          * ENCTYPE_DES_CBC_CRC
946          */
947         pkb->version            = 3;
948         pkb3->salt.string       = io->g.salt;
949         pkb3->num_keys          = 2;
950         pkb3->keys              = talloc_array(io->ac,
951                                                struct package_PrimaryKerberosKey3,
952                                                pkb3->num_keys);
953         if (!pkb3->keys) {
954                 return ldb_oom(ldb);
955         }
956
957         pkb3->keys[0].keytype   = ENCTYPE_DES_CBC_MD5;
958         pkb3->keys[0].value     = &io->g.des_md5;
959         pkb3->keys[1].keytype   = ENCTYPE_DES_CBC_CRC;
960         pkb3->keys[1].value     = &io->g.des_crc;
961
962         /* initialize the old keys to zero */
963         pkb3->num_old_keys      = 0;
964         pkb3->old_keys          = NULL;
965
966         /* if there're no old keys, then we're done */
967         if (!old_scb) {
968                 return LDB_SUCCESS;
969         }
970
971         for (i=0; i < old_scb->sub.num_packages; i++) {
972                 if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
973                         continue;
974                 }
975
976                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
977                         continue;
978                 }
979
980                 old_scp = &old_scb->sub.packages[i];
981                 break;
982         }
983         /* Primary:Kerberos element of supplementalCredentials */
984         if (old_scp) {
985                 DATA_BLOB blob;
986
987                 blob = strhex_to_data_blob(io->ac, old_scp->data);
988                 if (!blob.data) {
989                         return ldb_oom(ldb);
990                 }
991
992                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
993                 ndr_err = ndr_pull_struct_blob(&blob, io->ac, &_old_pkb,
994                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
995                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
996                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
997                         ldb_asprintf_errstring(ldb,
998                                                "setup_primary_kerberos: "
999                                                "failed to pull old package_PrimaryKerberosBlob: %s",
1000                                                nt_errstr(status));
1001                         return LDB_ERR_OPERATIONS_ERROR;
1002                 }
1003
1004                 if (_old_pkb.version != 3) {
1005                         ldb_asprintf_errstring(ldb,
1006                                                "setup_primary_kerberos: "
1007                                                "package_PrimaryKerberosBlob version[%u] expected[3]",
1008                                                _old_pkb.version);
1009                         return LDB_ERR_OPERATIONS_ERROR;
1010                 }
1011
1012                 old_pkb3 = &_old_pkb.ctr.ctr3;
1013         }
1014
1015         /* if we didn't find the old keys we're done */
1016         if (!old_pkb3) {
1017                 return LDB_SUCCESS;
1018         }
1019
1020         /* fill in the old keys */
1021         pkb3->num_old_keys      = old_pkb3->num_keys;
1022         pkb3->old_keys          = old_pkb3->keys;
1023
1024         return LDB_SUCCESS;
1025 }
1026
1027 static int setup_primary_kerberos_newer(struct setup_password_fields_io *io,
1028                                         const struct supplementalCredentialsBlob *old_scb,
1029                                         struct package_PrimaryKerberosBlob *pkb)
1030 {
1031         struct ldb_context *ldb;
1032         struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4;
1033         struct supplementalCredentialsPackage *old_scp = NULL;
1034         struct package_PrimaryKerberosBlob _old_pkb;
1035         struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL;
1036         uint32_t i;
1037         enum ndr_err_code ndr_err;
1038
1039         ldb = ldb_module_get_ctx(io->ac->module);
1040
1041         /*
1042          * prepare generation of keys
1043          *
1044          * ENCTYPE_AES256_CTS_HMAC_SHA1_96
1045          * ENCTYPE_AES128_CTS_HMAC_SHA1_96
1046          * ENCTYPE_DES_CBC_MD5
1047          * ENCTYPE_DES_CBC_CRC
1048          */
1049         pkb->version                    = 4;
1050         pkb4->salt.string               = io->g.salt;
1051         pkb4->default_iteration_count   = 4096;
1052         pkb4->num_keys                  = 4;
1053
1054         pkb4->keys = talloc_array(io->ac,
1055                                   struct package_PrimaryKerberosKey4,
1056                                   pkb4->num_keys);
1057         if (!pkb4->keys) {
1058                 return ldb_oom(ldb);
1059         }
1060
1061         pkb4->keys[0].iteration_count   = 4096;
1062         pkb4->keys[0].keytype           = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1063         pkb4->keys[0].value             = &io->g.aes_256;
1064         pkb4->keys[1].iteration_count   = 4096;
1065         pkb4->keys[1].keytype           = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1066         pkb4->keys[1].value             = &io->g.aes_128;
1067         pkb4->keys[2].iteration_count   = 4096;
1068         pkb4->keys[2].keytype           = ENCTYPE_DES_CBC_MD5;
1069         pkb4->keys[2].value             = &io->g.des_md5;
1070         pkb4->keys[3].iteration_count   = 4096;
1071         pkb4->keys[3].keytype           = ENCTYPE_DES_CBC_CRC;
1072         pkb4->keys[3].value             = &io->g.des_crc;
1073
1074         /* initialize the old keys to zero */
1075         pkb4->num_old_keys      = 0;
1076         pkb4->old_keys          = NULL;
1077         pkb4->num_older_keys    = 0;
1078         pkb4->older_keys        = NULL;
1079
1080         /* if there're no old keys, then we're done */
1081         if (!old_scb) {
1082                 return LDB_SUCCESS;
1083         }
1084
1085         for (i=0; i < old_scb->sub.num_packages; i++) {
1086                 if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) {
1087                         continue;
1088                 }
1089
1090                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
1091                         continue;
1092                 }
1093
1094                 old_scp = &old_scb->sub.packages[i];
1095                 break;
1096         }
1097         /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
1098         if (old_scp) {
1099                 DATA_BLOB blob;
1100
1101                 blob = strhex_to_data_blob(io->ac, old_scp->data);
1102                 if (!blob.data) {
1103                         return ldb_oom(ldb);
1104                 }
1105
1106                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
1107                 ndr_err = ndr_pull_struct_blob(&blob, io->ac,
1108                                                &_old_pkb,
1109                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
1110                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1111                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1112                         ldb_asprintf_errstring(ldb,
1113                                                "setup_primary_kerberos_newer: "
1114                                                "failed to pull old package_PrimaryKerberosBlob: %s",
1115                                                nt_errstr(status));
1116                         return LDB_ERR_OPERATIONS_ERROR;
1117                 }
1118
1119                 if (_old_pkb.version != 4) {
1120                         ldb_asprintf_errstring(ldb,
1121                                                "setup_primary_kerberos_newer: "
1122                                                "package_PrimaryKerberosBlob version[%u] expected[4]",
1123                                                _old_pkb.version);
1124                         return LDB_ERR_OPERATIONS_ERROR;
1125                 }
1126
1127                 old_pkb4 = &_old_pkb.ctr.ctr4;
1128         }
1129
1130         /* if we didn't find the old keys we're done */
1131         if (!old_pkb4) {
1132                 return LDB_SUCCESS;
1133         }
1134
1135         /* fill in the old keys */
1136         pkb4->num_old_keys      = old_pkb4->num_keys;
1137         pkb4->old_keys          = old_pkb4->keys;
1138         pkb4->num_older_keys    = old_pkb4->num_old_keys;
1139         pkb4->older_keys        = old_pkb4->old_keys;
1140
1141         return LDB_SUCCESS;
1142 }
1143
1144 static int setup_primary_wdigest(struct setup_password_fields_io *io,
1145                                  const struct supplementalCredentialsBlob *old_scb,
1146                                  struct package_PrimaryWDigestBlob *pdb)
1147 {
1148         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1149         DATA_BLOB sAMAccountName;
1150         DATA_BLOB sAMAccountName_l;
1151         DATA_BLOB sAMAccountName_u;
1152         const char *user_principal_name = io->u.user_principal_name;
1153         DATA_BLOB userPrincipalName;
1154         DATA_BLOB userPrincipalName_l;
1155         DATA_BLOB userPrincipalName_u;
1156         DATA_BLOB netbios_domain;
1157         DATA_BLOB netbios_domain_l;
1158         DATA_BLOB netbios_domain_u;
1159         DATA_BLOB dns_domain;
1160         DATA_BLOB dns_domain_l;
1161         DATA_BLOB dns_domain_u;
1162         DATA_BLOB digest;
1163         DATA_BLOB delim;
1164         DATA_BLOB backslash;
1165         uint8_t i;
1166         struct {
1167                 DATA_BLOB *user;
1168                 DATA_BLOB *realm;
1169                 DATA_BLOB *nt4dom;
1170         } wdigest[] = {
1171         /*
1172          * See 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction
1173          *     https://msdn.microsoft.com/en-us/library/cc245680.aspx
1174          * for what precalculated hashes are supposed to be stored...
1175          *
1176          * I can't reproduce all values which should contain "Digest" as realm,
1177          * am I doing something wrong or is w2k3 just broken...?
1178          *
1179          * W2K3 fills in following for a user:
1180          *
1181          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1182          * sAMAccountName: NewUser2Sam
1183          * userPrincipalName: NewUser2Princ@sub1.w2k3.vmnet1.vm.base
1184          *
1185          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1186          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1187          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1188          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1189          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1190          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1191          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1192          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1193          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1194          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1195          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1196          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1197          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1198          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1199          * 221c55284451ae9b3aacaa2a3c86f10f => NewUser2Princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1200          * 74e1be668853d4324d38c07e2acfb8ea => (w2k3 has a bug here!) newuser2princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1201          * e1e244ab7f098e3ae1761be7f9229bbb => NEWUSER2PRINC@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1202          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1203          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1204          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1205          * 31dc704d3640335b2123d4ee28aa1f11 => ??? changes with NewUser2Sam => NewUser1Sam
1206          * 36349f5cecd07320fb3bb0e119230c43 => ??? changes with NewUser2Sam => NewUser1Sam
1207          * 12adf019d037fb535c01fd0608e78d9d => ??? changes with NewUser2Sam => NewUser1Sam
1208          * 6feecf8e724906f3ee1105819c5105a1 => ??? changes with NewUser2Princ => NewUser1Princ
1209          * 6c6911f3de6333422640221b9c51ff1f => ??? changes with NewUser2Princ => NewUser1Princ
1210          * 4b279877e742895f9348ac67a8de2f69 => ??? changes with NewUser2Princ => NewUser1Princ
1211          * db0c6bff069513e3ebb9870d29b57490 => ??? changes with NewUser2Sam => NewUser1Sam
1212          * 45072621e56b1c113a4e04a8ff68cd0e => ??? changes with NewUser2Sam => NewUser1Sam
1213          * 11d1220abc44a9c10cf91ef4a9c1de02 => ??? changes with NewUser2Sam => NewUser1Sam
1214          *
1215          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1216          * sAMAccountName: NewUser2Sam
1217          *
1218          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1219          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1220          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1221          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1222          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1223          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1224          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1225          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1226          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1227          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1228          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1229          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1230          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1231          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1232          * 8a140d30b6f0a5912735dc1e3bc993b4 => NewUser2Sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1233          * 86d95b2faae6cae4ec261e7fbaccf093 => (here w2k3 is correct) newuser2sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1234          * dfeff1493110220efcdfc6362e5f5450 => NEWUSER2SAM@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1235          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1236          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1237          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1238          * 31dc704d3640335b2123d4ee28aa1f11 => ???M1   changes with NewUser2Sam => NewUser1Sam
1239          * 36349f5cecd07320fb3bb0e119230c43 => ???M1.L changes with newuser2sam => newuser1sam
1240          * 12adf019d037fb535c01fd0608e78d9d => ???M1.U changes with NEWUSER2SAM => NEWUSER1SAM
1241          * 569b4533f2d9e580211dd040e5e360a8 => ???M2   changes with NewUser2Princ => NewUser1Princ
1242          * 52528bddf310a587c5d7e6a9ae2cbb20 => ???M2.L changes with newuser2princ => newuser1princ
1243          * 4f629a4f0361289ca4255ab0f658fcd5 => ???M3 changes with NewUser2Princ => NewUser1Princ (doesn't depend on case of userPrincipal )
1244          * db0c6bff069513e3ebb9870d29b57490 => ???M4 changes with NewUser2Sam => NewUser1Sam
1245          * 45072621e56b1c113a4e04a8ff68cd0e => ???M5 changes with NewUser2Sam => NewUser1Sam (doesn't depend on case of sAMAccountName)
1246          * 11d1220abc44a9c10cf91ef4a9c1de02 => ???M4.U changes with NEWUSER2SAM => NEWUSER1SAM
1247          */
1248
1249         /*
1250          * sAMAccountName, netbios_domain
1251          */
1252                 {
1253                 .user   = &sAMAccountName,
1254                 .realm  = &netbios_domain,
1255                 },
1256                 {
1257                 .user   = &sAMAccountName_l,
1258                 .realm  = &netbios_domain_l,
1259                 },
1260                 {
1261                 .user   = &sAMAccountName_u,
1262                 .realm  = &netbios_domain_u,
1263                 },
1264                 {
1265                 .user   = &sAMAccountName,
1266                 .realm  = &netbios_domain_u,
1267                 },
1268                 {
1269                 .user   = &sAMAccountName,
1270                 .realm  = &netbios_domain_l,
1271                 },
1272                 {
1273                 .user   = &sAMAccountName_u,
1274                 .realm  = &netbios_domain_l,
1275                 },
1276                 {
1277                 .user   = &sAMAccountName_l,
1278                 .realm  = &netbios_domain_u,
1279                 },
1280         /*
1281          * sAMAccountName, dns_domain
1282          *
1283          * TODO:
1284          * Windows preserves the case of the DNS domain,
1285          * Samba lower cases the domain at provision time
1286          * This means that for mixed case Domains, the WDigest08 hash
1287          * calculated by Samba differs from that calculated by Windows.
1288          * Until we get a real world use case this will remain a known
1289          * bug, as changing the case could have unforeseen impacts.
1290          *
1291          */
1292                 {
1293                 .user   = &sAMAccountName,
1294                 .realm  = &dns_domain,
1295                 },
1296                 {
1297                 .user   = &sAMAccountName_l,
1298                 .realm  = &dns_domain_l,
1299                 },
1300                 {
1301                 .user   = &sAMAccountName_u,
1302                 .realm  = &dns_domain_u,
1303                 },
1304                 {
1305                 .user   = &sAMAccountName,
1306                 .realm  = &dns_domain_u,
1307                 },
1308                 {
1309                 .user   = &sAMAccountName,
1310                 .realm  = &dns_domain_l,
1311                 },
1312                 {
1313                 .user   = &sAMAccountName_u,
1314                 .realm  = &dns_domain_l,
1315                 },
1316                 {
1317                 .user   = &sAMAccountName_l,
1318                 .realm  = &dns_domain_u,
1319                 },
1320         /*
1321          * userPrincipalName, no realm
1322          */
1323                 {
1324                 .user   = &userPrincipalName,
1325                 },
1326                 {
1327                 /*
1328                  * NOTE: w2k3 messes this up, if the user has a real userPrincipalName,
1329                  *       the fallback to the sAMAccountName based userPrincipalName is correct
1330                  */
1331                 .user   = &userPrincipalName_l,
1332                 },
1333                 {
1334                 .user   = &userPrincipalName_u,
1335                 },
1336         /*
1337          * nt4dom\sAMAccountName, no realm
1338          */
1339                 {
1340                 .user   = &sAMAccountName,
1341                 .nt4dom = &netbios_domain
1342                 },
1343                 {
1344                 .user   = &sAMAccountName_l,
1345                 .nt4dom = &netbios_domain_l
1346                 },
1347                 {
1348                 .user   = &sAMAccountName_u,
1349                 .nt4dom = &netbios_domain_u
1350                 },
1351
1352         /*
1353          * the following ones are guessed depending on the technet2 article
1354          * but not reproducible on a w2k3 server
1355          */
1356         /* sAMAccountName with "Digest" realm */
1357                 {
1358                 .user   = &sAMAccountName,
1359                 .realm  = &digest
1360                 },
1361                 {
1362                 .user   = &sAMAccountName_l,
1363                 .realm  = &digest
1364                 },
1365                 {
1366                 .user   = &sAMAccountName_u,
1367                 .realm  = &digest
1368                 },
1369         /* userPrincipalName with "Digest" realm */
1370                 {
1371                 .user   = &userPrincipalName,
1372                 .realm  = &digest
1373                 },
1374                 {
1375                 .user   = &userPrincipalName_l,
1376                 .realm  = &digest
1377                 },
1378                 {
1379                 .user   = &userPrincipalName_u,
1380                 .realm  = &digest
1381                 },
1382         /* nt4dom\\sAMAccountName with "Digest" realm */
1383                 {
1384                 .user   = &sAMAccountName,
1385                 .nt4dom = &netbios_domain,
1386                 .realm  = &digest
1387                 },
1388                 {
1389                 .user   = &sAMAccountName_l,
1390                 .nt4dom = &netbios_domain_l,
1391                 .realm  = &digest
1392                 },
1393                 {
1394                 .user   = &sAMAccountName_u,
1395                 .nt4dom = &netbios_domain_u,
1396                 .realm  = &digest
1397                 },
1398         };
1399         int rc = LDB_ERR_OTHER;
1400
1401         /* prepare DATA_BLOB's used in the combinations array */
1402         sAMAccountName          = data_blob_string_const(io->u.sAMAccountName);
1403         sAMAccountName_l        = data_blob_string_const(strlower_talloc(io->ac, io->u.sAMAccountName));
1404         if (!sAMAccountName_l.data) {
1405                 return ldb_oom(ldb);
1406         }
1407         sAMAccountName_u        = data_blob_string_const(strupper_talloc(io->ac, io->u.sAMAccountName));
1408         if (!sAMAccountName_u.data) {
1409                 return ldb_oom(ldb);
1410         }
1411
1412         /* if the user doesn't have a userPrincipalName, create one (with lower case realm) */
1413         if (!user_principal_name) {
1414                 user_principal_name = talloc_asprintf(io->ac, "%s@%s",
1415                                                       io->u.sAMAccountName,
1416                                                       io->ac->status->domain_data.dns_domain);
1417                 if (!user_principal_name) {
1418                         return ldb_oom(ldb);
1419                 }
1420         }
1421         userPrincipalName       = data_blob_string_const(user_principal_name);
1422         userPrincipalName_l     = data_blob_string_const(strlower_talloc(io->ac, user_principal_name));
1423         if (!userPrincipalName_l.data) {
1424                 return ldb_oom(ldb);
1425         }
1426         userPrincipalName_u     = data_blob_string_const(strupper_talloc(io->ac, user_principal_name));
1427         if (!userPrincipalName_u.data) {
1428                 return ldb_oom(ldb);
1429         }
1430
1431         netbios_domain          = data_blob_string_const(io->ac->status->domain_data.netbios_domain);
1432         netbios_domain_l        = data_blob_string_const(strlower_talloc(io->ac,
1433                                                                          io->ac->status->domain_data.netbios_domain));
1434         if (!netbios_domain_l.data) {
1435                 return ldb_oom(ldb);
1436         }
1437         netbios_domain_u        = data_blob_string_const(strupper_talloc(io->ac,
1438                                                                          io->ac->status->domain_data.netbios_domain));
1439         if (!netbios_domain_u.data) {
1440                 return ldb_oom(ldb);
1441         }
1442
1443         dns_domain              = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1444         dns_domain_l            = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1445         dns_domain_u            = data_blob_string_const(io->ac->status->domain_data.realm);
1446
1447         digest                  = data_blob_string_const("Digest");
1448
1449         delim                   = data_blob_string_const(":");
1450         backslash               = data_blob_string_const("\\");
1451
1452         pdb->num_hashes = ARRAY_SIZE(wdigest);
1453         pdb->hashes     = talloc_array(io->ac, struct package_PrimaryWDigestHash,
1454                                        pdb->num_hashes);
1455         if (!pdb->hashes) {
1456                 return ldb_oom(ldb);
1457         }
1458
1459         for (i=0; i < ARRAY_SIZE(wdigest); i++) {
1460                 gnutls_hash_hd_t hash_hnd = NULL;
1461
1462                 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
1463                 if (rc < 0) {
1464                         rc = ldb_oom(ldb);
1465                         goto out;
1466                 }
1467
1468                 if (wdigest[i].nt4dom) {
1469                         rc = gnutls_hash(hash_hnd,
1470                                           wdigest[i].nt4dom->data,
1471                                           wdigest[i].nt4dom->length);
1472                         if (rc < 0) {
1473                                 gnutls_hash_deinit(hash_hnd, NULL);
1474                                 rc = LDB_ERR_UNWILLING_TO_PERFORM;
1475                                 goto out;
1476                         }
1477                         rc = gnutls_hash(hash_hnd,
1478                                           backslash.data,
1479                                           backslash.length);
1480                         if (rc < 0) {
1481                                 gnutls_hash_deinit(hash_hnd, NULL);
1482                                 rc = LDB_ERR_UNWILLING_TO_PERFORM;
1483                                 goto out;
1484                         }
1485                 }
1486                 rc = gnutls_hash(hash_hnd,
1487                                  wdigest[i].user->data,
1488                                  wdigest[i].user->length);
1489                 if (rc < 0) {
1490                         gnutls_hash_deinit(hash_hnd, NULL);
1491                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1492                         goto out;
1493                 }
1494                 rc = gnutls_hash(hash_hnd, delim.data, delim.length);
1495                 if (rc < 0) {
1496                         gnutls_hash_deinit(hash_hnd, NULL);
1497                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1498                         goto out;
1499                 }
1500                 if (wdigest[i].realm) {
1501                         rc = gnutls_hash(hash_hnd,
1502                                          wdigest[i].realm->data,
1503                                          wdigest[i].realm->length);
1504                         if (rc < 0) {
1505                                 gnutls_hash_deinit(hash_hnd, NULL);
1506                                 rc = LDB_ERR_UNWILLING_TO_PERFORM;
1507                                 goto out;
1508                         }
1509                 }
1510                 rc = gnutls_hash(hash_hnd, delim.data, delim.length);
1511                 if (rc < 0) {
1512                         gnutls_hash_deinit(hash_hnd, NULL);
1513                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1514                         goto out;
1515                 }
1516                 rc = gnutls_hash(hash_hnd,
1517                                   io->n.cleartext_utf8->data,
1518                                   io->n.cleartext_utf8->length);
1519                 if (rc < 0) {
1520                         gnutls_hash_deinit(hash_hnd, NULL);
1521                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1522                         goto out;
1523                 }
1524
1525                 gnutls_hash_deinit(hash_hnd, pdb->hashes[i].hash);
1526         }
1527
1528         rc = LDB_SUCCESS;
1529 out:
1530         return rc;
1531 }
1532
1533 #define SHA_SALT_PERMITTED_CHARS "abcdefghijklmnopqrstuvwxyz" \
1534                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
1535                                  "0123456789./"
1536 #define SHA_SALT_SIZE 16
1537 #define SHA_256_SCHEME "CryptSHA256"
1538 #define SHA_512_SCHEME "CryptSHA512"
1539 #define CRYPT "{CRYPT}"
1540 #define SHA_ID_LEN 3
1541 #define SHA_256_ALGORITHM_ID 5
1542 #define SHA_512_ALGORITHM_ID 6
1543 #define ROUNDS_PARAMETER "rounds="
1544
1545 /*
1546  * Extract the crypt (3) algorithm number and number of hash rounds from the
1547  * supplied scheme string
1548  */
1549 static bool parse_scheme(const char *scheme, int *algorithm, int *rounds) {
1550
1551         const char *rp = NULL; /* Pointer to the 'rounds=' option */
1552         char digits[21];       /* digits extracted from the rounds option */
1553         int i = 0;             /* loop index variable */
1554
1555         if (strncasecmp(SHA_256_SCHEME, scheme, strlen(SHA_256_SCHEME)) == 0) {
1556                 *algorithm = SHA_256_ALGORITHM_ID;
1557         } else if (strncasecmp(SHA_512_SCHEME, scheme, strlen(SHA_256_SCHEME))
1558                    == 0) {
1559                 *algorithm = SHA_512_ALGORITHM_ID;
1560         } else {
1561                 return false;
1562         }
1563
1564         rp = strcasestr(scheme, ROUNDS_PARAMETER);
1565         if (rp == NULL) {
1566                 /* No options specified, use crypt default number of rounds */
1567                 *rounds = 0;
1568                 return true;
1569         }
1570         rp += strlen(ROUNDS_PARAMETER);
1571         for (i = 0; isdigit(rp[i]) && i < (sizeof(digits) - 1); i++) {
1572                 digits[i] = rp[i];
1573         }
1574         digits[i] = '\0';
1575         *rounds = atoi(digits);
1576         return true;
1577 }
1578
1579 /*
1580  * Calculate the password hash specified by scheme, and return it in
1581  * hash_value
1582  */
1583 static int setup_primary_userPassword_hash(
1584         TALLOC_CTX *ctx,
1585         struct setup_password_fields_io *io,
1586         const char* scheme,
1587         struct package_PrimaryUserPasswordValue *hash_value)
1588 {
1589         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1590         const char *salt = NULL;        /* Randomly generated salt */
1591         const char *cmd = NULL;         /* command passed to crypt */
1592         const char *hash = NULL;        /* password hash generated by crypt */
1593         int algorithm = 0;              /* crypt hash algorithm number */
1594         int rounds = 0;                 /* The number of hash rounds */
1595         DATA_BLOB *hash_blob = NULL;
1596         TALLOC_CTX *frame = talloc_stackframe();
1597 #if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT_RN)
1598         struct crypt_data crypt_data = {
1599                 .initialized = 0        /* working storage used by crypt */
1600         };
1601 #endif
1602
1603         /* Generate a random password salt */
1604         salt = generate_random_str_list(frame,
1605                                         SHA_SALT_SIZE,
1606                                         SHA_SALT_PERMITTED_CHARS);
1607         if (salt == NULL) {
1608                 TALLOC_FREE(frame);
1609                 return ldb_oom(ldb);
1610         }
1611
1612         /* determine the hashing algorithm and number of rounds*/
1613         if (!parse_scheme(scheme, &algorithm, &rounds)) {
1614                 ldb_asprintf_errstring(
1615                         ldb,
1616                         "setup_primary_userPassword: Invalid scheme of [%s] "
1617                         "specified for 'password hash userPassword schemes' in "
1618                         "samba.conf",
1619                         scheme);
1620                 TALLOC_FREE(frame);
1621                 return LDB_ERR_OPERATIONS_ERROR;
1622         }
1623         hash_value->scheme = talloc_strdup(ctx, CRYPT);
1624         if (hash_value->scheme == NULL) {
1625                 TALLOC_FREE(frame);
1626                 return ldb_oom(ldb);
1627         }
1628         hash_value->scheme_len = strlen(CRYPT) + 1;
1629
1630         /* generate the id/salt parameter used by crypt */
1631         if (rounds) {
1632                 cmd = talloc_asprintf(frame,
1633                                       "$%d$rounds=%d$%s",
1634                                       algorithm,
1635                                       rounds,
1636                                       salt);
1637                 if (cmd == NULL) {
1638                         TALLOC_FREE(frame);
1639                         return ldb_oom(ldb);
1640                 }
1641         } else {
1642                 cmd = talloc_asprintf(frame, "$%d$%s", algorithm, salt);
1643                 if (cmd == NULL) {
1644                         TALLOC_FREE(frame);
1645                         return ldb_oom(ldb);
1646                 }
1647         }
1648
1649         /*
1650          * Relies on the assertion that cleartext_utf8->data is a zero
1651          * terminated UTF-8 string
1652          */
1653
1654         /*
1655          * crypt_r() and crypt() may return a null pointer upon error
1656          * depending on how libcrypt was configured, so we prefer
1657          * crypt_rn() from libcrypt / libxcrypt which always returns
1658          * NULL on error.
1659          *
1660          * POSIX specifies returning a null pointer and setting
1661          * errno.
1662          *
1663          * RHEL 7 (which does not use libcrypt / libxcrypt) returns a
1664          * non-NULL pointer from crypt_r() on success but (always?)
1665          * sets errno during internal processing in the NSS crypto
1666          * subsystem.
1667          *
1668          * By preferring crypt_rn we avoid the 'return non-NULL but
1669          * set-errno' that we otherwise cannot tell apart from the
1670          * RHEL 7 behaviour.
1671          */
1672         errno = 0;
1673
1674 #ifdef HAVE_CRYPT_RN
1675         hash = crypt_rn((char *)io->n.cleartext_utf8->data,
1676                         cmd,
1677                         &crypt_data,
1678                         sizeof(crypt_data));
1679 #elif HAVE_CRYPT_R
1680         hash = crypt_r((char *)io->n.cleartext_utf8->data, cmd, &crypt_data);
1681 #else
1682         /*
1683          * No crypt_r falling back to crypt, which is NOT thread safe
1684          * Thread safety MT-Unsafe race:crypt
1685          */
1686         hash = crypt((char *)io->n.cleartext_utf8->data, cmd);
1687 #endif
1688         /*
1689         * On error, crypt() and crypt_r() may return a null pointer,
1690         * or a pointer to an invalid hash beginning with a '*'.
1691         */
1692         if (hash == NULL || hash[0] == '*') {
1693                 char buf[1024];
1694                 const char *reason = NULL;
1695                 if (errno == ERANGE) {
1696                         reason = "Password exceeds maximum length allowed for crypt() hashing";
1697                 } else {
1698                         int err = strerror_r(errno, buf, sizeof(buf));
1699                         if (err == 0) {
1700                                 reason = buf;
1701                         } else {
1702                                 reason = "Unknown error";
1703                         }
1704                 }
1705                 ldb_asprintf_errstring(
1706                         ldb,
1707                         "setup_primary_userPassword: generation of a %s "
1708                         "password hash failed: (%s)",
1709                         scheme,
1710                         reason);
1711                 TALLOC_FREE(frame);
1712                 return LDB_ERR_OPERATIONS_ERROR;
1713         }
1714
1715         hash_blob = talloc_zero(ctx, DATA_BLOB);
1716
1717         if (hash_blob == NULL) {
1718                 TALLOC_FREE(frame);
1719                 return ldb_oom(ldb);
1720         }
1721
1722         *hash_blob =  data_blob_talloc(hash_blob,
1723                                        (const uint8_t *)hash,
1724                                        strlen(hash));
1725         if (hash_blob->data == NULL) {
1726                 TALLOC_FREE(frame);
1727                 return ldb_oom(ldb);
1728         }
1729         hash_value->value = hash_blob;
1730         TALLOC_FREE(frame);
1731         return LDB_SUCCESS;
1732 }
1733
1734 /*
1735  * Calculate the desired extra password hashes
1736  */
1737 static int setup_primary_userPassword(
1738         struct setup_password_fields_io *io,
1739         const struct supplementalCredentialsBlob *old_scb,
1740         struct package_PrimaryUserPasswordBlob *p_userPassword_b)
1741 {
1742         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1743         TALLOC_CTX *frame = talloc_stackframe();
1744         int i;
1745         int ret;
1746
1747         /*
1748          * Save the current nt_hash, use this to determine if the password
1749          * has been changed by windows. Which will invalidate the userPassword
1750          * hash. Note once NTLM-Strong-NOWTF becomes available it should be
1751          * used in preference to the NT password hash
1752          */
1753         if (io->g.nt_hash == NULL) {
1754                 /*
1755                  * When the NT hash is not available, we use this field to store
1756                  * the first 16 bytes of the AES256 key instead. This allows
1757                  * 'samba-tool user' to verify that the user's password is in
1758                  * sync with the userPassword package.
1759                  */
1760                 uint8_t hash_len = MIN(16, io->g.aes_256.length);
1761
1762                 ZERO_STRUCT(p_userPassword_b->current_nt_hash);
1763                 memcpy(p_userPassword_b->current_nt_hash.hash,
1764                        io->g.aes_256.data,
1765                        hash_len);
1766         } else {
1767                 p_userPassword_b->current_nt_hash = *io->g.nt_hash;
1768         }
1769
1770         /*
1771          * Determine the number of hashes
1772          * Note: that currently there is no limit on the number of hashes
1773          *       no checking is done on the number of schemes specified
1774          *       or for uniqueness.
1775          */
1776         p_userPassword_b->num_hashes = 0;
1777         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1778                 p_userPassword_b->num_hashes++;
1779         }
1780
1781         p_userPassword_b->hashes
1782                 = talloc_array(io->ac,
1783                                struct package_PrimaryUserPasswordValue,
1784                                p_userPassword_b->num_hashes);
1785         if (p_userPassword_b->hashes == NULL) {
1786                 TALLOC_FREE(frame);
1787                 return ldb_oom(ldb);
1788         }
1789
1790         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1791                 ret = setup_primary_userPassword_hash(
1792                         p_userPassword_b->hashes,
1793                         io,
1794                         io->ac->userPassword_schemes[i],
1795                         &p_userPassword_b->hashes[i]);
1796                 if (ret != LDB_SUCCESS) {
1797                         TALLOC_FREE(frame);
1798                         return ret;
1799                 }
1800         }
1801         TALLOC_FREE(frame);
1802         return LDB_SUCCESS;
1803 }
1804
1805
1806 static int setup_primary_samba_gpg(struct setup_password_fields_io *io,
1807                                    struct package_PrimarySambaGPGBlob *pgb)
1808 {
1809         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1810 #ifdef ENABLE_GPGME
1811         gpgme_error_t gret;
1812         gpgme_ctx_t ctx = NULL;
1813         size_t num_keys = str_list_length(io->ac->gpg_key_ids);
1814         gpgme_key_t keys[num_keys+1];
1815         size_t ki = 0;
1816         size_t kr = 0;
1817         gpgme_data_t plain_data = NULL;
1818         gpgme_data_t crypt_data = NULL;
1819         size_t crypt_length = 0;
1820         char *crypt_mem = NULL;
1821
1822         gret = gpgme_new(&ctx);
1823         if (gret != GPG_ERR_NO_ERROR) {
1824                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1825                           "%s:%s: gret[%u] %s\n",
1826                           __location__, __func__,
1827                           gret, gpgme_strerror(gret));
1828                 return ldb_module_operr(io->ac->module);
1829         }
1830
1831         gpgme_set_armor(ctx, 1);
1832
1833         gret = gpgme_data_new_from_mem(&plain_data,
1834                                        (const char *)io->n.cleartext_utf16->data,
1835                                        io->n.cleartext_utf16->length,
1836                                        0 /* no copy */);
1837         if (gret != GPG_ERR_NO_ERROR) {
1838                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1839                           "%s:%s: gret[%u] %s\n",
1840                           __location__, __func__,
1841                           gret, gpgme_strerror(gret));
1842                 gpgme_release(ctx);
1843                 return ldb_module_operr(io->ac->module);
1844         }
1845         gret = gpgme_data_new(&crypt_data);
1846         if (gret != GPG_ERR_NO_ERROR) {
1847                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1848                           "%s:%s: gret[%u] %s\n",
1849                           __location__, __func__,
1850                           gret, gpgme_strerror(gret));
1851                 gpgme_data_release(plain_data);
1852                 gpgme_release(ctx);
1853                 return ldb_module_operr(io->ac->module);
1854         }
1855
1856         for (ki = 0; ki < num_keys; ki++) {
1857                 const char *key_id = io->ac->gpg_key_ids[ki];
1858                 size_t len = strlen(key_id);
1859
1860                 keys[ki] = NULL;
1861
1862                 if (len < 16) {
1863                         ldb_debug(ldb, LDB_DEBUG_FATAL,
1864                                   "%s:%s: ki[%zu] key_id[%s] strlen < 16, "
1865                                   "please specify at least the 64bit key id\n",
1866                                   __location__, __func__,
1867                                   ki, key_id);
1868                         for (kr = 0; keys[kr] != NULL; kr++) {
1869                                 gpgme_key_release(keys[kr]);
1870                         }
1871                         gpgme_data_release(crypt_data);
1872                         gpgme_data_release(plain_data);
1873                         gpgme_release(ctx);
1874                         return ldb_module_operr(io->ac->module);
1875                 }
1876
1877                 gret = gpgme_get_key(ctx, key_id, &keys[ki], 0 /* public key */);
1878                 if (gret != GPG_ERR_NO_ERROR) {
1879                         keys[ki] = NULL;
1880                         if (gpg_err_source(gret) == GPG_ERR_SOURCE_GPGME
1881                             && gpg_err_code(gret) == GPG_ERR_EOF) {
1882                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1883                                           "Invalid "
1884                                           "'password hash gpg key ids': "
1885                                           "Public Key ID [%s] "
1886                                           "not found in keyring\n",
1887                                           key_id);
1888
1889                         } else {
1890                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1891                                           "%s:%s: ki[%zu] key_id[%s] "
1892                                           "gret[%u] %s\n",
1893                                           __location__, __func__,
1894                                           ki, key_id,
1895                                           gret, gpgme_strerror(gret));
1896                         }
1897                         for (kr = 0; keys[kr] != NULL; kr++) {
1898                                 gpgme_key_release(keys[kr]);
1899                         }
1900                         gpgme_data_release(crypt_data);
1901                         gpgme_data_release(plain_data);
1902                         gpgme_release(ctx);
1903                         return ldb_module_operr(io->ac->module);
1904                 }
1905         }
1906         keys[ki] = NULL;
1907
1908         gret = gpgme_op_encrypt(ctx, keys,
1909                                 GPGME_ENCRYPT_ALWAYS_TRUST,
1910                                 plain_data, crypt_data);
1911         gpgme_data_release(plain_data);
1912         plain_data = NULL;
1913         for (kr = 0; keys[kr] != NULL; kr++) {
1914                 gpgme_key_release(keys[kr]);
1915                 keys[kr] = NULL;
1916         }
1917         gpgme_release(ctx);
1918         ctx = NULL;
1919         if (gret != GPG_ERR_NO_ERROR) {
1920                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1921                           "%s:%s: gret[%u] %s\n",
1922                           __location__, __func__,
1923                           gret, gpgme_strerror(gret));
1924                 gpgme_data_release(crypt_data);
1925                 return ldb_module_operr(io->ac->module);
1926         }
1927
1928         crypt_mem = gpgme_data_release_and_get_mem(crypt_data, &crypt_length);
1929         crypt_data = NULL;
1930         if (crypt_mem == NULL) {
1931                 return ldb_module_oom(io->ac->module);
1932         }
1933
1934         pgb->gpg_blob = data_blob_talloc(io->ac,
1935                                          (const uint8_t *)crypt_mem,
1936                                          crypt_length);
1937         gpgme_free(crypt_mem);
1938         crypt_mem = NULL;
1939         crypt_length = 0;
1940         if (pgb->gpg_blob.data == NULL) {
1941                 return ldb_module_oom(io->ac->module);
1942         }
1943
1944         return LDB_SUCCESS;
1945 #else /* ENABLE_GPGME */
1946         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
1947                       "You configured 'password hash gpg key ids', "
1948                       "but GPGME support is missing. (%s:%d)",
1949                       __FILE__, __LINE__);
1950         return LDB_ERR_UNWILLING_TO_PERFORM;
1951 #endif /* else ENABLE_GPGME */
1952 }
1953
1954 #define NUM_PACKAGES 6
1955 static int setup_supplemental_field(struct setup_password_fields_io *io)
1956 {
1957         struct ldb_context *ldb;
1958         struct supplementalCredentialsBlob scb = {};
1959         struct supplementalCredentialsBlob *old_scb = NULL;
1960         /*
1961          * Packages +
1962          * ( Kerberos-Newer-Keys, Kerberos,
1963          *   WDigest, CLEARTEXT, userPassword, SambaGPG)
1964          */
1965         uint32_t num_names = 0;
1966         const char *names[1+NUM_PACKAGES] = {};
1967         uint32_t num_packages = 0;
1968         struct supplementalCredentialsPackage packages[1+NUM_PACKAGES] = {};
1969         struct supplementalCredentialsPackage *pp = packages;
1970         int ret;
1971         enum ndr_err_code ndr_err;
1972         bool do_newer_keys = false;
1973         bool do_cleartext = false;
1974         bool do_samba_gpg = false;
1975         struct loadparm_context *lp_ctx = NULL;
1976
1977         ldb = ldb_module_get_ctx(io->ac->module);
1978         lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1979                                  struct loadparm_context);
1980
1981         if (!io->n.cleartext_utf8) {
1982                 /*
1983                  * when we don't have a cleartext password
1984                  * we can't setup a supplementalCredentials value
1985                  */
1986                 return LDB_SUCCESS;
1987         }
1988
1989         /* if there's an old supplementalCredentials blob then use it */
1990         if (io->o.supplemental) {
1991                 if (io->o.scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
1992                         old_scb = &io->o.scb;
1993                 } else {
1994                         ldb_debug(ldb, LDB_DEBUG_ERROR,
1995                                   "setup_supplemental_field: "
1996                                   "supplementalCredentialsBlob "
1997                                   "signature[0x%04X] expected[0x%04X]",
1998                                   io->o.scb.sub.signature,
1999                                   SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
2000                 }
2001         }
2002         /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
2003
2004
2005
2006         /*
2007          * The ordering is this
2008          *
2009          * Primary:Kerberos-Newer-Keys (optional)
2010          * Primary:Kerberos
2011          * Primary:WDigest
2012          * Primary:CLEARTEXT (optional)
2013          * Primary:userPassword
2014          * Primary:SambaGPG (optional)
2015          *
2016          * And the 'Packages' package is insert before the last
2017          * other package.
2018          *
2019          * Note: it's important that Primary:SambaGPG is added as
2020          * the last element. This is the indication that it matches
2021          * the current password. When a password change happens on
2022          * a Windows DC, it will keep the old Primary:SambaGPG value,
2023          * but as the first element.
2024          */
2025         do_newer_keys = (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008);
2026         if (do_newer_keys) {
2027                 struct package_PrimaryKerberosBlob pknb;
2028                 DATA_BLOB pknb_blob;
2029                 char *pknb_hexstr;
2030                 /*
2031                  * setup 'Primary:Kerberos-Newer-Keys' element
2032                  */
2033                 names[num_names++] = "Kerberos-Newer-Keys";
2034
2035                 ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
2036                 if (ret != LDB_SUCCESS) {
2037                         return ret;
2038                 }
2039
2040                 ndr_err = ndr_push_struct_blob(
2041                         &pknb_blob, io->ac,
2042                         &pknb,
2043                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
2044                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2045                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2046                         ldb_asprintf_errstring(
2047                                 ldb,
2048                                 "setup_supplemental_field: "
2049                                 "failed to push "
2050                                 "package_PrimaryKerberosNeverBlob: %s",
2051                                 nt_errstr(status));
2052                         return LDB_ERR_OPERATIONS_ERROR;
2053                 }
2054                 pknb_hexstr = data_blob_hex_string_upper(io->ac, &pknb_blob);
2055                 if (!pknb_hexstr) {
2056                         return ldb_oom(ldb);
2057                 }
2058                 pp->name        = "Primary:Kerberos-Newer-Keys";
2059                 pp->reserved    = 1;
2060                 pp->data        = pknb_hexstr;
2061                 pp++;
2062                 num_packages++;
2063         }
2064
2065         {
2066                 /*
2067                  * setup 'Primary:Kerberos' element
2068                  */
2069                 /* Primary:Kerberos */
2070                 struct package_PrimaryKerberosBlob pkb;
2071                 DATA_BLOB pkb_blob;
2072                 char *pkb_hexstr;
2073
2074                 names[num_names++] = "Kerberos";
2075
2076                 ret = setup_primary_kerberos(io, old_scb, &pkb);
2077                 if (ret != LDB_SUCCESS) {
2078                         return ret;
2079                 }
2080
2081                 ndr_err = ndr_push_struct_blob(
2082                         &pkb_blob, io->ac,
2083                         &pkb,
2084                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
2085                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2086                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2087                         ldb_asprintf_errstring(
2088                                 ldb,
2089                                 "setup_supplemental_field: "
2090                                 "failed to push package_PrimaryKerberosBlob: %s",
2091                                 nt_errstr(status));
2092                         return LDB_ERR_OPERATIONS_ERROR;
2093                 }
2094                 pkb_hexstr = data_blob_hex_string_upper(io->ac, &pkb_blob);
2095                 if (!pkb_hexstr) {
2096                         return ldb_oom(ldb);
2097                 }
2098                 pp->name        = "Primary:Kerberos";
2099                 pp->reserved    = 1;
2100                 pp->data        = pkb_hexstr;
2101                 pp++;
2102                 num_packages++;
2103         }
2104
2105         if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_ALLOWED) {
2106                 /*
2107                  * setup 'Primary:WDigest' element
2108                  */
2109                 struct package_PrimaryWDigestBlob pdb;
2110                 DATA_BLOB pdb_blob;
2111                 char *pdb_hexstr;
2112
2113                 names[num_names++] = "WDigest";
2114
2115                 ret = setup_primary_wdigest(io, old_scb, &pdb);
2116                 if (ret != LDB_SUCCESS) {
2117                         return ret;
2118                 }
2119
2120                 ndr_err = ndr_push_struct_blob(
2121                         &pdb_blob, io->ac,
2122                         &pdb,
2123                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryWDigestBlob);
2124                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2125                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2126                         ldb_asprintf_errstring(
2127                                 ldb,
2128                                 "setup_supplemental_field: "
2129                                 "failed to push package_PrimaryWDigestBlob: %s",
2130                                 nt_errstr(status));
2131                         return LDB_ERR_OPERATIONS_ERROR;
2132                 }
2133                 pdb_hexstr = data_blob_hex_string_upper(io->ac, &pdb_blob);
2134                 if (!pdb_hexstr) {
2135                         return ldb_oom(ldb);
2136                 }
2137                 pp->name        = "Primary:WDigest";
2138                 pp->reserved    = 1;
2139                 pp->data        = pdb_hexstr;
2140                 pp++;
2141                 num_packages++;
2142         }
2143
2144         /*
2145          * setup 'Primary:CLEARTEXT' element
2146          */
2147         if (io->ac->status->domain_data.store_cleartext &&
2148             (io->u.userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
2149                 do_cleartext = true;
2150         }
2151         if (do_cleartext) {
2152                 struct package_PrimaryCLEARTEXTBlob pcb;
2153                 DATA_BLOB pcb_blob;
2154                 char *pcb_hexstr;
2155
2156                 names[num_names++] = "CLEARTEXT";
2157
2158                 pcb.cleartext   = *io->n.cleartext_utf16;
2159
2160                 ndr_err = ndr_push_struct_blob(
2161                         &pcb_blob, io->ac,
2162                         &pcb,
2163                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryCLEARTEXTBlob);
2164                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2165                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2166                         ldb_asprintf_errstring(
2167                                 ldb,
2168                                 "setup_supplemental_field: "
2169                                 "failed to push package_PrimaryCLEARTEXTBlob: %s",
2170                                 nt_errstr(status));
2171                         return LDB_ERR_OPERATIONS_ERROR;
2172                 }
2173                 pcb_hexstr = data_blob_hex_string_upper(io->ac, &pcb_blob);
2174                 if (!pcb_hexstr) {
2175                         return ldb_oom(ldb);
2176                 }
2177                 pp->name        = "Primary:CLEARTEXT";
2178                 pp->reserved    = 1;
2179                 pp->data        = pcb_hexstr;
2180                 pp++;
2181                 num_packages++;
2182         }
2183
2184         /*
2185          * Don't generate crypt() or similar password for the krbtgt account.
2186          * It's unnecessary, and the length of the cleartext in UTF-8 form
2187          * exceeds the maximum (CRYPT_MAX_PASSPHRASE_SIZE) allowed by crypt().
2188          */
2189         if (io->ac->userPassword_schemes && !io->u.is_krbtgt) {
2190                 /*
2191                  * setup 'Primary:userPassword' element
2192                  */
2193                 struct package_PrimaryUserPasswordBlob
2194                         p_userPassword_b;
2195                 DATA_BLOB p_userPassword_b_blob;
2196                 char *p_userPassword_b_hexstr;
2197
2198                 names[num_names++] = "userPassword";
2199
2200                 ret = setup_primary_userPassword(io,
2201                                                  old_scb,
2202                                                  &p_userPassword_b);
2203                 if (ret != LDB_SUCCESS) {
2204                         return ret;
2205                 }
2206
2207                 ndr_err = ndr_push_struct_blob(
2208                         &p_userPassword_b_blob,
2209                         io->ac,
2210                         &p_userPassword_b,
2211                         (ndr_push_flags_fn_t)
2212                         ndr_push_package_PrimaryUserPasswordBlob);
2213                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2214                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2215                         ldb_asprintf_errstring(
2216                                 ldb,
2217                                 "setup_supplemental_field: failed to push "
2218                                 "package_PrimaryUserPasswordBlob: %s",
2219                                 nt_errstr(status));
2220                         return LDB_ERR_OPERATIONS_ERROR;
2221                 }
2222                 p_userPassword_b_hexstr
2223                         = data_blob_hex_string_upper(
2224                                 io->ac,
2225                                 &p_userPassword_b_blob);
2226                 if (!p_userPassword_b_hexstr) {
2227                         return ldb_oom(ldb);
2228                 }
2229                 pp->name     = "Primary:userPassword";
2230                 pp->reserved = 1;
2231                 pp->data     = p_userPassword_b_hexstr;
2232                 pp++;
2233                 num_packages++;
2234         }
2235
2236         /*
2237          * setup 'Primary:SambaGPG' element
2238          */
2239         if (io->ac->gpg_key_ids != NULL) {
2240                 do_samba_gpg = true;
2241         }
2242         if (do_samba_gpg) {
2243                 struct package_PrimarySambaGPGBlob pgb;
2244                 DATA_BLOB pgb_blob;
2245                 char *pgb_hexstr;
2246
2247                 names[num_names++] = "SambaGPG";
2248
2249                 ret = setup_primary_samba_gpg(io, &pgb);
2250                 if (ret != LDB_SUCCESS) {
2251                         return ret;
2252                 }
2253
2254                 ndr_err = ndr_push_struct_blob(&pgb_blob, io->ac, &pgb,
2255                         (ndr_push_flags_fn_t)ndr_push_package_PrimarySambaGPGBlob);
2256                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2257                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2258                         ldb_asprintf_errstring(ldb,
2259                                         "setup_supplemental_field: failed to "
2260                                         "push package_PrimarySambaGPGBlob: %s",
2261                                         nt_errstr(status));
2262                         return LDB_ERR_OPERATIONS_ERROR;
2263                 }
2264                 pgb_hexstr = data_blob_hex_string_upper(io->ac, &pgb_blob);
2265                 if (!pgb_hexstr) {
2266                         return ldb_oom(ldb);
2267                 }
2268                 pp->name        = "Primary:SambaGPG";
2269                 pp->reserved    = 1;
2270                 pp->data        = pgb_hexstr;
2271                 pp++;
2272                 num_packages++;
2273         }
2274
2275         /*
2276          * setup 'Packages' element
2277          */
2278         {
2279                 struct package_PackagesBlob pb;
2280                 DATA_BLOB pb_blob;
2281                 char *pb_hexstr;
2282
2283                 pb.names = names;
2284                 ndr_err = ndr_push_struct_blob(
2285                         &pb_blob, io->ac,
2286                         &pb,
2287                         (ndr_push_flags_fn_t)ndr_push_package_PackagesBlob);
2288                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2289                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2290                         ldb_asprintf_errstring(
2291                                 ldb,
2292                                 "setup_supplemental_field: "
2293                                 "failed to push package_PackagesBlob: %s",
2294                                 nt_errstr(status));
2295                         return LDB_ERR_OPERATIONS_ERROR;
2296                 }
2297                 pb_hexstr = data_blob_hex_string_upper(io->ac, &pb_blob);
2298                 if (!pb_hexstr) {
2299                         return ldb_oom(ldb);
2300                 }
2301                 pp->name        = "Packages";
2302                 pp->reserved    = 2;
2303                 pp->data        = pb_hexstr;
2304                 num_packages++;
2305                 /*
2306                  * We don't increment pp so it's pointing to the last package
2307                  */
2308         }
2309
2310         /*
2311          * setup 'supplementalCredentials' value
2312          */
2313         {
2314                 /*
2315                  * The 'Packages' element needs to be the second last element
2316                  * in supplementalCredentials
2317                  */
2318                 struct supplementalCredentialsPackage temp;
2319                 struct supplementalCredentialsPackage *prev;
2320
2321                 prev = pp-1;
2322                 temp = *prev;
2323                 *prev = *pp;
2324                 *pp = temp;
2325
2326                 scb.sub.signature       = SUPPLEMENTAL_CREDENTIALS_SIGNATURE;
2327                 scb.sub.num_packages    = num_packages;
2328                 scb.sub.packages        = packages;
2329
2330                 ndr_err = ndr_push_struct_blob(
2331                         &io->g.supplemental, io->ac,
2332                         &scb,
2333                         (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2334                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2335                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2336                         ldb_asprintf_errstring(
2337                                 ldb,
2338                                 "setup_supplemental_field: "
2339                                 "failed to push supplementalCredentialsBlob: %s",
2340                                 nt_errstr(status));
2341                         return LDB_ERR_OPERATIONS_ERROR;
2342                 }
2343         }
2344
2345         return LDB_SUCCESS;
2346 }
2347
2348 static int setup_last_set_field(struct setup_password_fields_io *io)
2349 {
2350         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2351         const struct ldb_message *msg = NULL;
2352         struct timeval tv = { .tv_sec = 0 };
2353         const struct ldb_val *old_val = NULL;
2354         const struct ldb_val *new_val = NULL;
2355         int ret;
2356
2357         switch (io->ac->req->operation) {
2358         case LDB_ADD:
2359                 msg = io->ac->req->op.add.message;
2360                 break;
2361         case LDB_MODIFY:
2362                 msg = io->ac->req->op.mod.message;
2363                 break;
2364         default:
2365                 return LDB_ERR_OPERATIONS_ERROR;
2366                 break;
2367         }
2368
2369         if (io->ac->pwd_last_set_bypass) {
2370                 struct ldb_message_element *el = NULL;
2371                 size_t i;
2372                 size_t count = 0;
2373                 /*
2374                  * This is a message from pdb_samba_dsdb_replace_by_sam()
2375                  *
2376                  * We want to ensure there is only one pwdLastSet element, and
2377                  * it isn't deleting.
2378                  */
2379                 if (msg == NULL) {
2380                         return LDB_ERR_CONSTRAINT_VIOLATION;
2381                 }
2382
2383                 for (i = 0; i < msg->num_elements; i++) {
2384                         if (ldb_attr_cmp(msg->elements[i].name,
2385                                          "pwdLastSet") == 0) {
2386                                 count++;
2387                                 el = &msg->elements[i];
2388                         }
2389                 }
2390                 if (count != 1) {
2391                         return LDB_ERR_CONSTRAINT_VIOLATION;
2392                 }
2393
2394                 if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
2395                         return LDB_ERR_CONSTRAINT_VIOLATION;
2396                 }
2397
2398                 io->g.last_set = samdb_result_nttime(msg, "pwdLastSet", 0);
2399                 return LDB_SUCCESS;
2400         }
2401
2402         ret = msg_find_old_and_new_pwd_val(msg, "pwdLastSet",
2403                                            io->ac->req->operation,
2404                                            &new_val, &old_val);
2405         if (ret != LDB_SUCCESS) {
2406                 return ret;
2407         }
2408
2409         if (old_val != NULL && new_val == NULL) {
2410                 ldb_set_errstring(ldb,
2411                                   "'pwdLastSet' deletion is not allowed!");
2412                 return LDB_ERR_UNWILLING_TO_PERFORM;
2413         }
2414
2415         io->g.last_set = UINT64_MAX;
2416         if (new_val != NULL) {
2417                 struct ldb_message *tmp_msg = NULL;
2418
2419                 tmp_msg = ldb_msg_new(io->ac);
2420                 if (tmp_msg == NULL) {
2421                         return ldb_module_oom(io->ac->module);
2422                 }
2423
2424                 if (old_val != NULL) {
2425                         NTTIME old_last_set = 0;
2426
2427                         ret = ldb_msg_add_value(tmp_msg, "oldval",
2428                                                 old_val, NULL);
2429                         if (ret != LDB_SUCCESS) {
2430                                 return ret;
2431                         }
2432
2433                         old_last_set = samdb_result_nttime(tmp_msg,
2434                                                            "oldval",
2435                                                            1);
2436                         if (io->u.pwdLastSet != old_last_set) {
2437                                 return dsdb_module_werror(io->ac->module,
2438                                         LDB_ERR_NO_SUCH_ATTRIBUTE,
2439                                         WERR_DS_CANT_REM_MISSING_ATT_VAL,
2440                                         "setup_last_set_field: old pwdLastSet "
2441                                         "value not found!");
2442                         }
2443                 }
2444
2445                 ret = ldb_msg_add_value(tmp_msg, "newval",
2446                                         new_val, NULL);
2447                 if (ret != LDB_SUCCESS) {
2448                         return ret;
2449                 }
2450
2451                 io->g.last_set = samdb_result_nttime(tmp_msg,
2452                                                      "newval",
2453                                                      1);
2454         } else if (ldb_msg_find_element(msg, "pwdLastSet")) {
2455                 ldb_set_errstring(ldb,
2456                                   "'pwdLastSet' deletion is not allowed!");
2457                 return LDB_ERR_UNWILLING_TO_PERFORM;
2458         } else if (io->ac->smartcard_reset) {
2459                 /*
2460                  * adding UF_SMARTCARD_REQUIRED doesn't update
2461                  * pwdLastSet implicitly.
2462                  */
2463                 io->ac->update_lastset = false;
2464         }
2465
2466         /* only 0 or -1 (0xFFFFFFFFFFFFFFFF) are allowed */
2467         switch (io->g.last_set) {
2468         case 0:
2469                 if (!io->ac->pwd_last_set_default) {
2470                         break;
2471                 }
2472                 if (!io->ac->update_password) {
2473                         break;
2474                 }
2475                 FALL_THROUGH;
2476         case UINT64_MAX:
2477                 if (!io->ac->update_password &&
2478                     io->u.pwdLastSet != 0 &&
2479                     io->u.pwdLastSet != UINT64_MAX)
2480                 {
2481                         /*
2482                          * Just setting pwdLastSet to -1, while not changing
2483                          * any password field has no effect if pwdLastSet
2484                          * is already non-zero.
2485                          */
2486                         io->ac->update_lastset = false;
2487                         break;
2488                 }
2489                 /* -1 means set it as now */
2490                 GetTimeOfDay(&tv);
2491                 io->g.last_set = timeval_to_nttime(&tv);
2492                 break;
2493         default:
2494                 return dsdb_module_werror(io->ac->module,
2495                                           LDB_ERR_OTHER,
2496                                           WERR_INVALID_PARAMETER,
2497                                           "setup_last_set_field: "
2498                                           "pwdLastSet must be 0 or -1 only!");
2499         }
2500
2501         if (io->ac->req->operation == LDB_ADD) {
2502                 /*
2503                  * We always need to store the value on add
2504                  * operations.
2505                  */
2506                 return LDB_SUCCESS;
2507         }
2508
2509         if (io->g.last_set == io->u.pwdLastSet) {
2510                 /*
2511                  * Just setting pwdLastSet to 0, is no-op if it's already 0.
2512                  */
2513                 io->ac->update_lastset = false;
2514         }
2515
2516         return LDB_SUCCESS;
2517 }
2518
2519 static int setup_given_passwords(struct setup_password_fields_io *io,
2520                                  struct setup_password_fields_given *g)
2521 {
2522         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2523
2524         if (g->cleartext_utf8) {
2525                 struct ldb_val *cleartext_utf16_blob;
2526
2527                 cleartext_utf16_blob = talloc(io->ac, struct ldb_val);
2528                 if (!cleartext_utf16_blob) {
2529                         return ldb_oom(ldb);
2530                 }
2531                 if (!convert_string_talloc(io->ac,
2532                                            CH_UTF8, CH_UTF16,
2533                                            g->cleartext_utf8->data,
2534                                            g->cleartext_utf8->length,
2535                                            &cleartext_utf16_blob->data,
2536                                            &cleartext_utf16_blob->length)) {
2537                         if (g->cleartext_utf8->length != 0) {
2538                                 talloc_free(cleartext_utf16_blob);
2539                                 ldb_asprintf_errstring(ldb,
2540                                                        "setup_password_fields: "
2541                                                        "failed to generate UTF16 password from cleartext UTF8 one for user '%s'!",
2542                                                        io->u.sAMAccountName);
2543                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2544                         } else {
2545                                 /* passwords with length "0" are valid! */
2546                                 cleartext_utf16_blob->data = NULL;
2547                                 cleartext_utf16_blob->length = 0;
2548                         }
2549                 }
2550                 g->cleartext_utf16 = cleartext_utf16_blob;
2551         } else if (g->cleartext_utf16) {
2552                 struct ldb_val *cleartext_utf8_blob;
2553
2554                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
2555                 if (!cleartext_utf8_blob) {
2556                         return ldb_oom(ldb);
2557                 }
2558                 if (!convert_string_talloc(io->ac,
2559                                            CH_UTF16MUNGED, CH_UTF8,
2560                                            g->cleartext_utf16->data,
2561                                            g->cleartext_utf16->length,
2562                                            &cleartext_utf8_blob->data,
2563                                            &cleartext_utf8_blob->length)) {
2564                         if (g->cleartext_utf16->length != 0) {
2565                                 /* We must bail out here, the input wasn't even
2566                                  * a multiple of 2 bytes */
2567                                 talloc_free(cleartext_utf8_blob);
2568                                 ldb_asprintf_errstring(ldb,
2569                                                        "setup_password_fields: "
2570                                                        "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)!",
2571                                                        io->u.sAMAccountName);
2572                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2573                         } else {
2574                                 /* passwords with length "0" are valid! */
2575                                 cleartext_utf8_blob->data = NULL;
2576                                 cleartext_utf8_blob->length = 0;
2577                         }
2578                 }
2579                 g->cleartext_utf8 = cleartext_utf8_blob;
2580         }
2581
2582         if (g->cleartext_utf16) {
2583                 struct samr_Password *nt_hash;
2584
2585                 nt_hash = talloc(io->ac, struct samr_Password);
2586                 if (!nt_hash) {
2587                         return ldb_oom(ldb);
2588                 }
2589                 g->nt_hash = nt_hash;
2590
2591                 /* compute the new nt hash */
2592                 mdfour(nt_hash->hash,
2593                        g->cleartext_utf16->data,
2594                        g->cleartext_utf16->length);
2595         }
2596
2597         /*
2598          * We need to build one more hash, so we can compare with what might
2599          * have been stored in the old password (for the LDAP password change)
2600          *
2601          * We don't have any old salts, so we won't catch password reuse if said
2602          * password was used prior to an account rename and another password
2603          * change.
2604          *
2605          * We don't have to store the 'opaque' (string2key iterations)
2606          * as Heimdal doesn't allow that to be changed.
2607          */
2608         if (g->cleartext_utf8 != NULL) {
2609                 int ret = setup_kerberos_key_hash(io, g);
2610                 if (ret != LDB_SUCCESS) {
2611                         return ret;
2612                 }
2613         }
2614
2615         return LDB_SUCCESS;
2616 }
2617
2618 static int setup_password_fields(struct setup_password_fields_io *io)
2619 {
2620         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2621         int ret;
2622
2623         ret = setup_last_set_field(io);
2624         if (ret != LDB_SUCCESS) {
2625                 return ret;
2626         }
2627
2628         if (!io->ac->update_password) {
2629                 return LDB_SUCCESS;
2630         }
2631
2632         if (io->u.is_krbtgt) {
2633                 size_t min = 196;
2634                 size_t max = 255;
2635                 size_t diff = max - min;
2636                 size_t len = max;
2637                 struct ldb_val *krbtgt_utf16 = NULL;
2638
2639                 if (!io->ac->pwd_reset) {
2640                         return dsdb_module_werror(io->ac->module,
2641                                         LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
2642                                         WERR_DS_ATT_ALREADY_EXISTS,
2643                                         "Password change on krbtgt not permitted!");
2644                 }
2645
2646                 if (io->n.cleartext_utf16 == NULL) {
2647                         return dsdb_module_werror(io->ac->module,
2648                                         LDB_ERR_UNWILLING_TO_PERFORM,
2649                                         WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
2650                                         "Password reset on krbtgt requires UTF16!");
2651                 }
2652
2653                 /*
2654                  * Instead of taking the callers value,
2655                  * we just generate a new random value here.
2656                  *
2657                  * Include null termination in the array.
2658                  */
2659                 if (diff > 0) {
2660                         size_t tmp;
2661
2662                         generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
2663
2664                         tmp %= diff;
2665
2666                         len = min + tmp;
2667                 }
2668
2669                 krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
2670                 if (krbtgt_utf16 == NULL) {
2671                         return ldb_oom(ldb);
2672                 }
2673
2674                 *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
2675                                                       (len+1)*2);
2676                 if (krbtgt_utf16->data == NULL) {
2677                         return ldb_oom(ldb);
2678                 }
2679                 krbtgt_utf16->length = len * 2;
2680                 generate_secret_buffer(krbtgt_utf16->data,
2681                                        krbtgt_utf16->length);
2682                 io->n.cleartext_utf16 = krbtgt_utf16;
2683         }
2684
2685         /* transform the old password (for password changes) */
2686         ret = setup_given_passwords(io, &io->og);
2687         if (ret != LDB_SUCCESS) {
2688                 return ret;
2689         }
2690
2691         /* transform the new password */
2692         ret = setup_given_passwords(io, &io->n);
2693         if (ret != LDB_SUCCESS) {
2694                 return ret;
2695         }
2696
2697         if (io->n.cleartext_utf8) {
2698                 ret = setup_kerberos_keys(io);
2699                 if (ret != LDB_SUCCESS) {
2700                         return ret;
2701                 }
2702         }
2703
2704         /*
2705          * This relies on setup_kerberos_keys to make a NT-hash-like
2706          * value for password history purposes
2707          */
2708
2709         ret = setup_nt_fields(io);
2710         if (ret != LDB_SUCCESS) {
2711                 return ret;
2712         }
2713
2714         ret = setup_supplemental_field(io);
2715         if (ret != LDB_SUCCESS) {
2716                 return ret;
2717         }
2718
2719         return LDB_SUCCESS;
2720 }
2721
2722 static int setup_smartcard_reset(struct setup_password_fields_io *io)
2723 {
2724         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2725         struct supplementalCredentialsBlob scb = { .__ndr_size = 0 };
2726         enum ndr_err_code ndr_err;
2727
2728         if (!io->ac->smartcard_reset) {
2729                 return LDB_SUCCESS;
2730         }
2731
2732         io->g.nt_hash = talloc(io->ac, struct samr_Password);
2733         if (io->g.nt_hash == NULL) {
2734                 return ldb_module_oom(io->ac->module);
2735         }
2736         generate_secret_buffer(io->g.nt_hash->hash,
2737                                sizeof(io->g.nt_hash->hash));
2738         io->g.nt_history_len = 0;
2739
2740         /*
2741          * We take the "old" value and store it
2742          * with num_packages = 0.
2743          *
2744          * On "add" we have scb.sub.signature == 0, which
2745          * results in:
2746          *
2747          * [0000] 00 00 00 00 00 00 00 00   00 00 00 00 00
2748          *
2749          * On modify it's likely to be scb.sub.signature ==
2750          * SUPPLEMENTAL_CREDENTIALS_SIGNATURE (0x0050), which results in
2751          * something like:
2752          *
2753          * [0000] 00 00 00 00 62 00 00 00   00 00 00 00 20 00 20 00
2754          * [0010] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2755          * [0020] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2756          * [0030] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2757          * [0040] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2758          * [0050] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2759          * [0060] 20 00 20 00 20 00 20 00   20 00 20 00 50 00 00
2760          *
2761          * See https://bugzilla.samba.org/show_bug.cgi?id=11441
2762          * and ndr_{push,pull}_supplementalCredentialsSubBlob().
2763          */
2764         scb = io->o.scb;
2765         scb.sub.num_packages = 0;
2766
2767         /*
2768          * setup 'supplementalCredentials' value without packages
2769          */
2770         ndr_err = ndr_push_struct_blob(&io->g.supplemental, io->ac,
2771                                        &scb,
2772                                        (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2773         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2774                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2775                 ldb_asprintf_errstring(ldb,
2776                                        "setup_smartcard_reset: "
2777                                        "failed to push supplementalCredentialsBlob: %s",
2778                                        nt_errstr(status));
2779                 return LDB_ERR_OPERATIONS_ERROR;
2780         }
2781
2782         io->ac->update_password = true;
2783         return LDB_SUCCESS;
2784 }
2785
2786 static int make_error_and_update_badPwdCount(struct setup_password_fields_io *io, WERROR *werror)
2787 {
2788         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2789         struct ldb_message *mod_msg = NULL;
2790         struct ldb_message *pso_msg = NULL;
2791         struct ldb_message *current = NULL;
2792         NTSTATUS status = NT_STATUS_OK;
2793         int ret; /* The errors we will actually return */
2794         int dbg_ret; /* The errors we can only complain about in logs */
2795
2796         /*
2797          * OK, horrible semantics ahead.
2798          *
2799          * - We need to abort any existing transaction
2800          * - create a transaction around the badPwdCount update
2801          * - re-open the transaction so the upper layer
2802          *   doesn't know what happened.
2803          *
2804          * This is needed because returning an error to the upper
2805          * layer will cancel the transaction and undo the badPwdCount
2806          * update.
2807          */
2808
2809         /*
2810          * Checking errors here is a bit pointless.
2811          * What can we do if we can't end the transaction?
2812          */
2813         dbg_ret = ldb_next_del_trans(io->ac->module);
2814         if (dbg_ret != LDB_SUCCESS) {
2815                 ldb_debug(ldb, LDB_DEBUG_FATAL,
2816                           "Failed to abort transaction prior to update of badPwdCount of %s: %s",
2817                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2818                           ldb_errstring(ldb));
2819                 /*
2820                  * just return the original error
2821                  */
2822                 goto done;
2823         }
2824
2825         /* Likewise, what should we do if we can't open a new transaction? */
2826         dbg_ret = ldb_next_start_trans(io->ac->module);
2827         if (dbg_ret != LDB_SUCCESS) {
2828                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2829                           "Failed to open transaction to update badPwdCount of %s: %s",
2830                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2831                           ldb_errstring(ldb));
2832                 /*
2833                  * just return the original error
2834                  */
2835                 goto done;
2836         }
2837
2838         /*
2839          * Re-read the account details, using the GUID in case the DN
2840          * is being changed.
2841          */
2842         status = authsam_reread_user_logon_data(
2843                 ldb, io->ac,
2844                 io->ac->search_res->message,
2845                 &current);
2846         if (!NT_STATUS_IS_OK(status)) {
2847                 /* The re-read can return account locked out, as well
2848                  * as an internal error
2849                  */
2850                 goto end_transaction;
2851         }
2852
2853         /* PSO search result is optional (NULL if no PSO applies) */
2854         if (io->ac->pso_res != NULL) {
2855                 pso_msg = io->ac->pso_res->message;
2856         }
2857
2858         status = dsdb_update_bad_pwd_count(io->ac, ldb,
2859                                            current,
2860                                            io->ac->dom_res->message,
2861                                            pso_msg,
2862                                            &mod_msg);
2863         if (!NT_STATUS_IS_OK(status)) {
2864                 goto end_transaction;
2865         }
2866
2867         if (mod_msg == NULL) {
2868                 goto end_transaction;
2869         }
2870
2871         dbg_ret = dsdb_module_modify(io->ac->module, mod_msg,
2872                                  DSDB_FLAG_NEXT_MODULE,
2873                                  io->ac->req);
2874         if (dbg_ret != LDB_SUCCESS) {
2875                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2876                           "Failed to update badPwdCount of %s: %s",
2877                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2878                           ldb_errstring(ldb));
2879                 /*
2880                  * We can only ignore this...
2881                  */
2882         }
2883
2884 end_transaction:
2885         dbg_ret = ldb_next_end_trans(io->ac->module);
2886         if (dbg_ret != LDB_SUCCESS) {
2887                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2888                           "Failed to close transaction to update badPwdCount of %s: %s",
2889                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2890                           ldb_errstring(ldb));
2891                 /*
2892                  * We can only ignore this...
2893                  */
2894         }
2895
2896         dbg_ret = ldb_next_start_trans(io->ac->module);
2897         if (dbg_ret != LDB_SUCCESS) {
2898                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2899                           "Failed to open transaction after update of badPwdCount of %s: %s",
2900                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2901                           ldb_errstring(ldb));
2902                 /*
2903                  * We can only ignore this...
2904                  */
2905         }
2906
2907 done:
2908         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2909         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_LOCKED_OUT)) {
2910                 *werror = WERR_ACCOUNT_LOCKED_OUT;
2911         } else {
2912                 *werror = WERR_INVALID_PASSWORD;
2913         }
2914         ldb_asprintf_errstring(ldb,
2915                                "%08X: %s - check_password_restrictions: "
2916                                "The old password specified doesn't match!",
2917                                W_ERROR_V(*werror),
2918                                ldb_strerror(ret));
2919         return ret;
2920 }
2921
2922 static int check_password_restrictions(struct setup_password_fields_io *io, WERROR *werror)
2923 {
2924         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2925         int ret;
2926         uint32_t i;
2927         struct loadparm_context *lp_ctx =
2928                 talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
2929                                 struct loadparm_context);
2930         struct dsdb_encrypted_connection_state *opaque_connection_state =
2931                 ldb_get_opaque(ldb,DSDB_OPAQUE_ENCRYPTED_CONNECTION_STATE_NAME);
2932
2933         *werror = WERR_INVALID_PARAMETER;
2934
2935         if (!io->ac->update_password) {
2936                 return LDB_SUCCESS;
2937         }
2938
2939         /*
2940          * Prevent update password on an insecure connection.
2941          * The opaque is added in the ldap backend init.
2942          */
2943         if (opaque_connection_state != NULL &&
2944             !opaque_connection_state->using_encrypted_connection) {
2945                 ret = LDB_ERR_UNWILLING_TO_PERFORM;
2946                 *werror = WERR_GEN_FAILURE;
2947                 ldb_asprintf_errstring(ldb,
2948                                        "%08X: SvcErr: DSID-031A126C, "
2949                                        "problem 5003 (WILL_NOT_PERFORM), "
2950                                        "data 0\n"
2951                                        "Password modification over LDAP "
2952                                        "must be over an encrypted connection",
2953                                        W_ERROR_V(*werror));
2954                 return ret;
2955         }
2956
2957         /*
2958          * First check the old password is correct, for password
2959          * changes when this hasn't already been checked by a
2960          * trustworthy layer above
2961          */
2962         if (!io->ac->pwd_reset && !(io->ac->change
2963                                     && io->ac->change->old_password_checked == DSDB_PASSWORD_CHECKED_AND_CORRECT)) {
2964                 bool hash_checked = false;
2965                 /*
2966                  * we need the old nt hash given by the client (this
2967                  * is for the plaintext over LDAP password change,
2968                  * Kpasswd and SAMR supply the control)
2969                  */
2970                 if (io->og.nt_hash == NULL && io->og.aes_256.length == 0) {
2971                         ldb_asprintf_errstring(ldb,
2972                                 "check_password_restrictions: "
2973                                 "You need to provide the old password in order "
2974                                 "to change it!");
2975                         return LDB_ERR_UNWILLING_TO_PERFORM;
2976                 }
2977
2978                 /*
2979                  * First compare the ENCTYPE_AES256_CTS_HMAC_SHA1_96 password and see if we have a match
2980                  */
2981
2982                 if (io->og.aes_256.length > 0 && io->o.aes_256.length) {
2983                         hash_checked = data_blob_equal_const_time(&io->og.aes_256, &io->o.aes_256);
2984                 }
2985
2986                 /* The password modify through the NT hash is encouraged and
2987                    has no problems at all */
2988                 if (!hash_checked && io->og.nt_hash && io->o.nt_hash) {
2989                         hash_checked = mem_equal_const_time(io->og.nt_hash->hash, io->o.nt_hash->hash, 16);
2990                 }
2991
2992                 if (!hash_checked) {
2993                         return make_error_and_update_badPwdCount(io, werror);
2994                 }
2995         }
2996
2997         if (io->u.restrictions == 0) {
2998                 /* FIXME: Is this right? */
2999                 return LDB_SUCCESS;
3000         }
3001
3002         /* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */
3003         if ((io->u.pwdLastSet - io->ac->status->domain_data.minPwdAge > io->g.last_set) &&
3004             !io->ac->pwd_reset)
3005         {
3006                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3007                 *werror = WERR_PASSWORD_RESTRICTION;
3008                 ldb_asprintf_errstring(ldb,
3009                         "%08X: %s - check_password_restrictions: "
3010                         "password is too young to change!",
3011                         W_ERROR_V(*werror),
3012                         ldb_strerror(ret));
3013                 return ret;
3014         }
3015
3016         /*
3017          * Fundamental password checks done by the call
3018          * "samdb_check_password".
3019          * It is also in use by "dcesrv_samr_ValidatePassword".
3020          */
3021         if (io->n.cleartext_utf8 != NULL) {
3022                 enum samr_ValidationStatus vstat;
3023                 vstat = samdb_check_password(io->ac, lp_ctx,
3024                                              io->u.sAMAccountName,
3025                                              io->u.user_principal_name,
3026                                              io->u.displayName,
3027                                              io->n.cleartext_utf8,
3028                                              io->ac->status->domain_data.pwdProperties,
3029                                              io->ac->status->domain_data.minPwdLength);
3030                 switch (vstat) {
3031                 case SAMR_VALIDATION_STATUS_SUCCESS:
3032                                 /* perfect -> proceed! */
3033                         break;
3034
3035                 case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT:
3036                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3037                         *werror = WERR_PASSWORD_RESTRICTION;
3038                         ldb_asprintf_errstring(ldb,
3039                                 "%08X: %s - check_password_restrictions: "
3040                                 "the password is too short. It should be equal to or longer than %u characters!",
3041                                 W_ERROR_V(*werror),
3042                                 ldb_strerror(ret),
3043                                 io->ac->status->domain_data.minPwdLength);
3044                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PASSWORD_TOO_SHORT;
3045                         return ret;
3046
3047                 case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH:
3048                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3049                         *werror = WERR_PASSWORD_RESTRICTION;
3050                         ldb_asprintf_errstring(ldb,
3051                                 "%08X: %s - check_password_restrictions: "
3052                                 "the password does not meet the complexity criteria!",
3053                                 W_ERROR_V(*werror),
3054                                 ldb_strerror(ret));
3055                         io->ac->status->reject_reason = SAM_PWD_CHANGE_NOT_COMPLEX;
3056                         return ret;
3057
3058                 default:
3059                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3060                         *werror = WERR_PASSWORD_RESTRICTION;
3061                         ldb_asprintf_errstring(ldb,
3062                                 "%08X: %s - check_password_restrictions: "
3063                                 "the password doesn't fit due to a miscellaneous restriction!",
3064                                 W_ERROR_V(*werror),
3065                                 ldb_strerror(ret));
3066                         return ret;
3067                 }
3068         }
3069
3070         if (io->ac->pwd_reset) {
3071                 *werror = WERR_OK;
3072                 return LDB_SUCCESS;
3073         }
3074
3075         /*
3076          * This check works by using the current Kerberos password to
3077          * make up a password history.  We already did the salted hash
3078          * creation to pass the password change check.
3079          *
3080          * We check the pwdHistoryLength to ensure we honour the
3081          * policy on if the history should be checked
3082          */
3083         if (io->ac->status->domain_data.pwdHistoryLength > 0
3084             && io->g.aes_256.length && io->o.aes_256.length)
3085         {
3086                 bool equal = data_blob_equal_const_time(&io->g.aes_256,
3087                                                         &io->o.aes_256);
3088                 if (equal) {
3089                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3090                         *werror = WERR_PASSWORD_RESTRICTION;
3091                         ldb_asprintf_errstring(ldb,
3092                                                "%08X: %s - check_password_restrictions: "
3093                                                "the password was already used (previous password)!",
3094                                                W_ERROR_V(*werror),
3095                                                ldb_strerror(ret));
3096                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3097                         return ret;
3098                 }
3099         }
3100
3101         if (io->n.nt_hash) {
3102                 /*
3103                  * checks the NT hash password history, against the
3104                  * generated NT hash
3105                  */
3106                 for (i = 0; i < io->o.nt_history_len; i++) {
3107                         bool pw_cmp = mem_equal_const_time(io->n.nt_hash, io->o.nt_history[i].hash, 16);
3108                         if (pw_cmp) {
3109                                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3110                                 *werror = WERR_PASSWORD_RESTRICTION;
3111                                 ldb_asprintf_errstring(ldb,
3112                                         "%08X: %s - check_password_restrictions: "
3113                                         "the password was already used (in history)!",
3114                                         W_ERROR_V(*werror),
3115                                         ldb_strerror(ret));
3116                                 io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3117                                 return ret;
3118                         }
3119                 }
3120         }
3121
3122         /*
3123          * This check works by using the old Kerberos passwords
3124          * (old and older) to make up a password history.
3125          *
3126          * We check the pwdHistoryLength to ensure we honour the
3127          * policy on if the history should be checked
3128          */
3129         for (i = 1;
3130              i <= io->o.kvno && i < MIN(3, io->ac->status->domain_data.pwdHistoryLength);
3131              i++)
3132         {
3133                 krb5_error_code krb5_ret;
3134                 const uint32_t request_kvno = io->o.kvno - i;
3135                 DATA_BLOB db_key_blob;
3136                 bool pw_equal;
3137
3138                 if (io->n.cleartext_utf8 == NULL) {
3139                         /*
3140                          * No point checking history if we don't have
3141                          * a cleartext password.
3142                          */
3143                         break;
3144                 }
3145
3146                 if (io->ac->search_res == NULL) {
3147                         /*
3148                          * This is an ADD, no existing history to check
3149                          */
3150                         break;
3151                 }
3152
3153                 /*
3154                  * If this account requires a smartcard for login, we don't
3155                  * attempt a comparison with the old password.
3156                  */
3157                 if (io->u.userAccountControl & UF_SMARTCARD_REQUIRED) {
3158                         break;
3159                 }
3160
3161                 /*
3162                  * Extract the old ENCTYPE_AES256_CTS_HMAC_SHA1_96 value from
3163                  * the supplementalCredentials.
3164                  */
3165                 krb5_ret = dsdb_extract_aes_256_key(io->smb_krb5_context->krb5_context,
3166                                                     io->ac,
3167                                                     ldb,
3168                                                     io->ac->search_res->message,
3169                                                     io->u.userAccountControl,
3170                                                     &request_kvno, /* kvno */
3171                                                     NULL, /* kvno_out */
3172                                                     &db_key_blob,
3173                                                     NULL); /* salt */
3174                 if (krb5_ret == ENOENT) {
3175                         /*
3176                          * If there is no old AES hash (perhaps an imported DB with
3177                          * just unicodePwd) then we just won't have an old
3178                          * password to compare to if there is no NT hash
3179                          */
3180                         break;
3181                 } else if (krb5_ret) {
3182                         ldb_asprintf_errstring(ldb,
3183                                                "check_password_restrictions: "
3184                                                "extraction of old[%u - %d = %d] aes256-cts-hmac-sha1-96 key failed: %s",
3185                                                io->o.kvno, i, io->o.kvno - i,
3186                                                smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
3187                                                                           krb5_ret, io->ac));
3188                         return LDB_ERR_OPERATIONS_ERROR;
3189                 }
3190
3191                 /* This is the actual history check */
3192                 pw_equal = data_blob_equal_const_time(&io->n.aes_256,
3193                                                       &db_key_blob);
3194                 if (pw_equal) {
3195                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3196                         *werror = WERR_PASSWORD_RESTRICTION;
3197                         ldb_asprintf_errstring(ldb,
3198                                                "%08X: %s - check_password_restrictions: "
3199                                                "the password was already used (in history)!",
3200                                                W_ERROR_V(*werror),
3201                                                ldb_strerror(ret));
3202                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3203                         return ret;
3204                 }
3205         }
3206
3207         /* are all password changes disallowed? */
3208         if (io->ac->status->domain_data.pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
3209                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3210                 *werror = WERR_PASSWORD_RESTRICTION;
3211                 ldb_asprintf_errstring(ldb,
3212                         "%08X: %s - check_password_restrictions: "
3213                         "password changes disabled!",
3214                         W_ERROR_V(*werror),
3215                         ldb_strerror(ret));
3216                 return ret;
3217         }
3218
3219         /* can this user change the password? */
3220         if (io->u.userAccountControl & UF_PASSWD_CANT_CHANGE) {
3221                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3222                 *werror = WERR_PASSWORD_RESTRICTION;
3223                 ldb_asprintf_errstring(ldb,
3224                         "%08X: %s - check_password_restrictions: "
3225                         "password can't be changed on this account!",
3226                         W_ERROR_V(*werror),
3227                         ldb_strerror(ret));
3228                 return ret;
3229         }
3230
3231         return LDB_SUCCESS;
3232 }
3233
3234 static int check_password_restrictions_and_log(struct setup_password_fields_io *io)
3235 {
3236         WERROR werror;
3237         int ret = check_password_restrictions(io, &werror);
3238         struct ph_context *ac = io->ac;
3239         /*
3240          * Password resets are not authentication events, and if the
3241          * upper layer checked the password and supplied the hash
3242          * values as proof, then this is also not an authentication
3243          * even at this layer (already logged).  This is to log LDAP
3244          * password changes.
3245          */
3246
3247         /* Do not record a failure in the auth log below in the success case */
3248         if (ret == LDB_SUCCESS) {
3249                 werror = WERR_OK;
3250         }
3251
3252         if (ac->pwd_reset == false && ac->change == NULL) {
3253                 struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3254                 struct imessaging_context *msg_ctx;
3255                 struct loadparm_context *lp_ctx
3256                         = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
3257                                                 struct loadparm_context);
3258                 NTSTATUS status = werror_to_ntstatus(werror);
3259                 const char *domain_name = lpcfg_sam_name(lp_ctx);
3260                 void *opaque_remote_address = NULL;
3261                 /*
3262                  * Forcing this via the NTLM auth structure is not ideal, but
3263                  * it is the most practical option right now, and ensures the
3264                  * logs are consistent, even if some elements are always NULL.
3265                  */
3266                 struct auth_usersupplied_info ui = {
3267                         .was_mapped = true,
3268                         .client = {
3269                                 .account_name = io->u.sAMAccountName,
3270                                 .domain_name = domain_name,
3271                         },
3272                         .mapped = {
3273                                 .account_name = io->u.sAMAccountName,
3274                                 .domain_name = domain_name,
3275                         },
3276                         .service_description = "LDAP Password Change",
3277                         .auth_description = "LDAP Modify",
3278                         .password_type = "plaintext"
3279                 };
3280
3281                 opaque_remote_address = ldb_get_opaque(ldb,
3282                                                        "remoteAddress");
3283                 if (opaque_remote_address == NULL) {
3284                         ldb_asprintf_errstring(ldb,
3285                                                "Failed to obtain remote address for "
3286                                                "the LDAP client while changing the "
3287                                                "password");
3288                         return LDB_ERR_OPERATIONS_ERROR;
3289                 }
3290                 ui.remote_host = talloc_get_type(opaque_remote_address,
3291                                                  struct tsocket_address);
3292
3293                 msg_ctx = imessaging_client_init(ac, lp_ctx,
3294                                                  ldb_get_event_context(ldb));
3295                 if (!msg_ctx) {
3296                         ldb_asprintf_errstring(ldb,
3297                                                "Failed to generate client messaging context in %s",
3298                                                lpcfg_imessaging_path(ac, lp_ctx));
3299                         return LDB_ERR_OPERATIONS_ERROR;
3300                 }
3301                 log_authentication_event(msg_ctx,
3302                                          lp_ctx,
3303                                          NULL,
3304                                          &ui,
3305                                          status,
3306                                          domain_name,
3307                                          io->u.sAMAccountName,
3308                                          io->u.account_sid,
3309                                          NULL /* client_audit_info */,
3310                                          NULL /* server_audit_info */);
3311
3312         }
3313         return ret;
3314 }
3315
3316 static int update_final_msg(struct setup_password_fields_io *io)
3317 {
3318         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
3319         int ret;
3320         int el_flags = 0;
3321         bool update_password = io->ac->update_password;
3322         bool update_scb = io->ac->update_password;
3323
3324         /*
3325          * If we add a user without initial password,
3326          * we need to add replication meta data for
3327          * following attributes:
3328          * - unicodePwd
3329          * - dBCSPwd
3330          * - ntPwdHistory
3331          * - lmPwdHistory
3332          *
3333          * If we add a user with initial password or a
3334          * password is changed of an existing user,
3335          * we need to replace the following attributes
3336          * with a forced meta data update, e.g. also
3337          * when updating an empty attribute with an empty value:
3338          * - unicodePwd
3339          * - dBCSPwd
3340          * - ntPwdHistory
3341          * - lmPwdHistory
3342          * - supplementalCredentials
3343          */
3344
3345         switch (io->ac->req->operation) {
3346         case LDB_ADD:
3347                 update_password = true;
3348                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
3349                 break;
3350         case LDB_MODIFY:
3351                 el_flags |= LDB_FLAG_MOD_REPLACE;
3352                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
3353                 break;
3354         default:
3355                 return ldb_module_operr(io->ac->module);
3356         }
3357
3358         if (update_password) {
3359                 ret = ldb_msg_add_empty(io->ac->update_msg,
3360                                         "unicodePwd",
3361                                         el_flags, NULL);
3362                 if (ret != LDB_SUCCESS) {
3363                         return ret;
3364                 }
3365
3366                 /*
3367                  * This wipes any old LM password after any password
3368                  * update operation.
3369                  *
3370                  * This is the same as the previous default behaviour
3371                  * of 'lanman auth = no'
3372                  */
3373                 ret = ldb_msg_add_empty(io->ac->update_msg,
3374                                         "dBCSPwd",
3375                                         el_flags, NULL);
3376                 if (ret != LDB_SUCCESS) {
3377                         return ret;
3378                 }
3379                 ret = ldb_msg_add_empty(io->ac->update_msg,
3380                                         "ntPwdHistory",
3381                                         el_flags, NULL);
3382                 if (ret != LDB_SUCCESS) {
3383                         return ret;
3384                 }
3385                 /*
3386                  * This wipes any LM password history after any password
3387                  * update operation.
3388                  *
3389                  * This is the same as the previous default behaviour
3390                  * of 'lanman auth = no'
3391                  */
3392                 ret = ldb_msg_add_empty(io->ac->update_msg,
3393                                         "lmPwdHistory",
3394                                         el_flags, NULL);
3395                 if (ret != LDB_SUCCESS) {
3396                         return ret;
3397                 }
3398         }
3399         if (update_scb) {
3400                 ret = ldb_msg_add_empty(io->ac->update_msg,
3401                                         "supplementalCredentials",
3402                                         el_flags, NULL);
3403                 if (ret != LDB_SUCCESS) {
3404                         return ret;
3405                 }
3406         }
3407         if (io->ac->update_lastset) {
3408                 ret = ldb_msg_add_empty(io->ac->update_msg,
3409                                         "pwdLastSet",
3410                                         el_flags, NULL);
3411                 if (ret != LDB_SUCCESS) {
3412                         return ret;
3413                 }
3414         }
3415
3416         if (io->g.nt_hash != NULL) {
3417                 ret = samdb_msg_add_hash(ldb, io->ac,
3418                                          io->ac->update_msg,
3419                                          "unicodePwd",
3420                                          io->g.nt_hash);
3421                 if (ret != LDB_SUCCESS) {
3422                         return ret;
3423                 }
3424         }
3425
3426         if (io->g.nt_history_len > 0) {
3427                 ret = samdb_msg_add_hashes(ldb, io->ac,
3428                                            io->ac->update_msg,
3429                                            "ntPwdHistory",
3430                                            io->g.nt_history,
3431                                            io->g.nt_history_len);
3432                 if (ret != LDB_SUCCESS) {
3433                         return ret;
3434                 }
3435         }
3436         if (io->g.supplemental.length > 0) {
3437                 ret = ldb_msg_add_value(io->ac->update_msg,
3438                                         "supplementalCredentials",
3439                                         &io->g.supplemental, NULL);
3440                 if (ret != LDB_SUCCESS) {
3441                         return ret;
3442                 }
3443         }
3444         if (io->ac->update_lastset) {
3445                 ret = samdb_msg_add_uint64(ldb, io->ac,
3446                                            io->ac->update_msg,
3447                                            "pwdLastSet",
3448                                            io->g.last_set);
3449                 if (ret != LDB_SUCCESS) {
3450                         return ret;
3451                 }
3452         }
3453
3454         return LDB_SUCCESS;
3455 }
3456
3457 /*
3458  * This is intended for use by the "password_hash" module since there
3459  * password changes can be specified through one message element with the
3460  * new password (to set) and another one with the old password (to unset).
3461  *
3462  * The first which sets a password (new value) can have flags
3463  * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
3464  * for entries). The latter (old value) has always specified
3465  * LDB_FLAG_MOD_DELETE.
3466  *
3467  * Returns LDB_ERR_CONSTRAINT_VIOLATION and LDB_ERR_UNWILLING_TO_PERFORM if
3468  * matching message elements are malformed in respect to the set/change rules.
3469  * Otherwise it returns LDB_SUCCESS.
3470  */
3471 static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
3472                                         const char *name,
3473                                         enum ldb_request_type operation,
3474                                         const struct ldb_val **new_val,
3475                                         const struct ldb_val **old_val)
3476 {
3477         unsigned int i;
3478
3479         *new_val = NULL;
3480         *old_val = NULL;
3481
3482         if (msg == NULL) {
3483                 return LDB_SUCCESS;
3484         }
3485
3486         for (i = 0; i < msg->num_elements; i++) {
3487                 if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
3488                         continue;
3489                 }
3490
3491                 if ((operation == LDB_MODIFY) &&
3492                     (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE)) {
3493                         /* 0 values are allowed */
3494                         if (msg->elements[i].num_values == 1) {
3495                                 *old_val = &msg->elements[i].values[0];
3496                         } else if (msg->elements[i].num_values > 1) {
3497                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3498                         }
3499                 } else if ((operation == LDB_MODIFY) &&
3500                            (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE)) {
3501                         if (msg->elements[i].num_values > 0) {
3502                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3503                         } else {
3504                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3505                         }
3506                 } else {
3507                         /* Add operations and LDB_FLAG_MOD_ADD */
3508                         if (msg->elements[i].num_values > 0) {
3509                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3510                         } else {
3511                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3512                         }
3513                 }
3514         }
3515
3516         return LDB_SUCCESS;
3517 }
3518
3519 static int setup_io(struct ph_context *ac,
3520                     const struct ldb_message *client_msg,
3521                     const struct ldb_message *existing_msg,
3522                     struct setup_password_fields_io *io)
3523 {
3524         const struct ldb_val *quoted_utf16, *old_quoted_utf16, *lm_hash, *old_lm_hash;
3525         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3526         struct loadparm_context *lp_ctx = talloc_get_type(
3527                 ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
3528         enum store_nt_hash store_hash_setting =
3529                 lpcfg_nt_hash_store(lp_ctx);
3530         int ret;
3531         const struct ldb_message *info_msg = NULL;
3532         struct dom_sid *account_sid = NULL;
3533         int rodc_krbtgt = 0;
3534
3535         *io = (struct setup_password_fields_io) {};
3536
3537         /* Some operations below require kerberos contexts */
3538
3539         if (existing_msg != NULL) {
3540                 /*
3541                  * This is a modify operation
3542                  */
3543                 info_msg = existing_msg;
3544         } else {
3545                 /*
3546                  * This is an add operation
3547                  */
3548                 info_msg = client_msg;
3549         }
3550
3551         ret = smb_krb5_init_context(ac,
3552                                   (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
3553                                   &io->smb_krb5_context);
3554
3555         if (ret != 0) {
3556                 /*
3557                  * In the special case of mit krb5.conf vs heimdal, the includedir
3558                  * statement causes ret == 22 (KRB5_CONFIG_BADFORMAT) to be returned.
3559                  * We look for this case so that we can give a more instructional
3560                  * message to the administrator.
3561                  */
3562                 if (ret == KRB5_CONFIG_BADFORMAT || ret == EINVAL) {
3563                         ldb_asprintf_errstring(ldb, "Failed to setup krb5_context: %s - "
3564                                 "This could be due to an invalid krb5 configuration. "
3565                                 "Please check your system's krb5 configuration is correct.",
3566                                 error_message(ret));
3567                 } else {
3568                         ldb_asprintf_errstring(ldb, "Failed to setup krb5_context: %s",
3569                                 error_message(ret));
3570                 }
3571                 return LDB_ERR_OPERATIONS_ERROR;
3572         }
3573
3574         io->ac                          = ac;
3575
3576         io->u.userAccountControl        = ldb_msg_find_attr_as_uint(info_msg,
3577                                                                     "userAccountControl", 0);
3578         if (info_msg == existing_msg) {
3579                 /*
3580                  * We only take pwdLastSet from the existing object
3581                  * otherwise we leave it as 0.
3582                  *
3583                  * If no attribute is available, e.g. on deleted objects
3584                  * we remember that as UINT64_MAX.
3585                  */
3586                 io->u.pwdLastSet = samdb_result_nttime(info_msg, "pwdLastSet",
3587                                                        UINT64_MAX);
3588         }
3589         io->u.sAMAccountName            = ldb_msg_find_attr_as_string(info_msg,
3590                                                                       "sAMAccountName", NULL);
3591         io->u.user_principal_name       = ldb_msg_find_attr_as_string(info_msg,
3592                                                                       "userPrincipalName", NULL);
3593         io->u.displayName               = ldb_msg_find_attr_as_string(info_msg,
3594                                                                       "displayName", NULL);
3595
3596         /* Ensure it has an objectSID too */
3597         io->u.account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
3598         if (io->u.account_sid != NULL) {
3599                 NTSTATUS status;
3600                 uint32_t rid = 0;
3601
3602                 status = dom_sid_split_rid(account_sid, io->u.account_sid, NULL, &rid);
3603                 if (NT_STATUS_IS_OK(status)) {
3604                         if (rid == DOMAIN_RID_KRBTGT) {
3605                                 io->u.is_krbtgt = true;
3606                         }
3607                 }
3608         }
3609
3610         rodc_krbtgt = ldb_msg_find_attr_as_int(info_msg,
3611                         "msDS-SecondaryKrbTgtNumber", 0);
3612         if (rodc_krbtgt != 0) {
3613                 io->u.is_krbtgt = true;
3614         }
3615
3616         if (io->u.sAMAccountName == NULL) {
3617                 ldb_asprintf_errstring(ldb,
3618                                        "setup_io: sAMAccountName attribute is missing on %s for attempted password set/change",
3619                                        ldb_dn_get_linearized(info_msg->dn));
3620
3621                 return LDB_ERR_CONSTRAINT_VIOLATION;
3622         }
3623
3624         if (io->u.userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
3625                 struct ldb_control *permit_trust = ldb_request_get_control(ac->req,
3626                                 DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
3627
3628                 if (permit_trust == NULL) {
3629                         ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
3630                         ldb_asprintf_errstring(ldb,
3631                                 "%08X: %s - setup_io: changing the interdomain trust password "
3632                                 "on %s not allowed via LDAP. Use LSA or NETLOGON",
3633                                 W_ERROR_V(WERR_ACCESS_DENIED),
3634                                 ldb_strerror(ret),
3635                                 ldb_dn_get_linearized(info_msg->dn));
3636                         return ret;
3637                 }
3638         }
3639
3640         /* Only non-trust accounts have restrictions (possibly this test is the
3641          * wrong way around, but we like to be restrictive if possible */
3642         io->u.restrictions = !(io->u.userAccountControl & UF_TRUST_ACCOUNT_MASK);
3643
3644         if (io->u.is_krbtgt) {
3645                 io->u.restrictions = 0;
3646                 io->ac->status->domain_data.pwdHistoryLength =
3647                         MAX(io->ac->status->domain_data.pwdHistoryLength, 3);
3648         }
3649
3650         /*
3651          * Machine accounts need the NT hash to operate the NETLOGON
3652          * ServerAuthenticate{,2,3} logic
3653          */
3654         if (!(io->u.userAccountControl & UF_NORMAL_ACCOUNT)) {
3655                 store_hash_setting = NT_HASH_STORE_ALWAYS;
3656         }
3657
3658         switch (store_hash_setting) {
3659         case NT_HASH_STORE_ALWAYS:
3660                 io->u.store_nt_hash = true;
3661                 break;
3662         case NT_HASH_STORE_NEVER:
3663                 io->u.store_nt_hash = false;
3664                 break;
3665         case NT_HASH_STORE_AUTO:
3666                 if (lpcfg_ntlm_auth(lp_ctx) == NTLM_AUTH_DISABLED) {
3667                         io->u.store_nt_hash = false;
3668                         break;
3669                 }
3670                 io->u.store_nt_hash = true;
3671                 break;
3672         }
3673
3674         if (ac->userPassword) {
3675                 ret = msg_find_old_and_new_pwd_val(client_msg, "userPassword",
3676                                                    ac->req->operation,
3677                                                    &io->n.cleartext_utf8,
3678                                                    &io->og.cleartext_utf8);
3679                 if (ret != LDB_SUCCESS) {
3680                         ldb_asprintf_errstring(ldb,
3681                                 "setup_io: "
3682                                 "it's only allowed to set the old password once!");
3683                         return ret;
3684                 }
3685         }
3686
3687         if (io->n.cleartext_utf8 != NULL) {
3688                 struct ldb_val *cleartext_utf8_blob;
3689                 char *p;
3690
3691                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
3692                 if (!cleartext_utf8_blob) {
3693                         return ldb_oom(ldb);
3694                 }
3695
3696                 *cleartext_utf8_blob = *io->n.cleartext_utf8;
3697
3698                 /* make sure we have a null terminated string */
3699                 p = talloc_strndup(cleartext_utf8_blob,
3700                                    (const char *)io->n.cleartext_utf8->data,
3701                                    io->n.cleartext_utf8->length);
3702                 if ((p == NULL) && (io->n.cleartext_utf8->length > 0)) {
3703                         return ldb_oom(ldb);
3704                 }
3705                 cleartext_utf8_blob->data = (uint8_t *)p;
3706
3707                 io->n.cleartext_utf8 = cleartext_utf8_blob;
3708         }
3709
3710         ret = msg_find_old_and_new_pwd_val(client_msg, "clearTextPassword",
3711                                            ac->req->operation,
3712                                            &io->n.cleartext_utf16,
3713                                            &io->og.cleartext_utf16);
3714         if (ret != LDB_SUCCESS) {
3715                 ldb_asprintf_errstring(ldb,
3716                         "setup_io: "
3717                         "it's only allowed to set the old password once!");
3718                 return ret;
3719         }
3720
3721         /* this rather strange looking piece of code is there to
3722            handle a ldap client setting a password remotely using the
3723            unicodePwd ldap field. The syntax is that the password is
3724            in UTF-16LE, with a " at either end. Unfortunately the
3725            unicodePwd field is also used to store the nt hashes
3726            internally in Samba, and is used in the nt hash format on
3727            the wire in DRS replication, so we have a single name for
3728            two distinct values. The code below leaves us with a small
3729            chance (less than 1 in 2^32) of a mixup, if someone manages
3730            to create a MD4 hash which starts and ends in 0x22 0x00, as
3731            that would then be treated as a UTF16 password rather than
3732            a nthash */
3733
3734         ret = msg_find_old_and_new_pwd_val(client_msg, "unicodePwd",
3735                                            ac->req->operation,
3736                                            &quoted_utf16,
3737                                            &old_quoted_utf16);
3738         if (ret != LDB_SUCCESS) {
3739                 ldb_asprintf_errstring(ldb,
3740                         "setup_io: "
3741                         "it's only allowed to set the old password once!");
3742                 return ret;
3743         }
3744
3745         /* Checks and converts the actual "unicodePwd" attribute */
3746         if (!ac->hash_values &&
3747             quoted_utf16 &&
3748             quoted_utf16->length >= 4 &&
3749             quoted_utf16->data[0] == '"' &&
3750             quoted_utf16->data[1] == 0 &&
3751             quoted_utf16->data[quoted_utf16->length-2] == '"' &&
3752             quoted_utf16->data[quoted_utf16->length-1] == 0) {
3753                 struct ldb_val *quoted_utf16_2;
3754
3755                 if (io->n.cleartext_utf16) {
3756                         /* refuse the change if someone wants to change with
3757                            both UTF16 possibilities at the same time... */
3758                         ldb_asprintf_errstring(ldb,
3759                                 "setup_io: "
3760                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3761                         return LDB_ERR_UNWILLING_TO_PERFORM;
3762                 }
3763
3764                 /*
3765                  * adapt the quoted UTF16 string to be a real
3766                  * cleartext one
3767                  */
3768                 quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3769                 if (quoted_utf16_2 == NULL) {
3770                         return ldb_oom(ldb);
3771                 }
3772
3773                 quoted_utf16_2->data = quoted_utf16->data + 2;
3774                 quoted_utf16_2->length = quoted_utf16->length-4;
3775                 io->n.cleartext_utf16 = quoted_utf16_2;
3776                 io->n.nt_hash = NULL;
3777
3778         } else if (quoted_utf16) {
3779                 /* We have only the hash available -> so no plaintext here */
3780                 if (!ac->hash_values) {
3781                         /* refuse the change if someone wants to change
3782                            the hash without control specified... */
3783                         ldb_asprintf_errstring(ldb,
3784                                 "setup_io: "
3785                                 "it's not allowed to set the NT hash password directly'");
3786                         /* this looks odd but this is what Windows does:
3787                            returns "UNWILLING_TO_PERFORM" on wrong
3788                            password sets and "CONSTRAINT_VIOLATION" on
3789                            wrong password changes. */
3790                         if (old_quoted_utf16 == NULL) {
3791                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3792                         }
3793
3794                         return LDB_ERR_CONSTRAINT_VIOLATION;
3795                 }
3796
3797                 io->n.nt_hash = talloc(io->ac, struct samr_Password);
3798                 if (io->n.nt_hash == NULL) {
3799                         return ldb_oom(ldb);
3800                 }
3801                 memcpy(io->n.nt_hash->hash, quoted_utf16->data,
3802                        MIN(quoted_utf16->length, sizeof(io->n.nt_hash->hash)));
3803         }
3804
3805         /* Checks and converts the previous "unicodePwd" attribute */
3806         if (!ac->hash_values &&
3807             old_quoted_utf16 &&
3808             old_quoted_utf16->length >= 4 &&
3809             old_quoted_utf16->data[0] == '"' &&
3810             old_quoted_utf16->data[1] == 0 &&
3811             old_quoted_utf16->data[old_quoted_utf16->length-2] == '"' &&
3812             old_quoted_utf16->data[old_quoted_utf16->length-1] == 0) {
3813                 struct ldb_val *old_quoted_utf16_2;
3814
3815                 if (io->og.cleartext_utf16) {
3816                         /* refuse the change if someone wants to change with
3817                            both UTF16 possibilities at the same time... */
3818                         ldb_asprintf_errstring(ldb,
3819                                 "setup_io: "
3820                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3821                         return LDB_ERR_UNWILLING_TO_PERFORM;
3822                 }
3823
3824                 /*
3825                  * adapt the quoted UTF16 string to be a real
3826                  * cleartext one
3827                  */
3828                 old_quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3829                 if (old_quoted_utf16_2 == NULL) {
3830                         return ldb_oom(ldb);
3831                 }
3832
3833                 old_quoted_utf16_2->data = old_quoted_utf16->data + 2;
3834                 old_quoted_utf16_2->length = old_quoted_utf16->length-4;
3835
3836                 io->og.cleartext_utf16 = old_quoted_utf16_2;
3837                 io->og.nt_hash = NULL;
3838         } else if (old_quoted_utf16) {
3839                 /* We have only the hash available -> so no plaintext here */
3840                 if (!ac->hash_values) {
3841                         /* refuse the change if someone wants to change
3842                            the hash without control specified... */
3843                         ldb_asprintf_errstring(ldb,
3844                                 "setup_io: "
3845                                 "it's not allowed to set the NT hash password directly'");
3846                         return LDB_ERR_UNWILLING_TO_PERFORM;
3847                 }
3848
3849                 io->og.nt_hash = talloc(io->ac, struct samr_Password);
3850                 if (io->og.nt_hash == NULL) {
3851                         return ldb_oom(ldb);
3852                 }
3853                 memcpy(io->og.nt_hash->hash, old_quoted_utf16->data,
3854                        MIN(old_quoted_utf16->length, sizeof(io->og.nt_hash->hash)));
3855         }
3856
3857         /* Handles the "dBCSPwd" attribute (LM hash) */
3858         ret = msg_find_old_and_new_pwd_val(client_msg, "dBCSPwd",
3859                                            ac->req->operation,
3860                                            &lm_hash, &old_lm_hash);
3861         if (ret != LDB_SUCCESS) {
3862                 ldb_asprintf_errstring(ldb,
3863                         "setup_io: "
3864                         "it's only allowed to set the old password once!");
3865                 return ret;
3866         }
3867
3868         if (((lm_hash != NULL) || (old_lm_hash != NULL))) {
3869                 /* refuse the change if someone wants to change the LM hash */
3870                 ldb_asprintf_errstring(ldb,
3871                         "setup_io: "
3872                         "it's not allowed to set the LM hash password (dBCSPwd)'");
3873                 return LDB_ERR_UNWILLING_TO_PERFORM;
3874         }
3875
3876         /*
3877          * Handles the password change control if it's specified. It has the
3878          * precedence and overrides already specified old password values of
3879          * change requests (but that shouldn't happen since the control is
3880          * fully internal and only used in conjunction with replace requests!).
3881          */
3882         if (ac->change != NULL) {
3883                 io->og.nt_hash = NULL;
3884         }
3885
3886         /* refuse the change if someone wants to change the clear-
3887            text and supply his own hashes at the same time... */
3888         if ((io->n.cleartext_utf8 || io->n.cleartext_utf16)
3889                         && (io->n.nt_hash)) {
3890                 ldb_asprintf_errstring(ldb,
3891                         "setup_io: "
3892                         "it's only allowed to set the password in form of cleartext attributes or as hashes");
3893                 return LDB_ERR_UNWILLING_TO_PERFORM;
3894         }
3895
3896         /* refuse the change if someone wants to change the password
3897            using both plaintext methods (UTF8 and UTF16) at the same time... */
3898         if (io->n.cleartext_utf8 && io->n.cleartext_utf16) {
3899                 ldb_asprintf_errstring(ldb,
3900                         "setup_io: "
3901                         "it's only allowed to set the cleartext password as 'unicodePwd' or as 'userPassword' or as 'clearTextPassword'");
3902                 return LDB_ERR_UNWILLING_TO_PERFORM;
3903         }
3904
3905         /* refuse the change if someone tries to set/change the password by
3906          * any method that would leave us without a password! */
3907         if (io->ac->update_password
3908             && (!io->n.cleartext_utf8) && (!io->n.cleartext_utf16)
3909             && (!io->n.nt_hash)) {
3910                 ldb_asprintf_errstring(ldb,
3911                         "setup_io: "
3912                         "It's not possible to delete the password (changes using the LAN Manager hash alone could be deactivated)!");
3913                 /* on "userPassword" and "clearTextPassword" we've to return
3914                  * something different, since these are virtual attributes */
3915                 if ((ldb_msg_find_element(client_msg, "userPassword") != NULL) ||
3916                     (ldb_msg_find_element(client_msg, "clearTextPassword") != NULL)) {
3917                         return LDB_ERR_CONSTRAINT_VIOLATION;
3918                 }
3919                 return LDB_ERR_UNWILLING_TO_PERFORM;
3920         }
3921
3922         /*
3923          * refuse the change if someone wants to compare against a
3924          * plaintext or dsdb_control_password_change at the same time
3925          * for a "password modify" operation...
3926          */
3927         if ((io->og.cleartext_utf8 || io->og.cleartext_utf16)
3928             && ac->change) {
3929                 ldb_asprintf_errstring(ldb,
3930                         "setup_io: "
3931                         "it's only allowed to provide the old password in form of cleartext attributes or as the dsdb_control_password_change");
3932                 return LDB_ERR_UNWILLING_TO_PERFORM;
3933         }
3934
3935         /* refuse the change if someone wants to compare against both
3936          * plaintexts at the same time for a "password modify" operation... */
3937         if (io->og.cleartext_utf8 && io->og.cleartext_utf16) {
3938                 ldb_asprintf_errstring(ldb,
3939                         "setup_io: "
3940                         "it's only allowed to provide the old cleartext password as 'unicodePwd' or as 'userPassword' or as 'clearTextPassword'");
3941                 return LDB_ERR_UNWILLING_TO_PERFORM;
3942         }
3943
3944         /* Decides if we have a password modify or password reset operation */
3945         if (ac->req->operation == LDB_ADD) {
3946                 /* On "add" we have only "password reset" */
3947                 ac->pwd_reset = true;
3948         } else if (ac->req->operation == LDB_MODIFY) {
3949                 struct ldb_control *pav_ctrl = NULL;
3950                 struct dsdb_control_password_acl_validation *pav = NULL;
3951
3952                 pav_ctrl = ldb_request_get_control(ac->req,
3953                                 DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID);
3954                 if (pav_ctrl != NULL) {
3955                         pav = talloc_get_type_abort(pav_ctrl->data,
3956                                 struct dsdb_control_password_acl_validation);
3957                 }
3958
3959                 if (pav == NULL && ac->update_password) {
3960                         bool ok;
3961
3962                         /*
3963                          * If the DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID
3964                          * control is missing, we require system access!
3965                          */
3966                         ok = dsdb_have_system_access(
3967                                 ac->module,
3968                                 ac->req,
3969                                 SYSTEM_CONTROL_KEEP_CRITICAL);
3970                         if (!ok) {
3971                                 return ldb_module_operr(ac->module);
3972                         }
3973                 }
3974
3975                 if (pav != NULL) {
3976                         /*
3977                          * We assume what the acl module has validated.
3978                          */
3979                         ac->pwd_reset = pav->pwd_reset;
3980                 } else if (io->og.cleartext_utf8 || io->og.cleartext_utf16
3981                     || ac->change) {
3982                         /*
3983                          * If we have an old password specified or the
3984                          * dsdb_control_password_change then for sure
3985                          * it is a user "password change"
3986                          */
3987                         ac->pwd_reset = false;
3988                 } else {
3989                         /* Otherwise we have also here a "password reset" */
3990                         ac->pwd_reset = true;
3991                 }
3992         } else {
3993                 /* this shouldn't happen */
3994                 return ldb_operr(ldb);
3995         }
3996
3997         if (existing_msg != NULL) {
3998                 NTSTATUS status;
3999                 krb5_error_code krb5_ret;
4000                 DATA_BLOB key_blob;
4001                 DATA_BLOB salt_blob;
4002                 uint32_t kvno;
4003
4004                 if (ac->pwd_reset) {
4005                         /* Get the old password from the database */
4006                         status = samdb_result_passwords_no_lockout(ac,
4007                                                                    lp_ctx,
4008                                                                    existing_msg,
4009                                                                    &io->o.nt_hash);
4010                 } else {
4011                         /* Get the old password from the database */
4012                         status = samdb_result_passwords(ac,
4013                                                         lp_ctx,
4014                                                         existing_msg,
4015                                                         &io->o.nt_hash);
4016                 }
4017
4018                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_LOCKED_OUT)) {
4019                         return dsdb_module_werror(ac->module,
4020                                                   LDB_ERR_CONSTRAINT_VIOLATION,
4021                                                   WERR_ACCOUNT_LOCKED_OUT,
4022                                                   "Password change not permitted,"
4023                                                   " account locked out!");
4024                 }
4025
4026                 if (!NT_STATUS_IS_OK(status)) {
4027                         /*
4028                          * This only happens if the database has gone weird,
4029                          * not if we are just missing the passwords
4030                          */
4031                         return ldb_operr(ldb);
4032                 }
4033
4034                 io->o.nt_history_len = samdb_result_hashes(ac, existing_msg,
4035                                                            "ntPwdHistory",
4036                                                            &io->o.nt_history);
4037                 io->o.supplemental = ldb_msg_find_ldb_val(existing_msg,
4038                                                           "supplementalCredentials");
4039
4040                 if (io->o.supplemental != NULL) {
4041                         enum ndr_err_code ndr_err;
4042
4043                         ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac,
4044                                         &io->o.scb,
4045                                         (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
4046                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4047                                 status = ndr_map_error2ntstatus(ndr_err);
4048                                 ldb_asprintf_errstring(ldb,
4049                                                 "setup_io: failed to pull "
4050                                                 "old supplementalCredentialsBlob: %s",
4051                                                 nt_errstr(status));
4052                                 return LDB_ERR_OPERATIONS_ERROR;
4053                         }
4054                 }
4055
4056                 /*
4057                  * If this account requires a smartcard for login, we don't
4058                  * attempt a comparison with the old password.
4059                  */
4060                 if (io->u.userAccountControl & UF_SMARTCARD_REQUIRED) {
4061                         return LDB_SUCCESS;
4062                 }
4063
4064                 /*
4065                  * Extract the old ENCTYPE_AES256_CTS_HMAC_SHA1_96
4066                  * value from the supplementalCredentials.
4067                  */
4068                 krb5_ret = dsdb_extract_aes_256_key(io->smb_krb5_context->krb5_context,
4069                                                     io->ac,
4070                                                     ldb,
4071                                                     existing_msg,
4072                                                     io->u.userAccountControl,
4073                                                     NULL, /* kvno */
4074                                                     &kvno, /* kvno_out */
4075                                                     &key_blob,
4076                                                     &salt_blob);
4077                 if (krb5_ret == ENOENT) {
4078                         /*
4079                          * If there is no old AES hash (perhaps an imported DB with
4080                          * just unicodePwd) then we just won't have an old
4081                          * password to compare to if there is no NT hash
4082                          */
4083                         return LDB_SUCCESS;
4084                 }
4085                 if (krb5_ret) {
4086                         ldb_asprintf_errstring(ldb,
4087                                                "setup_io: "
4088                                                "extraction of salt for old aes256-cts-hmac-sha1-96 key failed: %s",
4089                                                smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
4090                                                                           krb5_ret, io->ac));
4091                         return LDB_ERR_OPERATIONS_ERROR;
4092                 }
4093
4094                 io->o.salt = salt_blob;
4095                 io->o.aes_256 = key_blob;
4096                 io->o.kvno = kvno;
4097         }
4098
4099         return LDB_SUCCESS;
4100 }
4101
4102 static struct ph_context *ph_init_context(struct ldb_module *module,
4103                                           struct ldb_request *req,
4104                                           bool userPassword,
4105                                           bool update_password)
4106 {
4107         struct ldb_context *ldb;
4108         struct ph_context *ac;
4109         struct loadparm_context *lp_ctx = NULL;
4110
4111         ldb = ldb_module_get_ctx(module);
4112
4113         ac = talloc_zero(req, struct ph_context);
4114         if (ac == NULL) {
4115                 ldb_set_errstring(ldb, "Out of Memory");
4116                 return NULL;
4117         }
4118
4119         ac->module = module;
4120         ac->req = req;
4121         ac->userPassword = userPassword;
4122         ac->update_password = update_password;
4123         ac->update_lastset = true;
4124
4125         lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
4126                                        struct loadparm_context);
4127         ac->gpg_key_ids = lpcfg_password_hash_gpg_key_ids(lp_ctx);
4128         ac->userPassword_schemes
4129                 = lpcfg_password_hash_userpassword_schemes(lp_ctx);
4130         return ac;
4131 }
4132
4133 static void ph_apply_controls(struct ph_context *ac)
4134 {
4135         struct ldb_control *ctrl;
4136
4137         ac->change_status = false;
4138         ctrl = ldb_request_get_control(ac->req,
4139                                        DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID);
4140         if (ctrl != NULL) {
4141                 ac->change_status = true;
4142
4143                 /* Mark the "change status" control as uncritical (done) */
4144                 ctrl->critical = false;
4145         }
4146
4147         ac->hash_values = false;
4148         ctrl = ldb_request_get_control(ac->req,
4149                                        DSDB_CONTROL_PASSWORD_HASH_VALUES_OID);
4150         if (ctrl != NULL) {
4151                 ac->hash_values = true;
4152
4153                 /* Mark the "hash values" control as uncritical (done) */
4154                 ctrl->critical = false;
4155         }
4156
4157         ctrl = ldb_request_get_control(ac->req,
4158                                        DSDB_CONTROL_PASSWORD_CHANGE_OLD_PW_CHECKED_OID);
4159         if (ctrl != NULL) {
4160                 ac->change = talloc_get_type_abort(ctrl->data, struct dsdb_control_password_change);
4161
4162                 /* Mark the "change" control as uncritical (done) */
4163                 ctrl->critical = false;
4164         }
4165
4166         ac->pwd_last_set_bypass = false;
4167         ctrl = ldb_request_get_control(ac->req,
4168                                 DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID);
4169         if (ctrl != NULL) {
4170                 ac->pwd_last_set_bypass = true;
4171
4172                 /* Mark the "bypass pwdLastSet" control as uncritical (done) */
4173                 ctrl->critical = false;
4174         }
4175
4176         ac->pwd_last_set_default = false;
4177         ctrl = ldb_request_get_control(ac->req,
4178                                 DSDB_CONTROL_PASSWORD_DEFAULT_LAST_SET_OID);
4179         if (ctrl != NULL) {
4180                 ac->pwd_last_set_default = true;
4181
4182                 /* Mark the "bypass pwdLastSet" control as uncritical (done) */
4183                 ctrl->critical = false;
4184         }
4185
4186         ac->smartcard_reset = false;
4187         ctrl = ldb_request_get_control(ac->req,
4188                                 DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID);
4189         if (ctrl != NULL) {
4190                 struct dsdb_control_password_user_account_control *uac = NULL;
4191                 uint32_t added_flags = 0;
4192
4193                 uac = talloc_get_type_abort(ctrl->data,
4194                         struct dsdb_control_password_user_account_control);
4195
4196                 added_flags = uac->new_flags & ~uac->old_flags;
4197
4198                 if (added_flags & UF_SMARTCARD_REQUIRED) {
4199                         ac->smartcard_reset = true;
4200                 }
4201
4202                 /* Mark the "smartcard required" control as uncritical (done) */
4203                 ctrl->critical = false;
4204         }
4205 }
4206
4207 static int ph_op_callback(struct ldb_request *req, struct ldb_reply *ares)
4208 {
4209         struct ph_context *ac;
4210
4211         ac = talloc_get_type(req->context, struct ph_context);
4212
4213         if (!ares) {
4214                 return ldb_module_done(ac->req, NULL, NULL,
4215                                         LDB_ERR_OPERATIONS_ERROR);
4216         }
4217
4218         if (ares->type == LDB_REPLY_REFERRAL) {
4219                 return ldb_module_send_referral(ac->req, ares->referral);
4220         }
4221
4222         if ((ares->error != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
4223                 /* On success and trivial errors a status control is being
4224                  * added (used for example by the "samdb_set_password" call) */
4225                 ldb_reply_add_control(ares,
4226                                       DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
4227                                       false,
4228                                       ac->status);
4229         }
4230
4231         if (ares->error != LDB_SUCCESS) {
4232                 return ldb_module_done(ac->req, ares->controls,
4233                                         ares->response, ares->error);
4234         }
4235
4236         if (ares->type != LDB_REPLY_DONE) {
4237                 talloc_free(ares);
4238                 return ldb_module_done(ac->req, NULL, NULL,
4239                                         LDB_ERR_OPERATIONS_ERROR);
4240         }
4241
4242         return ldb_module_done(ac->req, ares->controls,
4243                                 ares->response, ares->error);
4244 }
4245
4246 static int password_hash_add_do_add(struct ph_context *ac);
4247 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares);
4248 static int password_hash_mod_search_self(struct ph_context *ac);
4249 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares);
4250 static int password_hash_mod_do_mod(struct ph_context *ac);
4251
4252 /*
4253  * LDB callback handler for searching for a user's PSO. Once we have all the
4254  * Password Settings that apply to the user, we can continue with the modify
4255  * operation
4256  */
4257 static int get_pso_data_callback(struct ldb_request *req,
4258                                  struct ldb_reply *ares)
4259 {
4260         struct ldb_context *ldb = NULL;
4261         struct ph_context *ac = NULL;
4262         bool domain_complexity = true;
4263         bool pso_complexity = true;
4264         struct dsdb_user_pwd_settings *settings = NULL;
4265         int ret = LDB_SUCCESS;
4266
4267         ac = talloc_get_type(req->context, struct ph_context);
4268         ldb = ldb_module_get_ctx(ac->module);
4269
4270         if (!ares) {
4271                 ret = LDB_ERR_OPERATIONS_ERROR;
4272                 goto done;
4273         }
4274         if (ares->error != LDB_SUCCESS) {
4275                 return ldb_module_done(ac->req, ares->controls,
4276                                        ares->response, ares->error);
4277         }
4278
4279         switch (ares->type) {
4280         case LDB_REPLY_ENTRY:
4281
4282                 /* check status was initialized by the domain query */
4283                 if (ac->status == NULL) {
4284                         talloc_free(ares);
4285                         ldb_set_errstring(ldb, "Uninitialized status");
4286                         ret = LDB_ERR_OPERATIONS_ERROR;
4287                         goto done;
4288                 }
4289
4290                 /*
4291                  * use the PSO's values instead of the domain defaults (the PSO
4292                  * attributes should always exist, but use the domain default
4293                  * values as a fallback).
4294                  */
4295                 settings = &ac->status->domain_data;
4296                 settings->store_cleartext =
4297                         ldb_msg_find_attr_as_bool(ares->message,
4298                                                   "msDS-PasswordReversibleEncryptionEnabled",
4299                                                   settings->store_cleartext);
4300
4301                 settings->pwdHistoryLength =
4302                         ldb_msg_find_attr_as_uint(ares->message,
4303                                                   "msDS-PasswordHistoryLength",
4304                                                   settings->pwdHistoryLength);
4305                 settings->maxPwdAge =
4306                         ldb_msg_find_attr_as_int64(ares->message,
4307                                                    "msDS-MaximumPasswordAge",
4308                                                    settings->maxPwdAge);
4309                 settings->minPwdAge =
4310                         ldb_msg_find_attr_as_int64(ares->message,
4311                                                    "msDS-MinimumPasswordAge",
4312                                                    settings->minPwdAge);
4313                 settings->minPwdLength =
4314                         ldb_msg_find_attr_as_uint(ares->message,
4315                                                   "msDS-MinimumPasswordLength",
4316                                                   settings->minPwdLength);
4317                 domain_complexity =
4318                         (settings->pwdProperties & DOMAIN_PASSWORD_COMPLEX);
4319                 pso_complexity =
4320                         ldb_msg_find_attr_as_bool(ares->message,
4321                                                   "msDS-PasswordComplexityEnabled",
4322                                                    domain_complexity);
4323
4324                 /* set or clear the complexity bit if required */
4325                 if (pso_complexity && !domain_complexity) {
4326                         settings->pwdProperties |= DOMAIN_PASSWORD_COMPLEX;
4327                 } else if (domain_complexity && !pso_complexity) {
4328                         settings->pwdProperties &= ~DOMAIN_PASSWORD_COMPLEX;
4329                 }
4330
4331                 if (ac->pso_res != NULL) {
4332                         DBG_ERR("Too many PSO results for %s\n",
4333                                 ldb_dn_get_linearized(ac->search_res->message->dn));
4334                         talloc_free(ac->pso_res);
4335                 }
4336
4337                 /* store the PSO result (we may need its lockout settings) */
4338                 ac->pso_res = talloc_steal(ac, ares);
4339                 ret = LDB_SUCCESS;
4340                 break;
4341
4342         case LDB_REPLY_REFERRAL:
4343                 /* ignore */
4344                 talloc_free(ares);
4345                 ret = LDB_SUCCESS;
4346                 break;
4347
4348         case LDB_REPLY_DONE:
4349                 talloc_free(ares);
4350
4351                 /*
4352                  * perform the next step of the modify operation (this code
4353                  * shouldn't get called in the 'user add' case)
4354                  */
4355                 if (ac->req->operation == LDB_MODIFY) {
4356                         ret = password_hash_mod_do_mod(ac);
4357                 } else {
4358                         ret = LDB_ERR_OPERATIONS_ERROR;
4359                 }
4360                 break;
4361         }
4362
4363 done:
4364         if (ret != LDB_SUCCESS) {
4365                 struct ldb_reply *new_ares;
4366
4367                 new_ares = talloc_zero(ac->req, struct ldb_reply);
4368                 if (new_ares == NULL) {
4369                         ldb_oom(ldb);
4370                         return ldb_module_done(ac->req, NULL, NULL,
4371                                                LDB_ERR_OPERATIONS_ERROR);
4372                 }
4373
4374                 new_ares->error = ret;
4375                 if ((ret != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
4376                         /* On success and trivial errors a status control is being
4377                          * added (used for example by the "samdb_set_password" call) */
4378                         ldb_reply_add_control(new_ares,
4379                                               DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
4380                                               false,
4381                                               ac->status);
4382                 }
4383
4384                 return ldb_module_done(ac->req, new_ares->controls,
4385                                        new_ares->response, new_ares->error);
4386         }
4387
4388         return LDB_SUCCESS;
4389 }
4390
4391 /*
4392  * Builds and returns a search request to look up the PSO that applies to
4393  * the user in question. Returns NULL if no PSO applies, or could not be found
4394  */
4395 static struct ldb_request * build_pso_data_request(struct ph_context *ac)
4396 {
4397         /* attrs[] is returned from this function in
4398            pso_req->op.search.attrs, so it must be static, as
4399            otherwise the compiler can put it on the stack */
4400         static const char * const attrs[] = { "msDS-PasswordComplexityEnabled",
4401                                               "msDS-PasswordReversibleEncryptionEnabled",
4402                                               "msDS-PasswordHistoryLength",
4403                                               "msDS-MaximumPasswordAge",
4404                                               "msDS-MinimumPasswordAge",
4405                                               "msDS-MinimumPasswordLength",
4406                                               "msDS-LockoutThreshold",
4407                                               "msDS-LockoutObservationWindow",
4408                                               NULL };
4409         struct ldb_context *ldb = NULL;
4410         struct ldb_request *pso_req = NULL;
4411         struct ldb_dn *pso_dn = NULL;
4412         TALLOC_CTX *mem_ctx = ac;
4413         int ret;
4414
4415         ldb = ldb_module_get_ctx(ac->module);
4416
4417         /* if a PSO applies to the user, we need to lookup the PSO as well */
4418         pso_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, ac->search_res->message,
4419                                          "msDS-ResultantPSO");
4420         if (pso_dn == NULL) {
4421                 return NULL;
4422         }
4423
4424         ret = ldb_build_search_req(&pso_req, ldb, mem_ctx, pso_dn,
4425                                    LDB_SCOPE_BASE, NULL, attrs, NULL,
4426                                    ac, get_pso_data_callback,
4427                                    ac->dom_req);
4428
4429         /* log errors, but continue with the default domain settings */
4430         if (ret != LDB_SUCCESS) {
4431                 DBG_ERR("Error %d constructing PSO query for user %s\n", ret,
4432                         ldb_dn_get_linearized(ac->search_res->message->dn));
4433         }
4434         LDB_REQ_SET_LOCATION(pso_req);
4435         return pso_req;
4436 }
4437
4438
4439 static int get_domain_data_callback(struct ldb_request *req,
4440                                     struct ldb_reply *ares)
4441 {
4442         struct ldb_context *ldb;
4443         struct ph_context *ac;
4444         struct loadparm_context *lp_ctx;
4445         struct ldb_request *pso_req = NULL;
4446         int ret = LDB_SUCCESS;
4447
4448         ac = talloc_get_type(req->context, struct ph_context);
4449         ldb = ldb_module_get_ctx(ac->module);
4450
4451         if (!ares) {
4452                 ret = LDB_ERR_OPERATIONS_ERROR;
4453                 goto done;
4454         }
4455         if (ares->error != LDB_SUCCESS) {
4456                 return ldb_module_done(ac->req, ares->controls,
4457                                         ares->response, ares->error);
4458         }
4459
4460         switch (ares->type) {
4461         case LDB_REPLY_ENTRY:
4462                 if (ac->status != NULL) {
4463                         talloc_free(ares);
4464
4465                         ldb_set_errstring(ldb, "Too many results");
4466                         ret = LDB_ERR_OPERATIONS_ERROR;
4467                         goto done;
4468                 }
4469
4470                 /* Setup the "status" structure (used as control later) */
4471                 ac->status = talloc_zero(ac->req,
4472                                          struct dsdb_control_password_change_status);
4473                 if (ac->status == NULL) {
4474                         talloc_free(ares);
4475
4476                         ldb_oom(ldb);
4477                         ret = LDB_ERR_OPERATIONS_ERROR;
4478                         goto done;
4479                 }
4480
4481                 /* Setup the "domain data" structure */
4482                 ac->status->domain_data.pwdProperties =
4483                         ldb_msg_find_attr_as_uint(ares->message, "pwdProperties", -1);
4484                 ac->status->domain_data.pwdHistoryLength =
4485                         ldb_msg_find_attr_as_uint(ares->message, "pwdHistoryLength", -1);
4486                 ac->status->domain_data.maxPwdAge =
4487                         ldb_msg_find_attr_as_int64(ares->message, "maxPwdAge", -1);
4488                 ac->status->domain_data.minPwdAge =
4489                         ldb_msg_find_attr_as_int64(ares->message, "minPwdAge", -1);
4490                 ac->status->domain_data.minPwdLength =
4491                         ldb_msg_find_attr_as_uint(ares->message, "minPwdLength", -1);
4492                 ac->status->domain_data.store_cleartext =
4493                         ac->status->domain_data.pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT;
4494
4495                 /* For a domain DN, this puts things in dotted notation */
4496                 /* For builtin domains, this will give details for the host,
4497                  * but that doesn't really matter, as it's just used for salt
4498                  * and kerberos principals, which don't exist here */
4499
4500                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
4501                                          struct loadparm_context);
4502
4503                 ac->status->domain_data.dns_domain = lpcfg_dnsdomain(lp_ctx);
4504                 ac->status->domain_data.realm = lpcfg_realm(lp_ctx);
4505                 ac->status->domain_data.netbios_domain = lpcfg_sam_name(lp_ctx);
4506
4507                 ac->status->reject_reason = SAM_PWD_CHANGE_NO_ERROR;
4508
4509                 if (ac->dom_res != NULL) {
4510                         talloc_free(ares);
4511
4512                         ldb_set_errstring(ldb, "Too many results");
4513                         ret = LDB_ERR_OPERATIONS_ERROR;
4514                         goto done;
4515                 }
4516
4517                 ac->dom_res = talloc_steal(ac, ares);
4518                 ret = LDB_SUCCESS;
4519                 break;
4520
4521         case LDB_REPLY_REFERRAL:
4522                 /* ignore */
4523                 talloc_free(ares);
4524                 ret = LDB_SUCCESS;
4525                 break;
4526
4527         case LDB_REPLY_DONE:
4528                 talloc_free(ares);
4529                 /* call the next step */
4530                 switch (ac->req->operation) {
4531                 case LDB_ADD:
4532                         ret = password_hash_add_do_add(ac);
4533                         break;
4534
4535                 case LDB_MODIFY:
4536
4537                         /*
4538                          * The user may have an optional PSO applied. If so,
4539                          * query the PSO to get the Fine-Grained Password Policy
4540                          * for the user, before we perform the modify
4541                          */
4542                         pso_req = build_pso_data_request(ac);
4543                         if (pso_req != NULL) {
4544                                 ret = ldb_next_request(ac->module, pso_req);
4545                         } else {
4546
4547                                 /* no PSO, so we can perform the modify now */
4548                                 ret = password_hash_mod_do_mod(ac);
4549                         }
4550                         break;
4551
4552                 default:
4553                         ret = LDB_ERR_OPERATIONS_ERROR;
4554                         break;
4555                 }
4556                 break;
4557         }
4558
4559 done:
4560         if (ret != LDB_SUCCESS) {
4561                 struct ldb_reply *new_ares;
4562
4563                 new_ares = talloc_zero(ac->req, struct ldb_reply);
4564                 if (new_ares == NULL) {
4565                         ldb_oom(ldb);
4566                         return ldb_module_done(ac->req, NULL, NULL,
4567                                                LDB_ERR_OPERATIONS_ERROR);
4568                 }
4569
4570                 new_ares->error = ret;
4571                 if ((ret != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
4572                         /* On success and trivial errors a status control is being
4573                          * added (used for example by the "samdb_set_password" call) */
4574                         ldb_reply_add_control(new_ares,
4575                                               DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
4576                                               false,
4577                                               ac->status);
4578                 }
4579
4580                 return ldb_module_done(ac->req, new_ares->controls,
4581                                        new_ares->response, new_ares->error);
4582         }
4583
4584         return LDB_SUCCESS;
4585 }
4586
4587 static int build_domain_data_request(struct ph_context *ac)
4588 {
4589         /* attrs[] is returned from this function in
4590            ac->dom_req->op.search.attrs, so it must be static, as
4591            otherwise the compiler can put it on the stack */
4592         struct ldb_context *ldb;
4593         static const char * const attrs[] = { "pwdProperties",
4594                                               "pwdHistoryLength",
4595                                               "maxPwdAge",
4596                                               "minPwdAge",
4597                                               "minPwdLength",
4598                                               "lockoutThreshold",
4599                                               "lockOutObservationWindow",
4600                                               NULL };
4601         int ret;
4602
4603         ldb = ldb_module_get_ctx(ac->module);
4604
4605         ret = ldb_build_search_req(&ac->dom_req, ldb, ac,
4606                                    ldb_get_default_basedn(ldb),
4607                                    LDB_SCOPE_BASE,
4608                                    NULL, attrs,
4609                                    NULL,
4610                                    ac, get_domain_data_callback,
4611                                    ac->req);
4612         LDB_REQ_SET_LOCATION(ac->dom_req);
4613         return ret;
4614 }
4615
4616 static int password_hash_needed(struct ldb_module *module,
4617                                 struct ldb_request *req,
4618                                 struct ph_context **_ac)
4619 {
4620         struct ldb_context *ldb = ldb_module_get_ctx(module);
4621         const char *operation = NULL;
4622         const struct ldb_message *msg = NULL;
4623         struct ph_context *ac = NULL;
4624         const char *passwordAttrs[] = {
4625                 DSDB_PASSWORD_ATTRIBUTES,
4626                 NULL
4627         };
4628         const char **a = NULL;
4629         unsigned int attr_cnt = 0;
4630         struct ldb_control *bypass = NULL;
4631         struct ldb_control *uac_ctrl = NULL;
4632         bool userPassword = dsdb_user_password_support(module, req, req);
4633         bool update_password = false;
4634         bool processing_needed = false;
4635
4636         *_ac = NULL;
4637
4638         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_needed\n");
4639
4640         switch (req->operation) {
4641         case LDB_ADD:
4642                 operation = "add";
4643                 msg = req->op.add.message;
4644                 break;
4645         case LDB_MODIFY:
4646                 operation = "modify";
4647                 msg = req->op.mod.message;
4648                 break;
4649         default:
4650                 return ldb_next_request(module, req);
4651         }
4652
4653         if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
4654                 return ldb_next_request(module, req);
4655         }
4656
4657         bypass = ldb_request_get_control(req,
4658                                          DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID);
4659         if (bypass != NULL) {
4660                 /* Mark the "bypass" control as uncritical (done) */
4661                 bypass->critical = false;
4662                 ldb_debug(ldb, LDB_DEBUG_TRACE,
4663                           "password_hash_needed(%s) (bypassing)\n",
4664                           operation);
4665                 return password_hash_bypass(module, req);
4666         }
4667
4668         /* nobody must touch password histories and 'supplementalCredentials' */
4669         if (ldb_msg_find_element(msg, "ntPwdHistory")) {
4670                 return LDB_ERR_UNWILLING_TO_PERFORM;
4671         }
4672         if (ldb_msg_find_element(msg, "lmPwdHistory")) {
4673                 return LDB_ERR_UNWILLING_TO_PERFORM;
4674         }
4675         if (ldb_msg_find_element(msg, "supplementalCredentials")) {
4676                 return LDB_ERR_UNWILLING_TO_PERFORM;
4677         }
4678
4679         /*
4680          * If no part of this touches the 'userPassword' OR 'clearTextPassword'
4681          * OR 'unicodePwd' OR 'dBCSPwd' we don't need to make any changes.
4682          * For password changes/set there should be a 'delete' or a 'modify'
4683          * on these attributes.
4684          */
4685         for (a = passwordAttrs; *a != NULL; a++) {
4686                 if ((!userPassword) && (ldb_attr_cmp(*a, "userPassword") == 0)) {
4687                         continue;
4688                 }
4689
4690                 if (ldb_msg_find_element(msg, *a) != NULL) {
4691                         /* MS-ADTS 3.1.1.3.1.5.2 */
4692                         if ((ldb_attr_cmp(*a, "userPassword") == 0) &&
4693                             (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003)) {
4694                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4695                         }
4696
4697                         ++attr_cnt;
4698                 }
4699         }
4700
4701         if (attr_cnt > 0) {
4702                 update_password = true;
4703                 processing_needed = true;
4704         }
4705
4706         if (ldb_msg_find_element(msg, "pwdLastSet")) {
4707                 processing_needed = true;
4708         }
4709
4710         uac_ctrl = ldb_request_get_control(req,
4711                                 DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID);
4712         if (uac_ctrl != NULL) {
4713                 struct dsdb_control_password_user_account_control *uac = NULL;
4714                 uint32_t added_flags = 0;
4715
4716                 uac = talloc_get_type_abort(uac_ctrl->data,
4717                         struct dsdb_control_password_user_account_control);
4718
4719                 added_flags = uac->new_flags & ~uac->old_flags;
4720
4721                 if (added_flags & UF_SMARTCARD_REQUIRED) {
4722                         processing_needed = true;
4723                 }
4724         }
4725
4726         if (!processing_needed) {
4727                 return ldb_next_request(module, req);
4728         }
4729
4730         ac = ph_init_context(module, req, userPassword, update_password);
4731         if (!ac) {
4732                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
4733                 return ldb_operr(ldb);
4734         }
4735         ph_apply_controls(ac);
4736
4737         /*
4738          * Make a copy in order to apply our modifications
4739          * to the final update
4740          */
4741         ac->update_msg = ldb_msg_copy_shallow(ac, msg);
4742         if (ac->update_msg == NULL) {
4743                 return ldb_oom(ldb);
4744         }
4745
4746         dsdb_remove_password_related_attrs(ac->update_msg, ac->userPassword);
4747
4748         *_ac = ac;
4749         return LDB_SUCCESS;
4750 }
4751
4752 static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
4753 {
4754         struct ldb_context *ldb = ldb_module_get_ctx(module);
4755         struct ph_context *ac = NULL;
4756         int ret;
4757
4758         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_add\n");
4759
4760         ret = password_hash_needed(module, req, &ac);
4761         if (ret != LDB_SUCCESS) {
4762                 return ret;
4763         }
4764         if (ac == NULL) {
4765                 return ret;
4766         }
4767
4768         /* Make sure we are performing the password set action on a (for us)
4769          * valid object. Those are instances of either "user" and/or
4770          * "inetOrgPerson". Otherwise continue with the submodules. */
4771         if ((!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "user"))
4772                 && (!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "inetOrgPerson"))) {
4773
4774                 TALLOC_FREE(ac);
4775
4776                 if (ldb_msg_find_element(req->op.add.message, "clearTextPassword") != NULL) {
4777                         ldb_set_errstring(ldb,
4778                                           "'clearTextPassword' is only allowed on objects of class 'user' and/or 'inetOrgPerson'!");
4779                         return LDB_ERR_NO_SUCH_ATTRIBUTE;
4780                 }
4781
4782                 return ldb_next_request(module, req);
4783         }
4784
4785         /* get user domain data */
4786         ret = build_domain_data_request(ac);
4787         if (ret != LDB_SUCCESS) {
4788                 return ret;
4789         }
4790
4791         return ldb_next_request(module, ac->dom_req);
4792 }
4793
4794 static int password_hash_add_do_add(struct ph_context *ac)
4795 {
4796         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
4797         struct ldb_request *down_req;
4798         struct setup_password_fields_io io;
4799         int ret;
4800
4801         /* Prepare the internal data structure containing the passwords */
4802         ret = setup_io(ac, ac->req->op.add.message, NULL, &io);
4803         if (ret != LDB_SUCCESS) {
4804                 return ret;
4805         }
4806
4807         ret = setup_password_fields(&io);
4808         if (ret != LDB_SUCCESS) {
4809                 return ret;
4810         }
4811
4812         ret = check_password_restrictions_and_log(&io);
4813         if (ret != LDB_SUCCESS) {
4814                 return ret;
4815         }
4816
4817         ret = setup_smartcard_reset(&io);
4818         if (ret != LDB_SUCCESS) {
4819                 return ret;
4820         }
4821
4822         ret = update_final_msg(&io);
4823         if (ret != LDB_SUCCESS) {
4824                 return ret;
4825         }
4826
4827         ret = ldb_build_add_req(&down_req, ldb, ac,
4828                                 ac->update_msg,
4829                                 ac->req->controls,
4830                                 ac, ph_op_callback,
4831                                 ac->req);
4832         LDB_REQ_SET_LOCATION(down_req);
4833         if (ret != LDB_SUCCESS) {
4834                 return ret;
4835         }
4836
4837         return ldb_next_request(ac->module, down_req);
4838 }
4839
4840 static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
4841 {
4842         struct ldb_context *ldb = ldb_module_get_ctx(module);
4843         struct ph_context *ac = NULL;
4844         const char *passwordAttrs[] = {DSDB_PASSWORD_ATTRIBUTES, NULL}, **l;
4845         unsigned int del_attr_cnt, add_attr_cnt, rep_attr_cnt;
4846         struct ldb_message_element *passwordAttr;
4847         struct ldb_message *msg;
4848         struct ldb_request *down_req;
4849         struct ldb_control *restore = NULL;
4850         int ret;
4851         unsigned int i = 0;
4852
4853         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");
4854
4855         ret = password_hash_needed(module, req, &ac);
4856         if (ret != LDB_SUCCESS) {
4857                 return ret;
4858         }
4859         if (ac == NULL) {
4860                 return ret;
4861         }
4862
4863         /* use a new message structure so that we can modify it */
4864         msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
4865         if (msg == NULL) {
4866                 return ldb_oom(ldb);
4867         }
4868
4869         /* - check for single-valued password attributes
4870          *   (if not return "CONSTRAINT_VIOLATION")
4871          * - check that for a password change operation one add and one delete
4872          *   operation exists
4873          *   (if not return "CONSTRAINT_VIOLATION" or "UNWILLING_TO_PERFORM")
4874          * - check that a password change and a password set operation cannot
4875          *   be mixed
4876          *   (if not return "UNWILLING_TO_PERFORM")
4877          * - remove all password attributes modifications from the first change
4878          *   operation (anything without the passwords) - we will make the real
4879          *   modification later */
4880         del_attr_cnt = 0;
4881         add_attr_cnt = 0;
4882         rep_attr_cnt = 0;
4883         for (l = passwordAttrs; *l != NULL; l++) {
4884                 if ((!ac->userPassword) &&
4885                     (ldb_attr_cmp(*l, "userPassword") == 0)) {
4886                         continue;
4887                 }
4888
4889                 while ((passwordAttr = ldb_msg_find_element(msg, *l)) != NULL) {
4890                         unsigned int mtype = LDB_FLAG_MOD_TYPE(passwordAttr->flags);
4891                         unsigned int nvalues = passwordAttr->num_values;
4892
4893                         if (mtype == LDB_FLAG_MOD_DELETE) {
4894                                 ++del_attr_cnt;
4895                         }
4896                         if (mtype == LDB_FLAG_MOD_ADD) {
4897                                 ++add_attr_cnt;
4898                         }
4899                         if (mtype == LDB_FLAG_MOD_REPLACE) {
4900                                 ++rep_attr_cnt;
4901                         }
4902                         if ((nvalues != 1) && (mtype == LDB_FLAG_MOD_ADD)) {
4903                                 talloc_free(ac);
4904                                 ldb_asprintf_errstring(ldb,
4905                                                        "'%s' attribute must have exactly one value on add operations!",
4906                                                        *l);
4907                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4908                         }
4909                         if ((nvalues > 1) && (mtype == LDB_FLAG_MOD_DELETE)) {
4910                                 talloc_free(ac);
4911                                 ldb_asprintf_errstring(ldb,
4912                                                        "'%s' attribute must have zero or one value(s) on delete operations!",
4913                                                        *l);
4914                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4915                         }
4916                         ldb_msg_remove_element(msg, passwordAttr);
4917                 }
4918         }
4919         if ((del_attr_cnt == 0) && (add_attr_cnt > 0)) {
4920                 talloc_free(ac);
4921                 ldb_set_errstring(ldb,
4922                                   "Only the add action for a password change specified!");
4923                 return LDB_ERR_UNWILLING_TO_PERFORM;
4924         }
4925         if ((del_attr_cnt > 1) || (add_attr_cnt > 1)) {
4926                 talloc_free(ac);
4927                 ldb_set_errstring(ldb,
4928                                   "Only one delete and one add action for a password change allowed!");
4929                 return LDB_ERR_UNWILLING_TO_PERFORM;
4930         }
4931         if ((rep_attr_cnt > 0) && ((del_attr_cnt > 0) || (add_attr_cnt > 0))) {
4932                 talloc_free(ac);
4933                 ldb_set_errstring(ldb,
4934                                   "Either a password change or a password set operation is allowed!");
4935                 return LDB_ERR_UNWILLING_TO_PERFORM;
4936         }
4937
4938         restore = ldb_request_get_control(req,
4939                                         DSDB_CONTROL_RESTORE_TOMBSTONE_OID);
4940         if (restore == NULL) {
4941                 /*
4942                  * A tombstone reanimation generates a double update
4943                  * of pwdLastSet.
4944                  *
4945                  * So we only remove it without the
4946                  * DSDB_CONTROL_RESTORE_TOMBSTONE_OID control.
4947                  */
4948                 ldb_msg_remove_attr(msg, "pwdLastSet");
4949         }
4950
4951
4952         /* if there was nothing else to be modified skip to next step */
4953         if (msg->num_elements == 0) {
4954                 return password_hash_mod_search_self(ac);
4955         }
4956
4957         /*
4958          * Now we apply all changes remaining in msg
4959          * and remove them from our final update_msg
4960          */
4961
4962         for (i = 0; i < msg->num_elements; i++) {
4963                 ldb_msg_remove_attr(ac->update_msg,
4964                                     msg->elements[i].name);
4965         }
4966
4967         ret = ldb_build_mod_req(&down_req, ldb, ac,
4968                                 msg,
4969                                 req->controls,
4970                                 ac, ph_modify_callback,
4971                                 req);
4972         LDB_REQ_SET_LOCATION(down_req);
4973         if (ret != LDB_SUCCESS) {
4974                 return ret;
4975         }
4976
4977         return ldb_next_request(module, down_req);
4978 }
4979
4980 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
4981 {
4982         struct ph_context *ac;
4983
4984         ac = talloc_get_type(req->context, struct ph_context);
4985
4986         if (!ares) {
4987                 return ldb_module_done(ac->req, NULL, NULL,
4988                                         LDB_ERR_OPERATIONS_ERROR);
4989         }
4990
4991         if (ares->type == LDB_REPLY_REFERRAL) {
4992                 return ldb_module_send_referral(ac->req, ares->referral);
4993         }
4994
4995         if (ares->error != LDB_SUCCESS) {
4996                 return ldb_module_done(ac->req, ares->controls,
4997                                         ares->response, ares->error);
4998         }
4999
5000         if (ares->type != LDB_REPLY_DONE) {
5001                 talloc_free(ares);
5002                 return ldb_module_done(ac->req, NULL, NULL,
5003                                         LDB_ERR_OPERATIONS_ERROR);
5004         }
5005
5006         talloc_free(ares);
5007
5008         return password_hash_mod_search_self(ac);
5009 }
5010
5011 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
5012 {
5013         struct ldb_context *ldb;
5014         struct ph_context *ac;
5015         int ret = LDB_SUCCESS;
5016
5017         ac = talloc_get_type(req->context, struct ph_context);
5018         ldb = ldb_module_get_ctx(ac->module);
5019
5020         if (!ares) {
5021                 ret = LDB_ERR_OPERATIONS_ERROR;
5022                 goto done;
5023         }
5024         if (ares->error != LDB_SUCCESS) {
5025                 return ldb_module_done(ac->req, ares->controls,
5026                                         ares->response, ares->error);
5027         }
5028
5029         /* we are interested only in the single reply (base search) */
5030         switch (ares->type) {
5031         case LDB_REPLY_ENTRY:
5032                 /* Make sure we are performing the password change action on a
5033                  * (for us) valid object. Those are instances of either "user"
5034                  * and/or "inetOrgPerson". Otherwise continue with the
5035                  * submodules. */
5036                 if ((!ldb_msg_check_string_attribute(ares->message, "objectClass", "user"))
5037                         && (!ldb_msg_check_string_attribute(ares->message, "objectClass", "inetOrgPerson"))) {
5038                         talloc_free(ares);
5039
5040                         if (ldb_msg_find_element(ac->req->op.mod.message, "clearTextPassword") != NULL) {
5041                                 ldb_set_errstring(ldb,
5042                                                   "'clearTextPassword' is only allowed on objects of class 'user' and/or 'inetOrgPerson'!");
5043                                 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
5044                                 goto done;
5045                         }
5046
5047                         ret = ldb_next_request(ac->module, ac->req);
5048                         goto done;
5049                 }
5050
5051                 if (ac->search_res != NULL) {
5052                         talloc_free(ares);
5053
5054                         ldb_set_errstring(ldb, "Too many results");
5055                         ret = LDB_ERR_OPERATIONS_ERROR;
5056                         goto done;
5057                 }
5058
5059                 ac->search_res = talloc_steal(ac, ares);
5060                 ret = LDB_SUCCESS;
5061                 break;
5062
5063         case LDB_REPLY_REFERRAL:
5064                 /* ignore anything else for now */
5065                 talloc_free(ares);
5066                 ret = LDB_SUCCESS;
5067                 break;
5068
5069         case LDB_REPLY_DONE:
5070                 talloc_free(ares);
5071
5072                 /* get user domain data */
5073                 ret = build_domain_data_request(ac);
5074                 if (ret != LDB_SUCCESS) {
5075                         return ldb_module_done(ac->req, NULL, NULL, ret);
5076                 }
5077
5078                 ret = ldb_next_request(ac->module, ac->dom_req);
5079                 break;
5080         }
5081
5082 done:
5083         if (ret != LDB_SUCCESS) {
5084                 return ldb_module_done(ac->req, NULL, NULL, ret);
5085         }
5086
5087         return LDB_SUCCESS;
5088 }
5089
5090 static int password_hash_mod_search_self(struct ph_context *ac)
5091 {
5092         struct ldb_context *ldb;
5093         static const char * const attrs[] = { "objectClass",
5094                                               "userAccountControl",
5095                                               "msDS-ResultantPSO",
5096                                               "msDS-User-Account-Control-Computed",
5097                                               "pwdLastSet",
5098                                               "sAMAccountName",
5099                                               "objectSid",
5100                                               "userPrincipalName",
5101                                               "displayName",
5102                                               "supplementalCredentials",
5103                                               "lmPwdHistory",
5104                                               "ntPwdHistory",
5105                                               "dBCSPwd",
5106                                               "unicodePwd",
5107                                               "badPasswordTime",
5108                                               "badPwdCount",
5109                                               "lockoutTime",
5110                                               "msDS-KeyVersionNumber",
5111                                               "msDS-SecondaryKrbTgtNumber",
5112                                               NULL };
5113         struct ldb_request *search_req;
5114         int ret;
5115
5116         ldb = ldb_module_get_ctx(ac->module);
5117
5118         ret = ldb_build_search_req(&search_req, ldb, ac,
5119                                    ac->req->op.mod.message->dn,
5120                                    LDB_SCOPE_BASE,
5121                                    "(objectclass=*)",
5122                                    attrs,
5123                                    NULL,
5124                                    ac, ph_mod_search_callback,
5125                                    ac->req);
5126         LDB_REQ_SET_LOCATION(search_req);
5127         if (ret != LDB_SUCCESS) {
5128                 return ret;
5129         }
5130
5131         return ldb_next_request(ac->module, search_req);
5132 }
5133
5134 static int password_hash_mod_do_mod(struct ph_context *ac)
5135 {
5136         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
5137         struct ldb_request *mod_req;
5138         struct setup_password_fields_io io;
5139         int ret;
5140
5141         /* Prepare the internal data structure containing the passwords */
5142         ret = setup_io(ac, ac->req->op.mod.message,
5143                        ac->search_res->message, &io);
5144         if (ret != LDB_SUCCESS) {
5145                 return ret;
5146         }
5147
5148         ret = setup_password_fields(&io);
5149         if (ret != LDB_SUCCESS) {
5150                 return ret;
5151         }
5152
5153         ret = check_password_restrictions_and_log(&io);
5154         if (ret != LDB_SUCCESS) {
5155                 return ret;
5156         }
5157
5158         ret = setup_smartcard_reset(&io);
5159         if (ret != LDB_SUCCESS) {
5160                 return ret;
5161         }
5162
5163         ret = update_final_msg(&io);
5164         if (ret != LDB_SUCCESS) {
5165                 return ret;
5166         }
5167
5168         ret = ldb_build_mod_req(&mod_req, ldb, ac,
5169                                 ac->update_msg,
5170                                 ac->req->controls,
5171                                 ac, ph_op_callback,
5172                                 ac->req);
5173         LDB_REQ_SET_LOCATION(mod_req);
5174         if (ret != LDB_SUCCESS) {
5175                 return ret;
5176         }
5177
5178         return ldb_next_request(ac->module, mod_req);
5179 }
5180
5181 static const struct ldb_module_ops ldb_password_hash_module_ops = {
5182         .name          = "password_hash",
5183         .add           = password_hash_add,
5184         .modify        = password_hash_modify
5185 };
5186
5187 int ldb_password_hash_module_init(const char *version)
5188 {
5189 #ifdef ENABLE_GPGME
5190         const char *gversion = NULL;
5191 #endif /* ENABLE_GPGME */
5192
5193         LDB_MODULE_CHECK_VERSION(version);
5194
5195 #ifdef ENABLE_GPGME
5196         /*
5197          * Note: this sets a SIGPIPE handler
5198          * if none is active already. See:
5199          * https://www.gnupg.org/documentation/manuals/gpgme/Signal-Handling.html#Signal-Handling
5200          */
5201         gversion = gpgme_check_version(MINIMUM_GPGME_VERSION);
5202         if (gversion == NULL) {
5203                 fprintf(stderr, "%s() in %s version[%s]: "
5204                         "gpgme_check_version(%s) not available, "
5205                         "gpgme_check_version(NULL) => '%s'\n",
5206                         __func__, __FILE__, version,
5207                         MINIMUM_GPGME_VERSION, gpgme_check_version(NULL));
5208                 return LDB_ERR_UNAVAILABLE;
5209         }
5210 #endif /* ENABLE_GPGME */
5211
5212         return ldb_register_module(&ldb_password_hash_module_ops);
5213 }