s4:dsdb: Remove trailing whitespace
[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 PrimaryKerberosNeverKeys");
543                         }
544
545                         if (k->version != 4) {
546                                 talloc_free(scb);
547                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
548                                                  "KerberosNerverKeys 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_pull_struct_blob_all");
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 found 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 found 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                                                     io->ac->search_res->message,
3168                                                     io->u.userAccountControl,
3169                                                     &request_kvno, /* kvno */
3170                                                     NULL, /* kvno_out */
3171                                                     &db_key_blob,
3172                                                     NULL); /* salt */
3173                 if (krb5_ret == ENOENT) {
3174                         /*
3175                          * If there is no old AES hash (perhaps an imported DB with
3176                          * just unicodePwd) then we just won't have an old
3177                          * password to compare to if there is no NT hash
3178                          */
3179                         break;
3180                 } else if (krb5_ret) {
3181                         ldb_asprintf_errstring(ldb,
3182                                                "check_password_restrictions: "
3183                                                "extraction of old[%u - %d = %d] aes256-cts-hmac-sha1-96 key failed: %s",
3184                                                io->o.kvno, i, io->o.kvno - i,
3185                                                smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
3186                                                                           krb5_ret, io->ac));
3187                         return LDB_ERR_OPERATIONS_ERROR;
3188                 }
3189
3190                 /* This is the actual history check */
3191                 pw_equal = data_blob_equal_const_time(&io->n.aes_256,
3192                                                       &db_key_blob);
3193                 if (pw_equal) {
3194                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3195                         *werror = WERR_PASSWORD_RESTRICTION;
3196                         ldb_asprintf_errstring(ldb,
3197                                                "%08X: %s - check_password_restrictions: "
3198                                                "the password was already used (in history)!",
3199                                                W_ERROR_V(*werror),
3200                                                ldb_strerror(ret));
3201                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3202                         return ret;
3203                 }
3204         }
3205
3206         /* are all password changes disallowed? */
3207         if (io->ac->status->domain_data.pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
3208                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3209                 *werror = WERR_PASSWORD_RESTRICTION;
3210                 ldb_asprintf_errstring(ldb,
3211                         "%08X: %s - check_password_restrictions: "
3212                         "password changes disabled!",
3213                         W_ERROR_V(*werror),
3214                         ldb_strerror(ret));
3215                 return ret;
3216         }
3217
3218         /* can this user change the password? */
3219         if (io->u.userAccountControl & UF_PASSWD_CANT_CHANGE) {
3220                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3221                 *werror = WERR_PASSWORD_RESTRICTION;
3222                 ldb_asprintf_errstring(ldb,
3223                         "%08X: %s - check_password_restrictions: "
3224                         "password can't be changed on this account!",
3225                         W_ERROR_V(*werror),
3226                         ldb_strerror(ret));
3227                 return ret;
3228         }
3229
3230         return LDB_SUCCESS;
3231 }
3232
3233 static int check_password_restrictions_and_log(struct setup_password_fields_io *io)
3234 {
3235         WERROR werror;
3236         int ret = check_password_restrictions(io, &werror);
3237         struct ph_context *ac = io->ac;
3238         /*
3239          * Password resets are not authentication events, and if the
3240          * upper layer checked the password and supplied the hash
3241          * values as proof, then this is also not an authentication
3242          * even at this layer (already logged).  This is to log LDAP
3243          * password changes.
3244          */
3245
3246         /* Do not record a failure in the auth log below in the success case */
3247         if (ret == LDB_SUCCESS) {
3248                 werror = WERR_OK;
3249         }
3250
3251         if (ac->pwd_reset == false && ac->change == NULL) {
3252                 struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3253                 struct imessaging_context *msg_ctx;
3254                 struct loadparm_context *lp_ctx
3255                         = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
3256                                                 struct loadparm_context);
3257                 NTSTATUS status = werror_to_ntstatus(werror);
3258                 const char *domain_name = lpcfg_sam_name(lp_ctx);
3259                 void *opaque_remote_address = NULL;
3260                 /*
3261                  * Forcing this via the NTLM auth structure is not ideal, but
3262                  * it is the most practical option right now, and ensures the
3263                  * logs are consistent, even if some elements are always NULL.
3264                  */
3265                 struct auth_usersupplied_info ui = {
3266                         .was_mapped = true,
3267                         .client = {
3268                                 .account_name = io->u.sAMAccountName,
3269                                 .domain_name = domain_name,
3270                         },
3271                         .mapped = {
3272                                 .account_name = io->u.sAMAccountName,
3273                                 .domain_name = domain_name,
3274                         },
3275                         .service_description = "LDAP Password Change",
3276                         .auth_description = "LDAP Modify",
3277                         .password_type = "plaintext"
3278                 };
3279
3280                 opaque_remote_address = ldb_get_opaque(ldb,
3281                                                        "remoteAddress");
3282                 if (opaque_remote_address == NULL) {
3283                         ldb_asprintf_errstring(ldb,
3284                                                "Failed to obtain remote address for "
3285                                                "the LDAP client while changing the "
3286                                                "password");
3287                         return LDB_ERR_OPERATIONS_ERROR;
3288                 }
3289                 ui.remote_host = talloc_get_type(opaque_remote_address,
3290                                                  struct tsocket_address);
3291
3292                 msg_ctx = imessaging_client_init(ac, lp_ctx,
3293                                                  ldb_get_event_context(ldb));
3294                 if (!msg_ctx) {
3295                         ldb_asprintf_errstring(ldb,
3296                                                "Failed to generate client messaging context in %s",
3297                                                lpcfg_imessaging_path(ac, lp_ctx));
3298                         return LDB_ERR_OPERATIONS_ERROR;
3299                 }
3300                 log_authentication_event(msg_ctx,
3301                                          lp_ctx,
3302                                          NULL,
3303                                          &ui,
3304                                          status,
3305                                          domain_name,
3306                                          io->u.sAMAccountName,
3307                                          io->u.account_sid,
3308                                          NULL /* client_audit_info */,
3309                                          NULL /* server_audit_info */);
3310
3311         }
3312         return ret;
3313 }
3314
3315 static int update_final_msg(struct setup_password_fields_io *io)
3316 {
3317         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
3318         int ret;
3319         int el_flags = 0;
3320         bool update_password = io->ac->update_password;
3321         bool update_scb = io->ac->update_password;
3322
3323         /*
3324          * If we add a user without initial password,
3325          * we need to add replication meta data for
3326          * following attributes:
3327          * - unicodePwd
3328          * - dBCSPwd
3329          * - ntPwdHistory
3330          * - lmPwdHistory
3331          *
3332          * If we add a user with initial password or a
3333          * password is changed of an existing user,
3334          * we need to replace the following attributes
3335          * with a forced meta data update, e.g. also
3336          * when updating an empty attribute with an empty value:
3337          * - unicodePwd
3338          * - dBCSPwd
3339          * - ntPwdHistory
3340          * - lmPwdHistory
3341          * - supplementalCredentials
3342          */
3343
3344         switch (io->ac->req->operation) {
3345         case LDB_ADD:
3346                 update_password = true;
3347                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
3348                 break;
3349         case LDB_MODIFY:
3350                 el_flags |= LDB_FLAG_MOD_REPLACE;
3351                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
3352                 break;
3353         default:
3354                 return ldb_module_operr(io->ac->module);
3355         }
3356
3357         if (update_password) {
3358                 ret = ldb_msg_add_empty(io->ac->update_msg,
3359                                         "unicodePwd",
3360                                         el_flags, NULL);
3361                 if (ret != LDB_SUCCESS) {
3362                         return ret;
3363                 }
3364
3365                 /*
3366                  * This wipes any old LM password after any password
3367                  * update operation.
3368                  *
3369                  * This is the same as the previous default behaviour
3370                  * of 'lanman auth = no'
3371                  */
3372                 ret = ldb_msg_add_empty(io->ac->update_msg,
3373                                         "dBCSPwd",
3374                                         el_flags, NULL);
3375                 if (ret != LDB_SUCCESS) {
3376                         return ret;
3377                 }
3378                 ret = ldb_msg_add_empty(io->ac->update_msg,
3379                                         "ntPwdHistory",
3380                                         el_flags, NULL);
3381                 if (ret != LDB_SUCCESS) {
3382                         return ret;
3383                 }
3384                 /*
3385                  * This wipes any LM password history after any password
3386                  * update operation.
3387                  *
3388                  * This is the same as the previous default behaviour
3389                  * of 'lanman auth = no'
3390                  */
3391                 ret = ldb_msg_add_empty(io->ac->update_msg,
3392                                         "lmPwdHistory",
3393                                         el_flags, NULL);
3394                 if (ret != LDB_SUCCESS) {
3395                         return ret;
3396                 }
3397         }
3398         if (update_scb) {
3399                 ret = ldb_msg_add_empty(io->ac->update_msg,
3400                                         "supplementalCredentials",
3401                                         el_flags, NULL);
3402                 if (ret != LDB_SUCCESS) {
3403                         return ret;
3404                 }
3405         }
3406         if (io->ac->update_lastset) {
3407                 ret = ldb_msg_add_empty(io->ac->update_msg,
3408                                         "pwdLastSet",
3409                                         el_flags, NULL);
3410                 if (ret != LDB_SUCCESS) {
3411                         return ret;
3412                 }
3413         }
3414
3415         if (io->g.nt_hash != NULL) {
3416                 ret = samdb_msg_add_hash(ldb, io->ac,
3417                                          io->ac->update_msg,
3418                                          "unicodePwd",
3419                                          io->g.nt_hash);
3420                 if (ret != LDB_SUCCESS) {
3421                         return ret;
3422                 }
3423         }
3424
3425         if (io->g.nt_history_len > 0) {
3426                 ret = samdb_msg_add_hashes(ldb, io->ac,
3427                                            io->ac->update_msg,
3428                                            "ntPwdHistory",
3429                                            io->g.nt_history,
3430                                            io->g.nt_history_len);
3431                 if (ret != LDB_SUCCESS) {
3432                         return ret;
3433                 }
3434         }
3435         if (io->g.supplemental.length > 0) {
3436                 ret = ldb_msg_add_value(io->ac->update_msg,
3437                                         "supplementalCredentials",
3438                                         &io->g.supplemental, NULL);
3439                 if (ret != LDB_SUCCESS) {
3440                         return ret;
3441                 }
3442         }
3443         if (io->ac->update_lastset) {
3444                 ret = samdb_msg_add_uint64(ldb, io->ac,
3445                                            io->ac->update_msg,
3446                                            "pwdLastSet",
3447                                            io->g.last_set);
3448                 if (ret != LDB_SUCCESS) {
3449                         return ret;
3450                 }
3451         }
3452
3453         return LDB_SUCCESS;
3454 }
3455
3456 /*
3457  * This is intended for use by the "password_hash" module since there
3458  * password changes can be specified through one message element with the
3459  * new password (to set) and another one with the old password (to unset).
3460  *
3461  * The first which sets a password (new value) can have flags
3462  * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
3463  * for entries). The latter (old value) has always specified
3464  * LDB_FLAG_MOD_DELETE.
3465  *
3466  * Returns LDB_ERR_CONSTRAINT_VIOLATION and LDB_ERR_UNWILLING_TO_PERFORM if
3467  * matching message elements are malformed in respect to the set/change rules.
3468  * Otherwise it returns LDB_SUCCESS.
3469  */
3470 static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
3471                                         const char *name,
3472                                         enum ldb_request_type operation,
3473                                         const struct ldb_val **new_val,
3474                                         const struct ldb_val **old_val)
3475 {
3476         unsigned int i;
3477
3478         *new_val = NULL;
3479         *old_val = NULL;
3480
3481         if (msg == NULL) {
3482                 return LDB_SUCCESS;
3483         }
3484
3485         for (i = 0; i < msg->num_elements; i++) {
3486                 if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
3487                         continue;
3488                 }
3489
3490                 if ((operation == LDB_MODIFY) &&
3491                     (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE)) {
3492                         /* 0 values are allowed */
3493                         if (msg->elements[i].num_values == 1) {
3494                                 *old_val = &msg->elements[i].values[0];
3495                         } else if (msg->elements[i].num_values > 1) {
3496                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3497                         }
3498                 } else if ((operation == LDB_MODIFY) &&
3499                            (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE)) {
3500                         if (msg->elements[i].num_values > 0) {
3501                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3502                         } else {
3503                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3504                         }
3505                 } else {
3506                         /* Add operations and LDB_FLAG_MOD_ADD */
3507                         if (msg->elements[i].num_values > 0) {
3508                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3509                         } else {
3510                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3511                         }
3512                 }
3513         }
3514
3515         return LDB_SUCCESS;
3516 }
3517
3518 static int setup_io(struct ph_context *ac,
3519                     const struct ldb_message *client_msg,
3520                     const struct ldb_message *existing_msg,
3521                     struct setup_password_fields_io *io)
3522 {
3523         const struct ldb_val *quoted_utf16, *old_quoted_utf16, *lm_hash, *old_lm_hash;
3524         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3525         struct loadparm_context *lp_ctx = talloc_get_type(
3526                 ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
3527         enum store_nt_hash store_hash_setting =
3528                 lpcfg_nt_hash_store(lp_ctx);
3529         int ret;
3530         const struct ldb_message *info_msg = NULL;
3531         struct dom_sid *account_sid = NULL;
3532         int rodc_krbtgt = 0;
3533
3534         *io = (struct setup_password_fields_io) {};
3535
3536         /* Some operations below require kerberos contexts */
3537
3538         if (existing_msg != NULL) {
3539                 /*
3540                  * This is a modify operation
3541                  */
3542                 info_msg = existing_msg;
3543         } else {
3544                 /*
3545                  * This is an add operation
3546                  */
3547                 info_msg = client_msg;
3548         }
3549
3550         ret = smb_krb5_init_context(ac,
3551                                   (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
3552                                   &io->smb_krb5_context);
3553
3554         if (ret != 0) {
3555                 /*
3556                  * In the special case of mit krb5.conf vs heimdal, the includedir
3557                  * statement causes ret == 22 (KRB5_CONFIG_BADFORMAT) to be returned.
3558                  * We look for this case so that we can give a more instructional
3559                  * message to the administrator.
3560                  */
3561                 if (ret == KRB5_CONFIG_BADFORMAT || ret == EINVAL) {
3562                         ldb_asprintf_errstring(ldb, "Failed to setup krb5_context: %s - "
3563                                 "This could be due to an invalid krb5 configuration. "
3564                                 "Please check your system's krb5 configuration is correct.",
3565                                 error_message(ret));
3566                 } else {
3567                         ldb_asprintf_errstring(ldb, "Failed to setup krb5_context: %s",
3568                                 error_message(ret));
3569                 }
3570                 return LDB_ERR_OPERATIONS_ERROR;
3571         }
3572
3573         io->ac                          = ac;
3574
3575         io->u.userAccountControl        = ldb_msg_find_attr_as_uint(info_msg,
3576                                                                     "userAccountControl", 0);
3577         if (info_msg == existing_msg) {
3578                 /*
3579                  * We only take pwdLastSet from the existing object
3580                  * otherwise we leave it as 0.
3581                  *
3582                  * If no attribute is available, e.g. on deleted objects
3583                  * we remember that as UINT64_MAX.
3584                  */
3585                 io->u.pwdLastSet = samdb_result_nttime(info_msg, "pwdLastSet",
3586                                                        UINT64_MAX);
3587         }
3588         io->u.sAMAccountName            = ldb_msg_find_attr_as_string(info_msg,
3589                                                                       "sAMAccountName", NULL);
3590         io->u.user_principal_name       = ldb_msg_find_attr_as_string(info_msg,
3591                                                                       "userPrincipalName", NULL);
3592         io->u.displayName               = ldb_msg_find_attr_as_string(info_msg,
3593                                                                       "displayName", NULL);
3594
3595         /* Ensure it has an objectSID too */
3596         io->u.account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
3597         if (io->u.account_sid != NULL) {
3598                 NTSTATUS status;
3599                 uint32_t rid = 0;
3600
3601                 status = dom_sid_split_rid(account_sid, io->u.account_sid, NULL, &rid);
3602                 if (NT_STATUS_IS_OK(status)) {
3603                         if (rid == DOMAIN_RID_KRBTGT) {
3604                                 io->u.is_krbtgt = true;
3605                         }
3606                 }
3607         }
3608
3609         rodc_krbtgt = ldb_msg_find_attr_as_int(info_msg,
3610                         "msDS-SecondaryKrbTgtNumber", 0);
3611         if (rodc_krbtgt != 0) {
3612                 io->u.is_krbtgt = true;
3613         }
3614
3615         if (io->u.sAMAccountName == NULL) {
3616                 ldb_asprintf_errstring(ldb,
3617                                        "setup_io: sAMAccountName attribute is missing on %s for attempted password set/change",
3618                                        ldb_dn_get_linearized(info_msg->dn));
3619
3620                 return LDB_ERR_CONSTRAINT_VIOLATION;
3621         }
3622
3623         if (io->u.userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
3624                 struct ldb_control *permit_trust = ldb_request_get_control(ac->req,
3625                                 DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
3626
3627                 if (permit_trust == NULL) {
3628                         ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
3629                         ldb_asprintf_errstring(ldb,
3630                                 "%08X: %s - setup_io: changing the interdomain trust password "
3631                                 "on %s not allowed via LDAP. Use LSA or NETLOGON",
3632                                 W_ERROR_V(WERR_ACCESS_DENIED),
3633                                 ldb_strerror(ret),
3634                                 ldb_dn_get_linearized(info_msg->dn));
3635                         return ret;
3636                 }
3637         }
3638
3639         /* Only non-trust accounts have restrictions (possibly this test is the
3640          * wrong way around, but we like to be restrictive if possible */
3641         io->u.restrictions = !(io->u.userAccountControl & UF_TRUST_ACCOUNT_MASK);
3642
3643         if (io->u.is_krbtgt) {
3644                 io->u.restrictions = 0;
3645                 io->ac->status->domain_data.pwdHistoryLength =
3646                         MAX(io->ac->status->domain_data.pwdHistoryLength, 3);
3647         }
3648
3649         /*
3650          * Machine accounts need the NT hash to operate the NETLOGON
3651          * ServerAuthenticate{,2,3} logic
3652          */
3653         if (!(io->u.userAccountControl & UF_NORMAL_ACCOUNT)) {
3654                 store_hash_setting = NT_HASH_STORE_ALWAYS;
3655         }
3656
3657         switch (store_hash_setting) {
3658         case NT_HASH_STORE_ALWAYS:
3659                 io->u.store_nt_hash = true;
3660                 break;
3661         case NT_HASH_STORE_NEVER:
3662                 io->u.store_nt_hash = false;
3663                 break;
3664         case NT_HASH_STORE_AUTO:
3665                 if (lpcfg_ntlm_auth(lp_ctx) == NTLM_AUTH_DISABLED) {
3666                         io->u.store_nt_hash = false;
3667                         break;
3668                 }
3669                 io->u.store_nt_hash = true;
3670                 break;
3671         }
3672
3673         if (ac->userPassword) {
3674                 ret = msg_find_old_and_new_pwd_val(client_msg, "userPassword",
3675                                                    ac->req->operation,
3676                                                    &io->n.cleartext_utf8,
3677                                                    &io->og.cleartext_utf8);
3678                 if (ret != LDB_SUCCESS) {
3679                         ldb_asprintf_errstring(ldb,
3680                                 "setup_io: "
3681                                 "it's only allowed to set the old password once!");
3682                         return ret;
3683                 }
3684         }
3685
3686         if (io->n.cleartext_utf8 != NULL) {
3687                 struct ldb_val *cleartext_utf8_blob;
3688                 char *p;
3689
3690                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
3691                 if (!cleartext_utf8_blob) {
3692                         return ldb_oom(ldb);
3693                 }
3694
3695                 *cleartext_utf8_blob = *io->n.cleartext_utf8;
3696
3697                 /* make sure we have a null terminated string */
3698                 p = talloc_strndup(cleartext_utf8_blob,
3699                                    (const char *)io->n.cleartext_utf8->data,
3700                                    io->n.cleartext_utf8->length);
3701                 if ((p == NULL) && (io->n.cleartext_utf8->length > 0)) {
3702                         return ldb_oom(ldb);
3703                 }
3704                 cleartext_utf8_blob->data = (uint8_t *)p;
3705
3706                 io->n.cleartext_utf8 = cleartext_utf8_blob;
3707         }
3708
3709         ret = msg_find_old_and_new_pwd_val(client_msg, "clearTextPassword",
3710                                            ac->req->operation,
3711                                            &io->n.cleartext_utf16,
3712                                            &io->og.cleartext_utf16);
3713         if (ret != LDB_SUCCESS) {
3714                 ldb_asprintf_errstring(ldb,
3715                         "setup_io: "
3716                         "it's only allowed to set the old password once!");
3717                 return ret;
3718         }
3719
3720         /* this rather strange looking piece of code is there to
3721            handle a ldap client setting a password remotely using the
3722            unicodePwd ldap field. The syntax is that the password is
3723            in UTF-16LE, with a " at either end. Unfortunately the
3724            unicodePwd field is also used to store the nt hashes
3725            internally in Samba, and is used in the nt hash format on
3726            the wire in DRS replication, so we have a single name for
3727            two distinct values. The code below leaves us with a small
3728            chance (less than 1 in 2^32) of a mixup, if someone manages
3729            to create a MD4 hash which starts and ends in 0x22 0x00, as
3730            that would then be treated as a UTF16 password rather than
3731            a nthash */
3732
3733         ret = msg_find_old_and_new_pwd_val(client_msg, "unicodePwd",
3734                                            ac->req->operation,
3735                                            &quoted_utf16,
3736                                            &old_quoted_utf16);
3737         if (ret != LDB_SUCCESS) {
3738                 ldb_asprintf_errstring(ldb,
3739                         "setup_io: "
3740                         "it's only allowed to set the old password once!");
3741                 return ret;
3742         }
3743
3744         /* Checks and converts the actual "unicodePwd" attribute */
3745         if (!ac->hash_values &&
3746             quoted_utf16 &&
3747             quoted_utf16->length >= 4 &&
3748             quoted_utf16->data[0] == '"' &&
3749             quoted_utf16->data[1] == 0 &&
3750             quoted_utf16->data[quoted_utf16->length-2] == '"' &&
3751             quoted_utf16->data[quoted_utf16->length-1] == 0) {
3752                 struct ldb_val *quoted_utf16_2;
3753
3754                 if (io->n.cleartext_utf16) {
3755                         /* refuse the change if someone wants to change with
3756                            with both UTF16 possibilities at the same time... */
3757                         ldb_asprintf_errstring(ldb,
3758                                 "setup_io: "
3759                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3760                         return LDB_ERR_UNWILLING_TO_PERFORM;
3761                 }
3762
3763                 /*
3764                  * adapt the quoted UTF16 string to be a real
3765                  * cleartext one
3766                  */
3767                 quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3768                 if (quoted_utf16_2 == NULL) {
3769                         return ldb_oom(ldb);
3770                 }
3771
3772                 quoted_utf16_2->data = quoted_utf16->data + 2;
3773                 quoted_utf16_2->length = quoted_utf16->length-4;
3774                 io->n.cleartext_utf16 = quoted_utf16_2;
3775                 io->n.nt_hash = NULL;
3776
3777         } else if (quoted_utf16) {
3778                 /* We have only the hash available -> so no plaintext here */
3779                 if (!ac->hash_values) {
3780                         /* refuse the change if someone wants to change
3781                            the hash without control specified... */
3782                         ldb_asprintf_errstring(ldb,
3783                                 "setup_io: "
3784                                 "it's not allowed to set the NT hash password directly'");
3785                         /* this looks odd but this is what Windows does:
3786                            returns "UNWILLING_TO_PERFORM" on wrong
3787                            password sets and "CONSTRAINT_VIOLATION" on
3788                            wrong password changes. */
3789                         if (old_quoted_utf16 == NULL) {
3790                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3791                         }
3792
3793                         return LDB_ERR_CONSTRAINT_VIOLATION;
3794                 }
3795
3796                 io->n.nt_hash = talloc(io->ac, struct samr_Password);
3797                 if (io->n.nt_hash == NULL) {
3798                         return ldb_oom(ldb);
3799                 }
3800                 memcpy(io->n.nt_hash->hash, quoted_utf16->data,
3801                        MIN(quoted_utf16->length, sizeof(io->n.nt_hash->hash)));
3802         }
3803
3804         /* Checks and converts the previous "unicodePwd" attribute */
3805         if (!ac->hash_values &&
3806             old_quoted_utf16 &&
3807             old_quoted_utf16->length >= 4 &&
3808             old_quoted_utf16->data[0] == '"' &&
3809             old_quoted_utf16->data[1] == 0 &&
3810             old_quoted_utf16->data[old_quoted_utf16->length-2] == '"' &&
3811             old_quoted_utf16->data[old_quoted_utf16->length-1] == 0) {
3812                 struct ldb_val *old_quoted_utf16_2;
3813
3814                 if (io->og.cleartext_utf16) {
3815                         /* refuse the change if someone wants to change with
3816                            both UTF16 possibilities at the same time... */
3817                         ldb_asprintf_errstring(ldb,
3818                                 "setup_io: "
3819                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3820                         return LDB_ERR_UNWILLING_TO_PERFORM;
3821                 }
3822
3823                 /*
3824                  * adapt the quoted UTF16 string to be a real
3825                  * cleartext one
3826                  */
3827                 old_quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3828                 if (old_quoted_utf16_2 == NULL) {
3829                         return ldb_oom(ldb);
3830                 }
3831
3832                 old_quoted_utf16_2->data = old_quoted_utf16->data + 2;
3833                 old_quoted_utf16_2->length = old_quoted_utf16->length-4;
3834
3835                 io->og.cleartext_utf16 = old_quoted_utf16_2;
3836                 io->og.nt_hash = NULL;
3837         } else if (old_quoted_utf16) {
3838                 /* We have only the hash available -> so no plaintext here */
3839                 if (!ac->hash_values) {
3840                         /* refuse the change if someone wants to change
3841                            the hash without control specified... */
3842                         ldb_asprintf_errstring(ldb,
3843                                 "setup_io: "
3844                                 "it's not allowed to set the NT hash password directly'");
3845                         return LDB_ERR_UNWILLING_TO_PERFORM;
3846                 }
3847
3848                 io->og.nt_hash = talloc(io->ac, struct samr_Password);
3849                 if (io->og.nt_hash == NULL) {
3850                         return ldb_oom(ldb);
3851                 }
3852                 memcpy(io->og.nt_hash->hash, old_quoted_utf16->data,
3853                        MIN(old_quoted_utf16->length, sizeof(io->og.nt_hash->hash)));
3854         }
3855
3856         /* Handles the "dBCSPwd" attribute (LM hash) */
3857         ret = msg_find_old_and_new_pwd_val(client_msg, "dBCSPwd",
3858                                            ac->req->operation,
3859                                            &lm_hash, &old_lm_hash);
3860         if (ret != LDB_SUCCESS) {
3861                 ldb_asprintf_errstring(ldb,
3862                         "setup_io: "
3863                         "it's only allowed to set the old password once!");
3864                 return ret;
3865         }
3866
3867         if (((lm_hash != NULL) || (old_lm_hash != NULL))) {
3868                 /* refuse the change if someone wants to change the LM hash */
3869                 ldb_asprintf_errstring(ldb,
3870                         "setup_io: "
3871                         "it's not allowed to set the LM hash password (dBCSPwd)'");
3872                 return LDB_ERR_UNWILLING_TO_PERFORM;
3873         }
3874
3875         /*
3876          * Handles the password change control if it's specified. It has the
3877          * precedence and overrides already specified old password values of
3878          * change requests (but that shouldn't happen since the control is
3879          * fully internal and only used in conjunction with replace requests!).
3880          */
3881         if (ac->change != NULL) {
3882                 io->og.nt_hash = NULL;
3883         }
3884
3885         /* refuse the change if someone wants to change the clear-
3886            text and supply his own hashes at the same time... */
3887         if ((io->n.cleartext_utf8 || io->n.cleartext_utf16)
3888                         && (io->n.nt_hash)) {
3889                 ldb_asprintf_errstring(ldb,
3890                         "setup_io: "
3891                         "it's only allowed to set the password in form of cleartext attributes or as hashes");
3892                 return LDB_ERR_UNWILLING_TO_PERFORM;
3893         }
3894
3895         /* refuse the change if someone wants to change the password
3896            using both plaintext methods (UTF8 and UTF16) at the same time... */
3897         if (io->n.cleartext_utf8 && io->n.cleartext_utf16) {
3898                 ldb_asprintf_errstring(ldb,
3899                         "setup_io: "
3900                         "it's only allowed to set the cleartext password as 'unicodePwd' or as 'userPassword' or as 'clearTextPassword'");
3901                 return LDB_ERR_UNWILLING_TO_PERFORM;
3902         }
3903
3904         /* refuse the change if someone tries to set/change the password by
3905          * any method that would leave us without a password! */
3906         if (io->ac->update_password
3907             && (!io->n.cleartext_utf8) && (!io->n.cleartext_utf16)
3908             && (!io->n.nt_hash)) {
3909                 ldb_asprintf_errstring(ldb,
3910                         "setup_io: "
3911                         "It's not possible to delete the password (changes using the LAN Manager hash alone could be deactivated)!");
3912                 /* on "userPassword" and "clearTextPassword" we've to return
3913                  * something different, since these are virtual attributes */
3914                 if ((ldb_msg_find_element(client_msg, "userPassword") != NULL) ||
3915                     (ldb_msg_find_element(client_msg, "clearTextPassword") != NULL)) {
3916                         return LDB_ERR_CONSTRAINT_VIOLATION;
3917                 }
3918                 return LDB_ERR_UNWILLING_TO_PERFORM;
3919         }
3920
3921         /*
3922          * refuse the change if someone wants to compare against a
3923          * plaintext or dsdb_control_password_change at the same time
3924          * for a "password modify" operation...
3925          */
3926         if ((io->og.cleartext_utf8 || io->og.cleartext_utf16)
3927             && ac->change) {
3928                 ldb_asprintf_errstring(ldb,
3929                         "setup_io: "
3930                         "it's only allowed to provide the old password in form of cleartext attributes or as the dsdb_control_password_change");
3931                 return LDB_ERR_UNWILLING_TO_PERFORM;
3932         }
3933
3934         /* refuse the change if someone wants to compare against both
3935          * plaintexts at the same time for a "password modify" operation... */
3936         if (io->og.cleartext_utf8 && io->og.cleartext_utf16) {
3937                 ldb_asprintf_errstring(ldb,
3938                         "setup_io: "
3939                         "it's only allowed to provide the old cleartext password as 'unicodePwd' or as 'userPassword' or as 'clearTextPassword'");
3940                 return LDB_ERR_UNWILLING_TO_PERFORM;
3941         }
3942
3943         /* Decides if we have a password modify or password reset operation */
3944         if (ac->req->operation == LDB_ADD) {
3945                 /* On "add" we have only "password reset" */
3946                 ac->pwd_reset = true;
3947         } else if (ac->req->operation == LDB_MODIFY) {
3948                 struct ldb_control *pav_ctrl = NULL;
3949                 struct dsdb_control_password_acl_validation *pav = NULL;
3950
3951                 pav_ctrl = ldb_request_get_control(ac->req,
3952                                 DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID);
3953                 if (pav_ctrl != NULL) {
3954                         pav = talloc_get_type_abort(pav_ctrl->data,
3955                                 struct dsdb_control_password_acl_validation);
3956                 }
3957
3958                 if (pav == NULL && ac->update_password) {
3959                         bool ok;
3960
3961                         /*
3962                          * If the DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID
3963                          * control is missing, we require system access!
3964                          */
3965                         ok = dsdb_module_am_system(ac->module);
3966                         if (!ok) {
3967                                 return ldb_module_operr(ac->module);
3968                         }
3969                 }
3970
3971                 if (pav != NULL) {
3972                         /*
3973                          * We assume what the acl module has validated.
3974                          */
3975                         ac->pwd_reset = pav->pwd_reset;
3976                 } else if (io->og.cleartext_utf8 || io->og.cleartext_utf16
3977                     || ac->change) {
3978                         /*
3979                          * If we have an old password specified or the
3980                          * dsdb_control_password_change then for sure
3981                          * it is a user "password change"
3982                          */
3983                         ac->pwd_reset = false;
3984                 } else {
3985                         /* Otherwise we have also here a "password reset" */
3986                         ac->pwd_reset = true;
3987                 }
3988         } else {
3989                 /* this shouldn't happen */
3990                 return ldb_operr(ldb);
3991         }
3992
3993         if (existing_msg != NULL) {
3994                 NTSTATUS status;
3995                 krb5_error_code krb5_ret;
3996                 DATA_BLOB key_blob;
3997                 DATA_BLOB salt_blob;
3998                 uint32_t kvno;
3999
4000                 if (ac->pwd_reset) {
4001                         /* Get the old password from the database */
4002                         status = samdb_result_passwords_no_lockout(ac,
4003                                                                    lp_ctx,
4004                                                                    existing_msg,
4005                                                                    &io->o.nt_hash);
4006                 } else {
4007                         /* Get the old password from the database */
4008                         status = samdb_result_passwords(ac,
4009                                                         lp_ctx,
4010                                                         existing_msg,
4011                                                         &io->o.nt_hash);
4012                 }
4013
4014                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_LOCKED_OUT)) {
4015                         return dsdb_module_werror(ac->module,
4016                                                   LDB_ERR_CONSTRAINT_VIOLATION,
4017                                                   WERR_ACCOUNT_LOCKED_OUT,
4018                                                   "Password change not permitted,"
4019                                                   " account locked out!");
4020                 }
4021
4022                 if (!NT_STATUS_IS_OK(status)) {
4023                         /*
4024                          * This only happens if the database has gone weird,
4025                          * not if we are just missing the passwords
4026                          */
4027                         return ldb_operr(ldb);
4028                 }
4029
4030                 io->o.nt_history_len = samdb_result_hashes(ac, existing_msg,
4031                                                            "ntPwdHistory",
4032                                                            &io->o.nt_history);
4033                 io->o.supplemental = ldb_msg_find_ldb_val(existing_msg,
4034                                                           "supplementalCredentials");
4035
4036                 if (io->o.supplemental != NULL) {
4037                         enum ndr_err_code ndr_err;
4038
4039                         ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac,
4040                                         &io->o.scb,
4041                                         (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
4042                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4043                                 status = ndr_map_error2ntstatus(ndr_err);
4044                                 ldb_asprintf_errstring(ldb,
4045                                                 "setup_io: failed to pull "
4046                                                 "old supplementalCredentialsBlob: %s",
4047                                                 nt_errstr(status));
4048                                 return LDB_ERR_OPERATIONS_ERROR;
4049                         }
4050                 }
4051
4052                 /*
4053                  * If this account requires a smartcard for login, we don't
4054                  * attempt a comparison with the old password.
4055                  */
4056                 if (io->u.userAccountControl & UF_SMARTCARD_REQUIRED) {
4057                         return LDB_SUCCESS;
4058                 }
4059
4060                 /*
4061                  * Extract the old ENCTYPE_AES256_CTS_HMAC_SHA1_96
4062                  * value from the supplementalCredentials.
4063                  */
4064                 krb5_ret = dsdb_extract_aes_256_key(io->smb_krb5_context->krb5_context,
4065                                                     io->ac,
4066                                                     existing_msg,
4067                                                     io->u.userAccountControl,
4068                                                     NULL, /* kvno */
4069                                                     &kvno, /* kvno_out */
4070                                                     &key_blob,
4071                                                     &salt_blob);
4072                 if (krb5_ret == ENOENT) {
4073                         /*
4074                          * If there is no old AES hash (perhaps an imported DB with
4075                          * just unicodePwd) then we just won't have an old
4076                          * password to compare to if there is no NT hash
4077                          */
4078                         return LDB_SUCCESS;
4079                 }
4080                 if (krb5_ret) {
4081                         ldb_asprintf_errstring(ldb,
4082                                                "setup_io: "
4083                                                "extraction of salt for old aes256-cts-hmac-sha1-96 key failed: %s",
4084                                                smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
4085                                                                           krb5_ret, io->ac));
4086                         return LDB_ERR_OPERATIONS_ERROR;
4087                 }
4088
4089                 io->o.salt = salt_blob;
4090                 io->o.aes_256 = key_blob;
4091                 io->o.kvno = kvno;
4092         }
4093
4094         return LDB_SUCCESS;
4095 }
4096
4097 static struct ph_context *ph_init_context(struct ldb_module *module,
4098                                           struct ldb_request *req,
4099                                           bool userPassword,
4100                                           bool update_password)
4101 {
4102         struct ldb_context *ldb;
4103         struct ph_context *ac;
4104         struct loadparm_context *lp_ctx = NULL;
4105
4106         ldb = ldb_module_get_ctx(module);
4107
4108         ac = talloc_zero(req, struct ph_context);
4109         if (ac == NULL) {
4110                 ldb_set_errstring(ldb, "Out of Memory");
4111                 return NULL;
4112         }
4113
4114         ac->module = module;
4115         ac->req = req;
4116         ac->userPassword = userPassword;
4117         ac->update_password = update_password;
4118         ac->update_lastset = true;
4119
4120         lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
4121                                        struct loadparm_context);
4122         ac->gpg_key_ids = lpcfg_password_hash_gpg_key_ids(lp_ctx);
4123         ac->userPassword_schemes
4124                 = lpcfg_password_hash_userpassword_schemes(lp_ctx);
4125         return ac;
4126 }
4127
4128 static void ph_apply_controls(struct ph_context *ac)
4129 {
4130         struct ldb_control *ctrl;
4131
4132         ac->change_status = false;
4133         ctrl = ldb_request_get_control(ac->req,
4134                                        DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID);
4135         if (ctrl != NULL) {
4136                 ac->change_status = true;
4137
4138                 /* Mark the "change status" control as uncritical (done) */
4139                 ctrl->critical = false;
4140         }
4141
4142         ac->hash_values = false;
4143         ctrl = ldb_request_get_control(ac->req,
4144                                        DSDB_CONTROL_PASSWORD_HASH_VALUES_OID);
4145         if (ctrl != NULL) {
4146                 ac->hash_values = true;
4147
4148                 /* Mark the "hash values" control as uncritical (done) */
4149                 ctrl->critical = false;
4150         }
4151
4152         ctrl = ldb_request_get_control(ac->req,
4153                                        DSDB_CONTROL_PASSWORD_CHANGE_OLD_PW_CHECKED_OID);
4154         if (ctrl != NULL) {
4155                 ac->change = talloc_get_type_abort(ctrl->data, struct dsdb_control_password_change);
4156
4157                 /* Mark the "change" control as uncritical (done) */
4158                 ctrl->critical = false;
4159         }
4160
4161         ac->pwd_last_set_bypass = false;
4162         ctrl = ldb_request_get_control(ac->req,
4163                                 DSDB_CONTROL_PASSWORD_BYPASS_LAST_SET_OID);
4164         if (ctrl != NULL) {
4165                 ac->pwd_last_set_bypass = true;
4166
4167                 /* Mark the "bypass pwdLastSet" control as uncritical (done) */
4168                 ctrl->critical = false;
4169         }
4170
4171         ac->pwd_last_set_default = false;
4172         ctrl = ldb_request_get_control(ac->req,
4173                                 DSDB_CONTROL_PASSWORD_DEFAULT_LAST_SET_OID);
4174         if (ctrl != NULL) {
4175                 ac->pwd_last_set_default = true;
4176
4177                 /* Mark the "bypass pwdLastSet" control as uncritical (done) */
4178                 ctrl->critical = false;
4179         }
4180
4181         ac->smartcard_reset = false;
4182         ctrl = ldb_request_get_control(ac->req,
4183                                 DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID);
4184         if (ctrl != NULL) {
4185                 struct dsdb_control_password_user_account_control *uac = NULL;
4186                 uint32_t added_flags = 0;
4187
4188                 uac = talloc_get_type_abort(ctrl->data,
4189                         struct dsdb_control_password_user_account_control);
4190
4191                 added_flags = uac->new_flags & ~uac->old_flags;
4192
4193                 if (added_flags & UF_SMARTCARD_REQUIRED) {
4194                         ac->smartcard_reset = true;
4195                 }
4196
4197                 /* Mark the "smartcard required" control as uncritical (done) */
4198                 ctrl->critical = false;
4199         }
4200 }
4201
4202 static int ph_op_callback(struct ldb_request *req, struct ldb_reply *ares)
4203 {
4204         struct ph_context *ac;
4205
4206         ac = talloc_get_type(req->context, struct ph_context);
4207
4208         if (!ares) {
4209                 return ldb_module_done(ac->req, NULL, NULL,
4210                                         LDB_ERR_OPERATIONS_ERROR);
4211         }
4212
4213         if (ares->type == LDB_REPLY_REFERRAL) {
4214                 return ldb_module_send_referral(ac->req, ares->referral);
4215         }
4216
4217         if ((ares->error != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
4218                 /* On success and trivial errors a status control is being
4219                  * added (used for example by the "samdb_set_password" call) */
4220                 ldb_reply_add_control(ares,
4221                                       DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
4222                                       false,
4223                                       ac->status);
4224         }
4225
4226         if (ares->error != LDB_SUCCESS) {
4227                 return ldb_module_done(ac->req, ares->controls,
4228                                         ares->response, ares->error);
4229         }
4230
4231         if (ares->type != LDB_REPLY_DONE) {
4232                 talloc_free(ares);
4233                 return ldb_module_done(ac->req, NULL, NULL,
4234                                         LDB_ERR_OPERATIONS_ERROR);
4235         }
4236
4237         return ldb_module_done(ac->req, ares->controls,
4238                                 ares->response, ares->error);
4239 }
4240
4241 static int password_hash_add_do_add(struct ph_context *ac);
4242 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares);
4243 static int password_hash_mod_search_self(struct ph_context *ac);
4244 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares);
4245 static int password_hash_mod_do_mod(struct ph_context *ac);
4246
4247 /*
4248  * LDB callback handler for searching for a user's PSO. Once we have all the
4249  * Password Settings that apply to the user, we can continue with the modify
4250  * operation
4251  */
4252 static int get_pso_data_callback(struct ldb_request *req,
4253                                  struct ldb_reply *ares)
4254 {
4255         struct ldb_context *ldb = NULL;
4256         struct ph_context *ac = NULL;
4257         bool domain_complexity = true;
4258         bool pso_complexity = true;
4259         struct dsdb_user_pwd_settings *settings = NULL;
4260         int ret = LDB_SUCCESS;
4261
4262         ac = talloc_get_type(req->context, struct ph_context);
4263         ldb = ldb_module_get_ctx(ac->module);
4264
4265         if (!ares) {
4266                 ret = LDB_ERR_OPERATIONS_ERROR;
4267                 goto done;
4268         }
4269         if (ares->error != LDB_SUCCESS) {
4270                 return ldb_module_done(ac->req, ares->controls,
4271                                        ares->response, ares->error);
4272         }
4273
4274         switch (ares->type) {
4275         case LDB_REPLY_ENTRY:
4276
4277                 /* check status was initialized by the domain query */
4278                 if (ac->status == NULL) {
4279                         talloc_free(ares);
4280                         ldb_set_errstring(ldb, "Uninitialized status");
4281                         ret = LDB_ERR_OPERATIONS_ERROR;
4282                         goto done;
4283                 }
4284
4285                 /*
4286                  * use the PSO's values instead of the domain defaults (the PSO
4287                  * attributes should always exist, but use the domain default
4288                  * values as a fallback).
4289                  */
4290                 settings = &ac->status->domain_data;
4291                 settings->store_cleartext =
4292                         ldb_msg_find_attr_as_bool(ares->message,
4293                                                   "msDS-PasswordReversibleEncryptionEnabled",
4294                                                   settings->store_cleartext);
4295
4296                 settings->pwdHistoryLength =
4297                         ldb_msg_find_attr_as_uint(ares->message,
4298                                                   "msDS-PasswordHistoryLength",
4299                                                   settings->pwdHistoryLength);
4300                 settings->maxPwdAge =
4301                         ldb_msg_find_attr_as_int64(ares->message,
4302                                                    "msDS-MaximumPasswordAge",
4303                                                    settings->maxPwdAge);
4304                 settings->minPwdAge =
4305                         ldb_msg_find_attr_as_int64(ares->message,
4306                                                    "msDS-MinimumPasswordAge",
4307                                                    settings->minPwdAge);
4308                 settings->minPwdLength =
4309                         ldb_msg_find_attr_as_uint(ares->message,
4310                                                   "msDS-MinimumPasswordLength",
4311                                                   settings->minPwdLength);
4312                 domain_complexity =
4313                         (settings->pwdProperties & DOMAIN_PASSWORD_COMPLEX);
4314                 pso_complexity =
4315                         ldb_msg_find_attr_as_bool(ares->message,
4316                                                   "msDS-PasswordComplexityEnabled",
4317                                                    domain_complexity);
4318
4319                 /* set or clear the complexity bit if required */
4320                 if (pso_complexity && !domain_complexity) {
4321                         settings->pwdProperties |= DOMAIN_PASSWORD_COMPLEX;
4322                 } else if (domain_complexity && !pso_complexity) {
4323                         settings->pwdProperties &= ~DOMAIN_PASSWORD_COMPLEX;
4324                 }
4325
4326                 if (ac->pso_res != NULL) {
4327                         DBG_ERR("Too many PSO results for %s\n",
4328                                 ldb_dn_get_linearized(ac->search_res->message->dn));
4329                         talloc_free(ac->pso_res);
4330                 }
4331
4332                 /* store the PSO result (we may need its lockout settings) */
4333                 ac->pso_res = talloc_steal(ac, ares);
4334                 ret = LDB_SUCCESS;
4335                 break;
4336
4337         case LDB_REPLY_REFERRAL:
4338                 /* ignore */
4339                 talloc_free(ares);
4340                 ret = LDB_SUCCESS;
4341                 break;
4342
4343         case LDB_REPLY_DONE:
4344                 talloc_free(ares);
4345
4346                 /*
4347                  * perform the next step of the modify operation (this code
4348                  * shouldn't get called in the 'user add' case)
4349                  */
4350                 if (ac->req->operation == LDB_MODIFY) {
4351                         ret = password_hash_mod_do_mod(ac);
4352                 } else {
4353                         ret = LDB_ERR_OPERATIONS_ERROR;
4354                 }
4355                 break;
4356         }
4357
4358 done:
4359         if (ret != LDB_SUCCESS) {
4360                 struct ldb_reply *new_ares;
4361
4362                 new_ares = talloc_zero(ac->req, struct ldb_reply);
4363                 if (new_ares == NULL) {
4364                         ldb_oom(ldb);
4365                         return ldb_module_done(ac->req, NULL, NULL,
4366                                                LDB_ERR_OPERATIONS_ERROR);
4367                 }
4368
4369                 new_ares->error = ret;
4370                 if ((ret != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
4371                         /* On success and trivial errors a status control is being
4372                          * added (used for example by the "samdb_set_password" call) */
4373                         ldb_reply_add_control(new_ares,
4374                                               DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
4375                                               false,
4376                                               ac->status);
4377                 }
4378
4379                 return ldb_module_done(ac->req, new_ares->controls,
4380                                        new_ares->response, new_ares->error);
4381         }
4382
4383         return LDB_SUCCESS;
4384 }
4385
4386 /*
4387  * Builds and returns a search request to look up the PSO that applies to
4388  * the user in question. Returns NULL if no PSO applies, or could not be found
4389  */
4390 static struct ldb_request * build_pso_data_request(struct ph_context *ac)
4391 {
4392         /* attrs[] is returned from this function in
4393            pso_req->op.search.attrs, so it must be static, as
4394            otherwise the compiler can put it on the stack */
4395         static const char * const attrs[] = { "msDS-PasswordComplexityEnabled",
4396                                               "msDS-PasswordReversibleEncryptionEnabled",
4397                                               "msDS-PasswordHistoryLength",
4398                                               "msDS-MaximumPasswordAge",
4399                                               "msDS-MinimumPasswordAge",
4400                                               "msDS-MinimumPasswordLength",
4401                                               "msDS-LockoutThreshold",
4402                                               "msDS-LockoutObservationWindow",
4403                                               NULL };
4404         struct ldb_context *ldb = NULL;
4405         struct ldb_request *pso_req = NULL;
4406         struct ldb_dn *pso_dn = NULL;
4407         TALLOC_CTX *mem_ctx = ac;
4408         int ret;
4409
4410         ldb = ldb_module_get_ctx(ac->module);
4411
4412         /* if a PSO applies to the user, we need to lookup the PSO as well */
4413         pso_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, ac->search_res->message,
4414                                          "msDS-ResultantPSO");
4415         if (pso_dn == NULL) {
4416                 return NULL;
4417         }
4418
4419         ret = ldb_build_search_req(&pso_req, ldb, mem_ctx, pso_dn,
4420                                    LDB_SCOPE_BASE, NULL, attrs, NULL,
4421                                    ac, get_pso_data_callback,
4422                                    ac->dom_req);
4423
4424         /* log errors, but continue with the default domain settings */
4425         if (ret != LDB_SUCCESS) {
4426                 DBG_ERR("Error %d constructing PSO query for user %s\n", ret,
4427                         ldb_dn_get_linearized(ac->search_res->message->dn));
4428         }
4429         LDB_REQ_SET_LOCATION(pso_req);
4430         return pso_req;
4431 }
4432
4433
4434 static int get_domain_data_callback(struct ldb_request *req,
4435                                     struct ldb_reply *ares)
4436 {
4437         struct ldb_context *ldb;
4438         struct ph_context *ac;
4439         struct loadparm_context *lp_ctx;
4440         struct ldb_request *pso_req = NULL;
4441         int ret = LDB_SUCCESS;
4442
4443         ac = talloc_get_type(req->context, struct ph_context);
4444         ldb = ldb_module_get_ctx(ac->module);
4445
4446         if (!ares) {
4447                 ret = LDB_ERR_OPERATIONS_ERROR;
4448                 goto done;
4449         }
4450         if (ares->error != LDB_SUCCESS) {
4451                 return ldb_module_done(ac->req, ares->controls,
4452                                         ares->response, ares->error);
4453         }
4454
4455         switch (ares->type) {
4456         case LDB_REPLY_ENTRY:
4457                 if (ac->status != NULL) {
4458                         talloc_free(ares);
4459
4460                         ldb_set_errstring(ldb, "Too many results");
4461                         ret = LDB_ERR_OPERATIONS_ERROR;
4462                         goto done;
4463                 }
4464
4465                 /* Setup the "status" structure (used as control later) */
4466                 ac->status = talloc_zero(ac->req,
4467                                          struct dsdb_control_password_change_status);
4468                 if (ac->status == NULL) {
4469                         talloc_free(ares);
4470
4471                         ldb_oom(ldb);
4472                         ret = LDB_ERR_OPERATIONS_ERROR;
4473                         goto done;
4474                 }
4475
4476                 /* Setup the "domain data" structure */
4477                 ac->status->domain_data.pwdProperties =
4478                         ldb_msg_find_attr_as_uint(ares->message, "pwdProperties", -1);
4479                 ac->status->domain_data.pwdHistoryLength =
4480                         ldb_msg_find_attr_as_uint(ares->message, "pwdHistoryLength", -1);
4481                 ac->status->domain_data.maxPwdAge =
4482                         ldb_msg_find_attr_as_int64(ares->message, "maxPwdAge", -1);
4483                 ac->status->domain_data.minPwdAge =
4484                         ldb_msg_find_attr_as_int64(ares->message, "minPwdAge", -1);
4485                 ac->status->domain_data.minPwdLength =
4486                         ldb_msg_find_attr_as_uint(ares->message, "minPwdLength", -1);
4487                 ac->status->domain_data.store_cleartext =
4488                         ac->status->domain_data.pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT;
4489
4490                 /* For a domain DN, this puts things in dotted notation */
4491                 /* For builtin domains, this will give details for the host,
4492                  * but that doesn't really matter, as it's just used for salt
4493                  * and kerberos principals, which don't exist here */
4494
4495                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
4496                                          struct loadparm_context);
4497
4498                 ac->status->domain_data.dns_domain = lpcfg_dnsdomain(lp_ctx);
4499                 ac->status->domain_data.realm = lpcfg_realm(lp_ctx);
4500                 ac->status->domain_data.netbios_domain = lpcfg_sam_name(lp_ctx);
4501
4502                 ac->status->reject_reason = SAM_PWD_CHANGE_NO_ERROR;
4503
4504                 if (ac->dom_res != NULL) {
4505                         talloc_free(ares);
4506
4507                         ldb_set_errstring(ldb, "Too many results");
4508                         ret = LDB_ERR_OPERATIONS_ERROR;
4509                         goto done;
4510                 }
4511
4512                 ac->dom_res = talloc_steal(ac, ares);
4513                 ret = LDB_SUCCESS;
4514                 break;
4515
4516         case LDB_REPLY_REFERRAL:
4517                 /* ignore */
4518                 talloc_free(ares);
4519                 ret = LDB_SUCCESS;
4520                 break;
4521
4522         case LDB_REPLY_DONE:
4523                 talloc_free(ares);
4524                 /* call the next step */
4525                 switch (ac->req->operation) {
4526                 case LDB_ADD:
4527                         ret = password_hash_add_do_add(ac);
4528                         break;
4529
4530                 case LDB_MODIFY:
4531
4532                         /*
4533                          * The user may have an optional PSO applied. If so,
4534                          * query the PSO to get the Fine-Grained Password Policy
4535                          * for the user, before we perform the modify
4536                          */
4537                         pso_req = build_pso_data_request(ac);
4538                         if (pso_req != NULL) {
4539                                 ret = ldb_next_request(ac->module, pso_req);
4540                         } else {
4541
4542                                 /* no PSO, so we can perform the modify now */
4543                                 ret = password_hash_mod_do_mod(ac);
4544                         }
4545                         break;
4546
4547                 default:
4548                         ret = LDB_ERR_OPERATIONS_ERROR;
4549                         break;
4550                 }
4551                 break;
4552         }
4553
4554 done:
4555         if (ret != LDB_SUCCESS) {
4556                 struct ldb_reply *new_ares;
4557
4558                 new_ares = talloc_zero(ac->req, struct ldb_reply);
4559                 if (new_ares == NULL) {
4560                         ldb_oom(ldb);
4561                         return ldb_module_done(ac->req, NULL, NULL,
4562                                                LDB_ERR_OPERATIONS_ERROR);
4563                 }
4564
4565                 new_ares->error = ret;
4566                 if ((ret != LDB_ERR_OPERATIONS_ERROR) && (ac->change_status)) {
4567                         /* On success and trivial errors a status control is being
4568                          * added (used for example by the "samdb_set_password" call) */
4569                         ldb_reply_add_control(new_ares,
4570                                               DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID,
4571                                               false,
4572                                               ac->status);
4573                 }
4574
4575                 return ldb_module_done(ac->req, new_ares->controls,
4576                                        new_ares->response, new_ares->error);
4577         }
4578
4579         return LDB_SUCCESS;
4580 }
4581
4582 static int build_domain_data_request(struct ph_context *ac)
4583 {
4584         /* attrs[] is returned from this function in
4585            ac->dom_req->op.search.attrs, so it must be static, as
4586            otherwise the compiler can put it on the stack */
4587         struct ldb_context *ldb;
4588         static const char * const attrs[] = { "pwdProperties",
4589                                               "pwdHistoryLength",
4590                                               "maxPwdAge",
4591                                               "minPwdAge",
4592                                               "minPwdLength",
4593                                               "lockoutThreshold",
4594                                               "lockOutObservationWindow",
4595                                               NULL };
4596         int ret;
4597
4598         ldb = ldb_module_get_ctx(ac->module);
4599
4600         ret = ldb_build_search_req(&ac->dom_req, ldb, ac,
4601                                    ldb_get_default_basedn(ldb),
4602                                    LDB_SCOPE_BASE,
4603                                    NULL, attrs,
4604                                    NULL,
4605                                    ac, get_domain_data_callback,
4606                                    ac->req);
4607         LDB_REQ_SET_LOCATION(ac->dom_req);
4608         return ret;
4609 }
4610
4611 static int password_hash_needed(struct ldb_module *module,
4612                                 struct ldb_request *req,
4613                                 struct ph_context **_ac)
4614 {
4615         struct ldb_context *ldb = ldb_module_get_ctx(module);
4616         const char *operation = NULL;
4617         const struct ldb_message *msg = NULL;
4618         struct ph_context *ac = NULL;
4619         const char *passwordAttrs[] = {
4620                 DSDB_PASSWORD_ATTRIBUTES,
4621                 NULL
4622         };
4623         const char **a = NULL;
4624         unsigned int attr_cnt = 0;
4625         struct ldb_control *bypass = NULL;
4626         struct ldb_control *uac_ctrl = NULL;
4627         bool userPassword = dsdb_user_password_support(module, req, req);
4628         bool update_password = false;
4629         bool processing_needed = false;
4630
4631         *_ac = NULL;
4632
4633         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_needed\n");
4634
4635         switch (req->operation) {
4636         case LDB_ADD:
4637                 operation = "add";
4638                 msg = req->op.add.message;
4639                 break;
4640         case LDB_MODIFY:
4641                 operation = "modify";
4642                 msg = req->op.mod.message;
4643                 break;
4644         default:
4645                 return ldb_next_request(module, req);
4646         }
4647
4648         if (ldb_dn_is_special(msg->dn)) { /* do not manipulate our control entries */
4649                 return ldb_next_request(module, req);
4650         }
4651
4652         bypass = ldb_request_get_control(req,
4653                                          DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID);
4654         if (bypass != NULL) {
4655                 /* Mark the "bypass" control as uncritical (done) */
4656                 bypass->critical = false;
4657                 ldb_debug(ldb, LDB_DEBUG_TRACE,
4658                           "password_hash_needed(%s) (bypassing)\n",
4659                           operation);
4660                 return password_hash_bypass(module, req);
4661         }
4662
4663         /* nobody must touch password histories and 'supplementalCredentials' */
4664         if (ldb_msg_find_element(msg, "ntPwdHistory")) {
4665                 return LDB_ERR_UNWILLING_TO_PERFORM;
4666         }
4667         if (ldb_msg_find_element(msg, "lmPwdHistory")) {
4668                 return LDB_ERR_UNWILLING_TO_PERFORM;
4669         }
4670         if (ldb_msg_find_element(msg, "supplementalCredentials")) {
4671                 return LDB_ERR_UNWILLING_TO_PERFORM;
4672         }
4673
4674         /*
4675          * If no part of this touches the 'userPassword' OR 'clearTextPassword'
4676          * OR 'unicodePwd' OR 'dBCSPwd' we don't need to make any changes.
4677          * For password changes/set there should be a 'delete' or a 'modify'
4678          * on these attributes.
4679          */
4680         for (a = passwordAttrs; *a != NULL; a++) {
4681                 if ((!userPassword) && (ldb_attr_cmp(*a, "userPassword") == 0)) {
4682                         continue;
4683                 }
4684
4685                 if (ldb_msg_find_element(msg, *a) != NULL) {
4686                         /* MS-ADTS 3.1.1.3.1.5.2 */
4687                         if ((ldb_attr_cmp(*a, "userPassword") == 0) &&
4688                             (dsdb_functional_level(ldb) < DS_DOMAIN_FUNCTION_2003)) {
4689                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4690                         }
4691
4692                         ++attr_cnt;
4693                 }
4694         }
4695
4696         if (attr_cnt > 0) {
4697                 update_password = true;
4698                 processing_needed = true;
4699         }
4700
4701         if (ldb_msg_find_element(msg, "pwdLastSet")) {
4702                 processing_needed = true;
4703         }
4704
4705         uac_ctrl = ldb_request_get_control(req,
4706                                 DSDB_CONTROL_PASSWORD_USER_ACCOUNT_CONTROL_OID);
4707         if (uac_ctrl != NULL) {
4708                 struct dsdb_control_password_user_account_control *uac = NULL;
4709                 uint32_t added_flags = 0;
4710
4711                 uac = talloc_get_type_abort(uac_ctrl->data,
4712                         struct dsdb_control_password_user_account_control);
4713
4714                 added_flags = uac->new_flags & ~uac->old_flags;
4715
4716                 if (added_flags & UF_SMARTCARD_REQUIRED) {
4717                         processing_needed = true;
4718                 }
4719         }
4720
4721         if (!processing_needed) {
4722                 return ldb_next_request(module, req);
4723         }
4724
4725         ac = ph_init_context(module, req, userPassword, update_password);
4726         if (!ac) {
4727                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
4728                 return ldb_operr(ldb);
4729         }
4730         ph_apply_controls(ac);
4731
4732         /*
4733          * Make a copy in order to apply our modifications
4734          * to the final update
4735          */
4736         ac->update_msg = ldb_msg_copy_shallow(ac, msg);
4737         if (ac->update_msg == NULL) {
4738                 return ldb_oom(ldb);
4739         }
4740
4741         /*
4742          * Remove all password related attributes.
4743          */
4744         if (ac->userPassword) {
4745                 ldb_msg_remove_attr(ac->update_msg, "userPassword");
4746         }
4747         ldb_msg_remove_attr(ac->update_msg, "clearTextPassword");
4748         ldb_msg_remove_attr(ac->update_msg, "unicodePwd");
4749         ldb_msg_remove_attr(ac->update_msg, "ntPwdHistory");
4750         ldb_msg_remove_attr(ac->update_msg, "dBCSPwd");
4751         ldb_msg_remove_attr(ac->update_msg, "lmPwdHistory");
4752         ldb_msg_remove_attr(ac->update_msg, "supplementalCredentials");
4753         ldb_msg_remove_attr(ac->update_msg, "pwdLastSet");
4754
4755         *_ac = ac;
4756         return LDB_SUCCESS;
4757 }
4758
4759 static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
4760 {
4761         struct ldb_context *ldb = ldb_module_get_ctx(module);
4762         struct ph_context *ac = NULL;
4763         int ret;
4764
4765         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_add\n");
4766
4767         ret = password_hash_needed(module, req, &ac);
4768         if (ret != LDB_SUCCESS) {
4769                 return ret;
4770         }
4771         if (ac == NULL) {
4772                 return ret;
4773         }
4774
4775         /* Make sure we are performing the password set action on a (for us)
4776          * valid object. Those are instances of either "user" and/or
4777          * "inetOrgPerson". Otherwise continue with the submodules. */
4778         if ((!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "user"))
4779                 && (!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "inetOrgPerson"))) {
4780
4781                 TALLOC_FREE(ac);
4782
4783                 if (ldb_msg_find_element(req->op.add.message, "clearTextPassword") != NULL) {
4784                         ldb_set_errstring(ldb,
4785                                           "'clearTextPassword' is only allowed on objects of class 'user' and/or 'inetOrgPerson'!");
4786                         return LDB_ERR_NO_SUCH_ATTRIBUTE;
4787                 }
4788
4789                 return ldb_next_request(module, req);
4790         }
4791
4792         /* get user domain data */
4793         ret = build_domain_data_request(ac);
4794         if (ret != LDB_SUCCESS) {
4795                 return ret;
4796         }
4797
4798         return ldb_next_request(module, ac->dom_req);
4799 }
4800
4801 static int password_hash_add_do_add(struct ph_context *ac)
4802 {
4803         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
4804         struct ldb_request *down_req;
4805         struct setup_password_fields_io io;
4806         int ret;
4807
4808         /* Prepare the internal data structure containing the passwords */
4809         ret = setup_io(ac, ac->req->op.add.message, NULL, &io);
4810         if (ret != LDB_SUCCESS) {
4811                 return ret;
4812         }
4813
4814         ret = setup_password_fields(&io);
4815         if (ret != LDB_SUCCESS) {
4816                 return ret;
4817         }
4818
4819         ret = check_password_restrictions_and_log(&io);
4820         if (ret != LDB_SUCCESS) {
4821                 return ret;
4822         }
4823
4824         ret = setup_smartcard_reset(&io);
4825         if (ret != LDB_SUCCESS) {
4826                 return ret;
4827         }
4828
4829         ret = update_final_msg(&io);
4830         if (ret != LDB_SUCCESS) {
4831                 return ret;
4832         }
4833
4834         ret = ldb_build_add_req(&down_req, ldb, ac,
4835                                 ac->update_msg,
4836                                 ac->req->controls,
4837                                 ac, ph_op_callback,
4838                                 ac->req);
4839         LDB_REQ_SET_LOCATION(down_req);
4840         if (ret != LDB_SUCCESS) {
4841                 return ret;
4842         }
4843
4844         return ldb_next_request(ac->module, down_req);
4845 }
4846
4847 static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
4848 {
4849         struct ldb_context *ldb = ldb_module_get_ctx(module);
4850         struct ph_context *ac = NULL;
4851         const char *passwordAttrs[] = {DSDB_PASSWORD_ATTRIBUTES, NULL}, **l;
4852         unsigned int del_attr_cnt, add_attr_cnt, rep_attr_cnt;
4853         struct ldb_message_element *passwordAttr;
4854         struct ldb_message *msg;
4855         struct ldb_request *down_req;
4856         struct ldb_control *restore = NULL;
4857         int ret;
4858         unsigned int i = 0;
4859
4860         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");
4861
4862         ret = password_hash_needed(module, req, &ac);
4863         if (ret != LDB_SUCCESS) {
4864                 return ret;
4865         }
4866         if (ac == NULL) {
4867                 return ret;
4868         }
4869
4870         /* use a new message structure so that we can modify it */
4871         msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
4872         if (msg == NULL) {
4873                 return ldb_oom(ldb);
4874         }
4875
4876         /* - check for single-valued password attributes
4877          *   (if not return "CONSTRAINT_VIOLATION")
4878          * - check that for a password change operation one add and one delete
4879          *   operation exists
4880          *   (if not return "CONSTRAINT_VIOLATION" or "UNWILLING_TO_PERFORM")
4881          * - check that a password change and a password set operation cannot
4882          *   be mixed
4883          *   (if not return "UNWILLING_TO_PERFORM")
4884          * - remove all password attributes modifications from the first change
4885          *   operation (anything without the passwords) - we will make the real
4886          *   modification later */
4887         del_attr_cnt = 0;
4888         add_attr_cnt = 0;
4889         rep_attr_cnt = 0;
4890         for (l = passwordAttrs; *l != NULL; l++) {
4891                 if ((!ac->userPassword) &&
4892                     (ldb_attr_cmp(*l, "userPassword") == 0)) {
4893                         continue;
4894                 }
4895
4896                 while ((passwordAttr = ldb_msg_find_element(msg, *l)) != NULL) {
4897                         unsigned int mtype = LDB_FLAG_MOD_TYPE(passwordAttr->flags);
4898                         unsigned int nvalues = passwordAttr->num_values;
4899
4900                         if (mtype == LDB_FLAG_MOD_DELETE) {
4901                                 ++del_attr_cnt;
4902                         }
4903                         if (mtype == LDB_FLAG_MOD_ADD) {
4904                                 ++add_attr_cnt;
4905                         }
4906                         if (mtype == LDB_FLAG_MOD_REPLACE) {
4907                                 ++rep_attr_cnt;
4908                         }
4909                         if ((nvalues != 1) && (mtype == LDB_FLAG_MOD_ADD)) {
4910                                 talloc_free(ac);
4911                                 ldb_asprintf_errstring(ldb,
4912                                                        "'%s' attribute must have exactly one value on add operations!",
4913                                                        *l);
4914                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4915                         }
4916                         if ((nvalues > 1) && (mtype == LDB_FLAG_MOD_DELETE)) {
4917                                 talloc_free(ac);
4918                                 ldb_asprintf_errstring(ldb,
4919                                                        "'%s' attribute must have zero or one value(s) on delete operations!",
4920                                                        *l);
4921                                 return LDB_ERR_CONSTRAINT_VIOLATION;
4922                         }
4923                         ldb_msg_remove_element(msg, passwordAttr);
4924                 }
4925         }
4926         if ((del_attr_cnt == 0) && (add_attr_cnt > 0)) {
4927                 talloc_free(ac);
4928                 ldb_set_errstring(ldb,
4929                                   "Only the add action for a password change specified!");
4930                 return LDB_ERR_UNWILLING_TO_PERFORM;
4931         }
4932         if ((del_attr_cnt > 1) || (add_attr_cnt > 1)) {
4933                 talloc_free(ac);
4934                 ldb_set_errstring(ldb,
4935                                   "Only one delete and one add action for a password change allowed!");
4936                 return LDB_ERR_UNWILLING_TO_PERFORM;
4937         }
4938         if ((rep_attr_cnt > 0) && ((del_attr_cnt > 0) || (add_attr_cnt > 0))) {
4939                 talloc_free(ac);
4940                 ldb_set_errstring(ldb,
4941                                   "Either a password change or a password set operation is allowed!");
4942                 return LDB_ERR_UNWILLING_TO_PERFORM;
4943         }
4944
4945         restore = ldb_request_get_control(req,
4946                                         DSDB_CONTROL_RESTORE_TOMBSTONE_OID);
4947         if (restore == NULL) {
4948                 /*
4949                  * A tombstone reanimation generates a double update
4950                  * of pwdLastSet.
4951                  *
4952                  * So we only remove it without the
4953                  * DSDB_CONTROL_RESTORE_TOMBSTONE_OID control.
4954                  */
4955                 ldb_msg_remove_attr(msg, "pwdLastSet");
4956         }
4957
4958
4959         /* if there was nothing else to be modified skip to next step */
4960         if (msg->num_elements == 0) {
4961                 return password_hash_mod_search_self(ac);
4962         }
4963
4964         /*
4965          * Now we apply all changes remaining in msg
4966          * and remove them from our final update_msg
4967          */
4968
4969         for (i = 0; i < msg->num_elements; i++) {
4970                 ldb_msg_remove_attr(ac->update_msg,
4971                                     msg->elements[i].name);
4972         }
4973
4974         ret = ldb_build_mod_req(&down_req, ldb, ac,
4975                                 msg,
4976                                 req->controls,
4977                                 ac, ph_modify_callback,
4978                                 req);
4979         LDB_REQ_SET_LOCATION(down_req);
4980         if (ret != LDB_SUCCESS) {
4981                 return ret;
4982         }
4983
4984         return ldb_next_request(module, down_req);
4985 }
4986
4987 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
4988 {
4989         struct ph_context *ac;
4990
4991         ac = talloc_get_type(req->context, struct ph_context);
4992
4993         if (!ares) {
4994                 return ldb_module_done(ac->req, NULL, NULL,
4995                                         LDB_ERR_OPERATIONS_ERROR);
4996         }
4997
4998         if (ares->type == LDB_REPLY_REFERRAL) {
4999                 return ldb_module_send_referral(ac->req, ares->referral);
5000         }
5001
5002         if (ares->error != LDB_SUCCESS) {
5003                 return ldb_module_done(ac->req, ares->controls,
5004                                         ares->response, ares->error);
5005         }
5006
5007         if (ares->type != LDB_REPLY_DONE) {
5008                 talloc_free(ares);
5009                 return ldb_module_done(ac->req, NULL, NULL,
5010                                         LDB_ERR_OPERATIONS_ERROR);
5011         }
5012
5013         talloc_free(ares);
5014
5015         return password_hash_mod_search_self(ac);
5016 }
5017
5018 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
5019 {
5020         struct ldb_context *ldb;
5021         struct ph_context *ac;
5022         int ret = LDB_SUCCESS;
5023
5024         ac = talloc_get_type(req->context, struct ph_context);
5025         ldb = ldb_module_get_ctx(ac->module);
5026
5027         if (!ares) {
5028                 ret = LDB_ERR_OPERATIONS_ERROR;
5029                 goto done;
5030         }
5031         if (ares->error != LDB_SUCCESS) {
5032                 return ldb_module_done(ac->req, ares->controls,
5033                                         ares->response, ares->error);
5034         }
5035
5036         /* we are interested only in the single reply (base search) */
5037         switch (ares->type) {
5038         case LDB_REPLY_ENTRY:
5039                 /* Make sure we are performing the password change action on a
5040                  * (for us) valid object. Those are instances of either "user"
5041                  * and/or "inetOrgPerson". Otherwise continue with the
5042                  * submodules. */
5043                 if ((!ldb_msg_check_string_attribute(ares->message, "objectClass", "user"))
5044                         && (!ldb_msg_check_string_attribute(ares->message, "objectClass", "inetOrgPerson"))) {
5045                         talloc_free(ares);
5046
5047                         if (ldb_msg_find_element(ac->req->op.mod.message, "clearTextPassword") != NULL) {
5048                                 ldb_set_errstring(ldb,
5049                                                   "'clearTextPassword' is only allowed on objects of class 'user' and/or 'inetOrgPerson'!");
5050                                 ret = LDB_ERR_NO_SUCH_ATTRIBUTE;
5051                                 goto done;
5052                         }
5053
5054                         ret = ldb_next_request(ac->module, ac->req);
5055                         goto done;
5056                 }
5057
5058                 if (ac->search_res != NULL) {
5059                         talloc_free(ares);
5060
5061                         ldb_set_errstring(ldb, "Too many results");
5062                         ret = LDB_ERR_OPERATIONS_ERROR;
5063                         goto done;
5064                 }
5065
5066                 ac->search_res = talloc_steal(ac, ares);
5067                 ret = LDB_SUCCESS;
5068                 break;
5069
5070         case LDB_REPLY_REFERRAL:
5071                 /* ignore anything else for now */
5072                 talloc_free(ares);
5073                 ret = LDB_SUCCESS;
5074                 break;
5075
5076         case LDB_REPLY_DONE:
5077                 talloc_free(ares);
5078
5079                 /* get user domain data */
5080                 ret = build_domain_data_request(ac);
5081                 if (ret != LDB_SUCCESS) {
5082                         return ldb_module_done(ac->req, NULL, NULL, ret);
5083                 }
5084
5085                 ret = ldb_next_request(ac->module, ac->dom_req);
5086                 break;
5087         }
5088
5089 done:
5090         if (ret != LDB_SUCCESS) {
5091                 return ldb_module_done(ac->req, NULL, NULL, ret);
5092         }
5093
5094         return LDB_SUCCESS;
5095 }
5096
5097 static int password_hash_mod_search_self(struct ph_context *ac)
5098 {
5099         struct ldb_context *ldb;
5100         static const char * const attrs[] = { "objectClass",
5101                                               "userAccountControl",
5102                                               "msDS-ResultantPSO",
5103                                               "msDS-User-Account-Control-Computed",
5104                                               "pwdLastSet",
5105                                               "sAMAccountName",
5106                                               "objectSid",
5107                                               "userPrincipalName",
5108                                               "displayName",
5109                                               "supplementalCredentials",
5110                                               "lmPwdHistory",
5111                                               "ntPwdHistory",
5112                                               "dBCSPwd",
5113                                               "unicodePwd",
5114                                               "badPasswordTime",
5115                                               "badPwdCount",
5116                                               "lockoutTime",
5117                                               "msDS-KeyVersionNumber",
5118                                               "msDS-SecondaryKrbTgtNumber",
5119                                               NULL };
5120         struct ldb_request *search_req;
5121         int ret;
5122
5123         ldb = ldb_module_get_ctx(ac->module);
5124
5125         ret = ldb_build_search_req(&search_req, ldb, ac,
5126                                    ac->req->op.mod.message->dn,
5127                                    LDB_SCOPE_BASE,
5128                                    "(objectclass=*)",
5129                                    attrs,
5130                                    NULL,
5131                                    ac, ph_mod_search_callback,
5132                                    ac->req);
5133         LDB_REQ_SET_LOCATION(search_req);
5134         if (ret != LDB_SUCCESS) {
5135                 return ret;
5136         }
5137
5138         return ldb_next_request(ac->module, search_req);
5139 }
5140
5141 static int password_hash_mod_do_mod(struct ph_context *ac)
5142 {
5143         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
5144         struct ldb_request *mod_req;
5145         struct setup_password_fields_io io;
5146         int ret;
5147
5148         /* Prepare the internal data structure containing the passwords */
5149         ret = setup_io(ac, ac->req->op.mod.message,
5150                        ac->search_res->message, &io);
5151         if (ret != LDB_SUCCESS) {
5152                 return ret;
5153         }
5154
5155         ret = setup_password_fields(&io);
5156         if (ret != LDB_SUCCESS) {
5157                 return ret;
5158         }
5159
5160         ret = check_password_restrictions_and_log(&io);
5161         if (ret != LDB_SUCCESS) {
5162                 return ret;
5163         }
5164
5165         ret = setup_smartcard_reset(&io);
5166         if (ret != LDB_SUCCESS) {
5167                 return ret;
5168         }
5169
5170         ret = update_final_msg(&io);
5171         if (ret != LDB_SUCCESS) {
5172                 return ret;
5173         }
5174
5175         ret = ldb_build_mod_req(&mod_req, ldb, ac,
5176                                 ac->update_msg,
5177                                 ac->req->controls,
5178                                 ac, ph_op_callback,
5179                                 ac->req);
5180         LDB_REQ_SET_LOCATION(mod_req);
5181         if (ret != LDB_SUCCESS) {
5182                 return ret;
5183         }
5184
5185         return ldb_next_request(ac->module, mod_req);
5186 }
5187
5188 static const struct ldb_module_ops ldb_password_hash_module_ops = {
5189         .name          = "password_hash",
5190         .add           = password_hash_add,
5191         .modify        = password_hash_modify
5192 };
5193
5194 int ldb_password_hash_module_init(const char *version)
5195 {
5196 #ifdef ENABLE_GPGME
5197         const char *gversion = NULL;
5198 #endif /* ENABLE_GPGME */
5199
5200         LDB_MODULE_CHECK_VERSION(version);
5201
5202 #ifdef ENABLE_GPGME
5203         /*
5204          * Note: this sets a SIGPIPE handler
5205          * if none is active already. See:
5206          * https://www.gnupg.org/documentation/manuals/gpgme/Signal-Handling.html#Signal-Handling
5207          */
5208         gversion = gpgme_check_version(MINIMUM_GPGME_VERSION);
5209         if (gversion == NULL) {
5210                 fprintf(stderr, "%s() in %s version[%s]: "
5211                         "gpgme_check_version(%s) not available, "
5212                         "gpgme_check_version(NULL) => '%s'\n",
5213                         __func__, __FILE__, version,
5214                         MINIMUM_GPGME_VERSION, gpgme_check_version(NULL));
5215                 return LDB_ERR_UNAVAILABLE;
5216         }
5217 #endif /* ENABLE_GPGME */
5218
5219         return ldb_register_module(&ldb_password_hash_module_ops);
5220 }