b308226a9f9a42247d8641de21d2e070d5160017
[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 contiuues 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                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
321                                          "ndr_pull_struct_blob_all");
322                 }
323
324                 if (scb->sub.num_packages < 2) {
325                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
326                                          "num_packages < 2");
327                 }
328
329                 for (i=0; i < scb->sub.num_packages; i++) {
330                         DATA_BLOB subblob;
331
332                         subblob = strhex_to_data_blob(scb, scb->sub.packages[i].data);
333                         if (subblob.data == NULL) {
334                                 return ldb_module_oom(module);
335                         }
336
337                         if (strcmp(scb->sub.packages[i].name, "Packages") == 0) {
338                                 if (scpp) {
339                                         return ldb_error(ldb,
340                                                          LDB_ERR_CONSTRAINT_VIOLATION,
341                                                          "Packages twice");
342                                 }
343                                 scpp = &scb->sub.packages[i];
344                                 scpbp = subblob;
345                                 continue;
346                         }
347                         if (strcmp(scb->sub.packages[i].name, "Primary:Kerberos") == 0) {
348                                 if (scpk) {
349                                         return ldb_error(ldb,
350                                                          LDB_ERR_CONSTRAINT_VIOLATION,
351                                                          "Primary:Kerberos twice");
352                                 }
353                                 scpk = &scb->sub.packages[i];
354                                 scpbk = subblob;
355                                 continue;
356                         }
357                         if (strcmp(scb->sub.packages[i].name, "Primary:Kerberos-Newer-Keys") == 0) {
358                                 if (scpkn) {
359                                         return ldb_error(ldb,
360                                                          LDB_ERR_CONSTRAINT_VIOLATION,
361                                                          "Primary:Kerberos-Newer-Keys twice");
362                                 }
363                                 scpkn = &scb->sub.packages[i];
364                                 scpbkn = subblob;
365                                 continue;
366                         }
367                         if (strcmp(scb->sub.packages[i].name, "Primary:CLEARTEXT") == 0) {
368                                 if (scpct) {
369                                         return ldb_error(ldb,
370                                                          LDB_ERR_CONSTRAINT_VIOLATION,
371                                                          "Primary:CLEARTEXT twice");
372                                 }
373                                 scpct = &scb->sub.packages[i];
374                                 scpbct = subblob;
375                                 continue;
376                         }
377
378                         data_blob_free(&subblob);
379                 }
380
381                 if (scpp == NULL) {
382                         return ldb_error(ldb,
383                                          LDB_ERR_CONSTRAINT_VIOLATION,
384                                          "Primary:Packages missing");
385                 }
386
387                 if (scpk == NULL) {
388                         /*
389                          * If Primary:Kerberos is missing w2k8r2 reboots
390                          * when a password is changed.
391                          */
392                         return ldb_error(ldb,
393                                          LDB_ERR_CONSTRAINT_VIOLATION,
394                                          "Primary:Kerberos missing");
395                 }
396
397                 if (scpp) {
398                         struct package_PackagesBlob *p;
399                         uint32_t n;
400
401                         p = talloc_zero(scb, struct package_PackagesBlob);
402                         if (p == NULL) {
403                                 return ldb_module_oom(module);
404                         }
405
406                         ndr_err = ndr_pull_struct_blob(&scpbp, p, p,
407                                         (ndr_pull_flags_fn_t)ndr_pull_package_PackagesBlob);
408                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
409                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
410                                                  "ndr_pull_struct_blob Packages");
411                         }
412
413                         if (p->names == NULL) {
414                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
415                                                  "Packages names == NULL");
416                         }
417
418                         for (n = 0; p->names[n]; n++) {
419                                 /* noop */
420                         }
421
422                         if (scb->sub.num_packages != (n + 1)) {
423                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
424                                                  "Packages num_packages != num_names + 1");
425                         }
426
427                         talloc_free(p);
428                 }
429
430                 if (scpk) {
431                         struct package_PrimaryKerberosBlob *k;
432
433                         k = talloc_zero(scb, struct package_PrimaryKerberosBlob);
434                         if (k == NULL) {
435                                 return ldb_module_oom(module);
436                         }
437
438                         ndr_err = ndr_pull_struct_blob(&scpbk, k, k,
439                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
440                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
441                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
442                                                  "ndr_pull_struct_blob PrimaryKerberos");
443                         }
444
445                         if (k->version != 3) {
446                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
447                                                  "PrimaryKerberos version != 3");
448                         }
449
450                         if (k->ctr.ctr3.salt.string == NULL) {
451                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
452                                                  "PrimaryKerberos salt == NULL");
453                         }
454
455                         if (strlen(k->ctr.ctr3.salt.string) == 0) {
456                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
457                                                  "PrimaryKerberos strlen(salt) == 0");
458                         }
459
460                         if (k->ctr.ctr3.num_keys != 2) {
461                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
462                                                  "PrimaryKerberos num_keys != 2");
463                         }
464
465                         if (k->ctr.ctr3.num_old_keys > k->ctr.ctr3.num_keys) {
466                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
467                                                  "PrimaryKerberos num_old_keys > num_keys");
468                         }
469
470                         if (k->ctr.ctr3.keys[0].keytype != ENCTYPE_DES_CBC_MD5) {
471                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
472                                                  "PrimaryKerberos key[0] != DES_CBC_MD5");
473                         }
474                         if (k->ctr.ctr3.keys[1].keytype != ENCTYPE_DES_CBC_CRC) {
475                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
476                                                  "PrimaryKerberos key[1] != DES_CBC_CRC");
477                         }
478
479                         if (k->ctr.ctr3.keys[0].value_len != 8) {
480                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
481                                                  "PrimaryKerberos key[0] value_len != 8");
482                         }
483                         if (k->ctr.ctr3.keys[1].value_len != 8) {
484                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
485                                                  "PrimaryKerberos key[1] value_len != 8");
486                         }
487
488                         for (i = 0; i < k->ctr.ctr3.num_old_keys; i++) {
489                                 if (k->ctr.ctr3.old_keys[i].keytype ==
490                                     k->ctr.ctr3.keys[i].keytype &&
491                                     k->ctr.ctr3.old_keys[i].value_len ==
492                                     k->ctr.ctr3.keys[i].value_len) {
493                                         continue;
494                                 }
495
496                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
497                                                  "PrimaryKerberos old_keys type/value_len doesn't match");
498                         }
499
500                         talloc_free(k);
501                 }
502
503                 if (scpkn) {
504                         struct package_PrimaryKerberosBlob *k;
505
506                         k = talloc_zero(scb, struct package_PrimaryKerberosBlob);
507                         if (k == NULL) {
508                                 return ldb_module_oom(module);
509                         }
510
511                         ndr_err = ndr_pull_struct_blob(&scpbkn, k, k,
512                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
513                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
514                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
515                                                  "ndr_pull_struct_blob PrimaryKerberosNeverKeys");
516                         }
517
518                         if (k->version != 4) {
519                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
520                                                  "KerberosNerverKeys version != 4");
521                         }
522
523                         if (k->ctr.ctr4.salt.string == NULL) {
524                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
525                                                  "KerberosNewerKeys salt == NULL");
526                         }
527
528                         if (strlen(k->ctr.ctr4.salt.string) == 0) {
529                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
530                                                  "KerberosNewerKeys strlen(salt) == 0");
531                         }
532
533                         if (k->ctr.ctr4.num_keys != 4) {
534                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
535                                                  "KerberosNewerKeys num_keys != 2");
536                         }
537
538                         if (k->ctr.ctr4.num_old_keys > k->ctr.ctr4.num_keys) {
539                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
540                                                  "KerberosNewerKeys num_old_keys > num_keys");
541                         }
542
543                         if (k->ctr.ctr4.num_older_keys > k->ctr.ctr4.num_old_keys) {
544                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
545                                                  "KerberosNewerKeys num_older_keys > num_old_keys");
546                         }
547
548                         if (k->ctr.ctr4.keys[0].keytype != ENCTYPE_AES256_CTS_HMAC_SHA1_96) {
549                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
550                                                  "KerberosNewerKeys key[0] != AES256");
551                         }
552                         if (k->ctr.ctr4.keys[1].keytype != ENCTYPE_AES128_CTS_HMAC_SHA1_96) {
553                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
554                                                  "KerberosNewerKeys key[1] != AES128");
555                         }
556                         if (k->ctr.ctr4.keys[2].keytype != ENCTYPE_DES_CBC_MD5) {
557                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
558                                                  "KerberosNewerKeys key[2] != DES_CBC_MD5");
559                         }
560                         if (k->ctr.ctr4.keys[3].keytype != ENCTYPE_DES_CBC_CRC) {
561                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
562                                                  "KerberosNewerKeys key[3] != DES_CBC_CRC");
563                         }
564
565                         if (k->ctr.ctr4.keys[0].value_len != 32) {
566                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
567                                                  "KerberosNewerKeys key[0] value_len != 32");
568                         }
569                         if (k->ctr.ctr4.keys[1].value_len != 16) {
570                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
571                                                  "KerberosNewerKeys key[1] value_len != 16");
572                         }
573                         if (k->ctr.ctr4.keys[2].value_len != 8) {
574                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
575                                                  "KerberosNewerKeys key[2] value_len != 8");
576                         }
577                         if (k->ctr.ctr4.keys[3].value_len != 8) {
578                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
579                                                  "KerberosNewerKeys key[3] value_len != 8");
580                         }
581
582                         /*
583                          * TODO:
584                          * Maybe we can check old and older keys here.
585                          * But we need to do some tests, if the old keys
586                          * can be taken from the PrimaryKerberos blob
587                          * (with only des keys), when the domain was upgraded
588                          * from w2k3 to w2k8.
589                          */
590
591                         talloc_free(k);
592                 }
593
594                 if (scpct) {
595                         struct package_PrimaryCLEARTEXTBlob *ct;
596
597                         ct = talloc_zero(scb, struct package_PrimaryCLEARTEXTBlob);
598                         if (ct == NULL) {
599                                 return ldb_module_oom(module);
600                         }
601
602                         ndr_err = ndr_pull_struct_blob(&scpbct, ct, ct,
603                                         (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryCLEARTEXTBlob);
604                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
605                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
606                                                  "ndr_pull_struct_blob PrimaryCLEARTEXT");
607                         }
608
609                         if ((ct->cleartext.length % 2) != 0) {
610                                 return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
611                                                  "PrimaryCLEARTEXT length % 2 != 0");
612                         }
613
614                         talloc_free(ct);
615                 }
616
617                 ndr_err = ndr_push_struct_blob(&blob, scb, scb,
618                                 (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
619                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
620                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
621                                          "ndr_pull_struct_blob_all");
622                 }
623
624                 if (sce->values[0].length != blob.length) {
625                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
626                                          "supplementalCredentialsBlob length differ");
627                 }
628
629                 if (!mem_equal_const_time(sce->values[0].data, blob.data, blob.length)) {
630                         return ldb_error(ldb, LDB_ERR_CONSTRAINT_VIOLATION,
631                                          "supplementalCredentialsBlob memcmp differ");
632                 }
633
634                 talloc_free(scb);
635         }
636
637         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_bypass - validated\n");
638         return ldb_next_request(module, request);
639 }
640
641 /* Get the NT hash, and fill it in as an entry in the password history, 
642    and specify it into io->g.nt_hash */
643
644 static int setup_nt_fields(struct setup_password_fields_io *io)
645 {
646         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
647         uint32_t i;
648         if (io->u.store_nt_hash) {
649                 io->g.nt_hash = io->n.nt_hash;
650         }
651
652         if (io->ac->status->domain_data.pwdHistoryLength == 0) {
653                 return LDB_SUCCESS;
654         }
655
656         /* We might not have an old NT password */
657
658         if (io->g.nt_hash == NULL) {
659                 /*
660                  * If there was not an NT hash specified, then don't
661                  * store the NT password history.
662                  *
663                  * While the NTLM code on a Windows DC will cope with
664                  * a missing unicodePwd, if it finds a last password
665                  * in the ntPwdHistory, even if the bytes are zero ,
666                  * it will (quite reasonably) treat it as a valid NT
667                  * hash.  NTLM logins with the previous password are
668                  * allowed for a short time after the password is
669                  * changed to allow for password propagation delays.
670                  */
671                 return LDB_SUCCESS;
672         }
673
674         io->g.nt_history = talloc_array(io->ac,
675                                         struct samr_Password,
676                                         io->ac->status->domain_data.pwdHistoryLength);
677         if (!io->g.nt_history) {
678                 return ldb_oom(ldb);
679         }
680
681         for (i = 0; i < MIN(io->ac->status->domain_data.pwdHistoryLength-1,
682                             io->o.nt_history_len); i++) {
683                 io->g.nt_history[i+1] = io->o.nt_history[i];
684         }
685         io->g.nt_history_len = i + 1;
686
687         io->g.nt_history[0] = *io->g.nt_hash;
688
689         return LDB_SUCCESS;
690 }
691
692 static int setup_kerberos_keys(struct setup_password_fields_io *io)
693 {
694         struct ldb_context *ldb;
695         krb5_error_code krb5_ret;
696         krb5_principal salt_principal = NULL;
697         krb5_data salt_data;
698         krb5_data salt;
699         krb5_keyblock key;
700         krb5_data cleartext_data;
701         uint32_t uac_flags = 0;
702
703         ldb = ldb_module_get_ctx(io->ac->module);
704         cleartext_data.data = (char *)io->n.cleartext_utf8->data;
705         cleartext_data.length = io->n.cleartext_utf8->length;
706
707         uac_flags = io->u.userAccountControl & UF_ACCOUNT_TYPE_MASK;
708         krb5_ret = smb_krb5_salt_principal(io->smb_krb5_context->krb5_context,
709                                            io->ac->status->domain_data.realm,
710                                            io->u.sAMAccountName,
711                                            io->u.user_principal_name,
712                                            uac_flags,
713                                            &salt_principal);
714         if (krb5_ret) {
715                 ldb_asprintf_errstring(ldb,
716                                        "setup_kerberos_keys: "
717                                        "generation of a salting principal failed: %s",
718                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
719                                                                   krb5_ret, io->ac));
720                 return LDB_ERR_OPERATIONS_ERROR;
721         }
722
723         /*
724          * create salt from salt_principal
725          */
726         krb5_ret = smb_krb5_get_pw_salt(io->smb_krb5_context->krb5_context,
727                                         salt_principal, &salt_data);
728
729         krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
730         if (krb5_ret) {
731                 ldb_asprintf_errstring(ldb,
732                                        "setup_kerberos_keys: "
733                                        "generation of krb5_salt failed: %s",
734                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
735                                                                   krb5_ret, io->ac));
736                 return LDB_ERR_OPERATIONS_ERROR;
737         }
738
739         /* now use the talloced copy of the salt */
740         salt.data       = talloc_strndup(io->ac,
741                                          (char *)salt_data.data,
742                                          salt_data.length);
743         io->g.salt      = salt.data;
744         salt.length     = strlen(io->g.salt);
745
746         smb_krb5_free_data_contents(io->smb_krb5_context->krb5_context,
747                                     &salt_data);
748
749         /*
750          * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
751          * the salt and the cleartext password
752          */
753         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
754                                                    NULL,
755                                                    &salt,
756                                                    &cleartext_data,
757                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
758                                                    &key);
759         if (krb5_ret) {
760                 ldb_asprintf_errstring(ldb,
761                                        "setup_kerberos_keys: "
762                                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
763                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
764                                                                   krb5_ret, io->ac));
765                 return LDB_ERR_OPERATIONS_ERROR;
766         }
767         io->g.aes_256 = data_blob_talloc(io->ac,
768                                          KRB5_KEY_DATA(&key),
769                                          KRB5_KEY_LENGTH(&key));
770         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
771         if (!io->g.aes_256.data) {
772                 return ldb_oom(ldb);
773         }
774
775         /*
776          * create ENCTYPE_AES128_CTS_HMAC_SHA1_96 key out of
777          * the salt and the cleartext password
778          */
779         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
780                                                    NULL,
781                                                    &salt,
782                                                    &cleartext_data,
783                                                    ENCTYPE_AES128_CTS_HMAC_SHA1_96,
784                                                    &key);
785         if (krb5_ret) {
786                 ldb_asprintf_errstring(ldb,
787                                        "setup_kerberos_keys: "
788                                        "generation of a aes128-cts-hmac-sha1-96 key failed: %s",
789                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
790                                                                   krb5_ret, io->ac));
791                 return LDB_ERR_OPERATIONS_ERROR;
792         }
793         io->g.aes_128 = data_blob_talloc(io->ac,
794                                          KRB5_KEY_DATA(&key),
795                                          KRB5_KEY_LENGTH(&key));
796         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
797         if (!io->g.aes_128.data) {
798                 return ldb_oom(ldb);
799         }
800
801         /*
802          * As per RFC-6649 single DES encryption types are no longer considered
803          * secure to be used in Kerberos, we store random keys instead of the
804          * ENCTYPE_DES_CBC_MD5 and ENCTYPE_DES_CBC_CRC keys.
805          */
806         io->g.des_md5 = data_blob_talloc(io->ac, NULL, 8);
807         if (!io->g.des_md5.data) {
808                 return ldb_oom(ldb);
809         }
810         generate_secret_buffer(io->g.des_md5.data, 8);
811
812         io->g.des_crc = data_blob_talloc(io->ac, NULL, 8);
813         if (!io->g.des_crc.data) {
814                 return ldb_oom(ldb);
815         }
816         generate_secret_buffer(io->g.des_crc.data, 8);
817
818         return LDB_SUCCESS;
819 }
820
821 static int setup_kerberos_key_hash(struct setup_password_fields_io *io,
822                                    struct setup_password_fields_given *g)
823 {
824         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
825         krb5_error_code krb5_ret;
826         krb5_data salt;
827         krb5_keyblock key;
828         krb5_data cleartext_data;
829
830         if (io->ac->search_res == NULL) {
831                 /* No old data so nothing to do */
832                 return LDB_SUCCESS;
833         }
834
835         if (io->o.salt.data == NULL) {
836                 /* We didn't fetch the salt in setup_io(), so nothing to do */
837                 return LDB_SUCCESS;
838         }
839
840         salt.data = (char *)io->o.salt.data;
841         salt.length = io->o.salt.length;
842
843         cleartext_data.data = (char *)g->cleartext_utf8->data;
844         cleartext_data.length = g->cleartext_utf8->length;
845
846         /*
847          * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of the salt
848          * and the cleartext password
849          */
850         krb5_ret = smb_krb5_create_key_from_string(io->smb_krb5_context->krb5_context,
851                                                    NULL,
852                                                    &salt,
853                                                    &cleartext_data,
854                                                    ENCTYPE_AES256_CTS_HMAC_SHA1_96,
855                                                    &key);
856         if (krb5_ret) {
857                 ldb_asprintf_errstring(ldb,
858                                        "setup_kerberos_key_hash: "
859                                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
860                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
861                                                                   krb5_ret, io->ac));
862                 return LDB_ERR_OPERATIONS_ERROR;
863         }
864
865         g->aes_256 = data_blob_talloc(io->ac,
866                                       KRB5_KEY_DATA(&key),
867                                       KRB5_KEY_LENGTH(&key));
868         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
869         if (g->aes_256.data == NULL) {
870                 return ldb_oom(ldb);
871         }
872
873         talloc_keep_secret(g->aes_256.data);
874
875         return LDB_SUCCESS;
876 }
877
878 static int setup_primary_kerberos(struct setup_password_fields_io *io,
879                                   const struct supplementalCredentialsBlob *old_scb,
880                                   struct package_PrimaryKerberosBlob *pkb)
881 {
882         struct ldb_context *ldb;
883         struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
884         struct supplementalCredentialsPackage *old_scp = NULL;
885         struct package_PrimaryKerberosBlob _old_pkb;
886         struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
887         uint32_t i;
888         enum ndr_err_code ndr_err;
889
890         ldb = ldb_module_get_ctx(io->ac->module);
891
892         /*
893          * prepare generation of keys
894          *
895          * ENCTYPE_DES_CBC_MD5
896          * ENCTYPE_DES_CBC_CRC
897          */
898         pkb->version            = 3;
899         pkb3->salt.string       = io->g.salt;
900         pkb3->num_keys          = 2;
901         pkb3->keys              = talloc_array(io->ac,
902                                                struct package_PrimaryKerberosKey3,
903                                                pkb3->num_keys);
904         if (!pkb3->keys) {
905                 return ldb_oom(ldb);
906         }
907
908         pkb3->keys[0].keytype   = ENCTYPE_DES_CBC_MD5;
909         pkb3->keys[0].value     = &io->g.des_md5;
910         pkb3->keys[1].keytype   = ENCTYPE_DES_CBC_CRC;
911         pkb3->keys[1].value     = &io->g.des_crc;
912
913         /* initialize the old keys to zero */
914         pkb3->num_old_keys      = 0;
915         pkb3->old_keys          = NULL;
916
917         /* if there're no old keys, then we're done */
918         if (!old_scb) {
919                 return LDB_SUCCESS;
920         }
921
922         for (i=0; i < old_scb->sub.num_packages; i++) {
923                 if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
924                         continue;
925                 }
926
927                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
928                         continue;
929                 }
930
931                 old_scp = &old_scb->sub.packages[i];
932                 break;
933         }
934         /* Primary:Kerberos element of supplementalCredentials */
935         if (old_scp) {
936                 DATA_BLOB blob;
937
938                 blob = strhex_to_data_blob(io->ac, old_scp->data);
939                 if (!blob.data) {
940                         return ldb_oom(ldb);
941                 }
942
943                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
944                 ndr_err = ndr_pull_struct_blob(&blob, io->ac, &_old_pkb,
945                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
946                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
947                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
948                         ldb_asprintf_errstring(ldb,
949                                                "setup_primary_kerberos: "
950                                                "failed to pull old package_PrimaryKerberosBlob: %s",
951                                                nt_errstr(status));
952                         return LDB_ERR_OPERATIONS_ERROR;
953                 }
954
955                 if (_old_pkb.version != 3) {
956                         ldb_asprintf_errstring(ldb,
957                                                "setup_primary_kerberos: "
958                                                "package_PrimaryKerberosBlob version[%u] expected[3]",
959                                                _old_pkb.version);
960                         return LDB_ERR_OPERATIONS_ERROR;
961                 }
962
963                 old_pkb3 = &_old_pkb.ctr.ctr3;
964         }
965
966         /* if we didn't found the old keys we're done */
967         if (!old_pkb3) {
968                 return LDB_SUCCESS;
969         }
970
971         /* fill in the old keys */
972         pkb3->num_old_keys      = old_pkb3->num_keys;
973         pkb3->old_keys          = old_pkb3->keys;
974
975         return LDB_SUCCESS;
976 }
977
978 static int setup_primary_kerberos_newer(struct setup_password_fields_io *io,
979                                         const struct supplementalCredentialsBlob *old_scb,
980                                         struct package_PrimaryKerberosBlob *pkb)
981 {
982         struct ldb_context *ldb;
983         struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4;
984         struct supplementalCredentialsPackage *old_scp = NULL;
985         struct package_PrimaryKerberosBlob _old_pkb;
986         struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL;
987         uint32_t i;
988         enum ndr_err_code ndr_err;
989
990         ldb = ldb_module_get_ctx(io->ac->module);
991
992         /*
993          * prepare generation of keys
994          *
995          * ENCTYPE_AES256_CTS_HMAC_SHA1_96
996          * ENCTYPE_AES128_CTS_HMAC_SHA1_96
997          * ENCTYPE_DES_CBC_MD5
998          * ENCTYPE_DES_CBC_CRC
999          */
1000         pkb->version                    = 4;
1001         pkb4->salt.string               = io->g.salt;
1002         pkb4->default_iteration_count   = 4096;
1003         pkb4->num_keys                  = 4;
1004
1005         pkb4->keys = talloc_array(io->ac,
1006                                   struct package_PrimaryKerberosKey4,
1007                                   pkb4->num_keys);
1008         if (!pkb4->keys) {
1009                 return ldb_oom(ldb);
1010         }
1011
1012         pkb4->keys[0].iteration_count   = 4096;
1013         pkb4->keys[0].keytype           = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
1014         pkb4->keys[0].value             = &io->g.aes_256;
1015         pkb4->keys[1].iteration_count   = 4096;
1016         pkb4->keys[1].keytype           = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
1017         pkb4->keys[1].value             = &io->g.aes_128;
1018         pkb4->keys[2].iteration_count   = 4096;
1019         pkb4->keys[2].keytype           = ENCTYPE_DES_CBC_MD5;
1020         pkb4->keys[2].value             = &io->g.des_md5;
1021         pkb4->keys[3].iteration_count   = 4096;
1022         pkb4->keys[3].keytype           = ENCTYPE_DES_CBC_CRC;
1023         pkb4->keys[3].value             = &io->g.des_crc;
1024
1025         /* initialize the old keys to zero */
1026         pkb4->num_old_keys      = 0;
1027         pkb4->old_keys          = NULL;
1028         pkb4->num_older_keys    = 0;
1029         pkb4->older_keys        = NULL;
1030
1031         /* if there're no old keys, then we're done */
1032         if (!old_scb) {
1033                 return LDB_SUCCESS;
1034         }
1035
1036         for (i=0; i < old_scb->sub.num_packages; i++) {
1037                 if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) {
1038                         continue;
1039                 }
1040
1041                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
1042                         continue;
1043                 }
1044
1045                 old_scp = &old_scb->sub.packages[i];
1046                 break;
1047         }
1048         /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
1049         if (old_scp) {
1050                 DATA_BLOB blob;
1051
1052                 blob = strhex_to_data_blob(io->ac, old_scp->data);
1053                 if (!blob.data) {
1054                         return ldb_oom(ldb);
1055                 }
1056
1057                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
1058                 ndr_err = ndr_pull_struct_blob(&blob, io->ac,
1059                                                &_old_pkb,
1060                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
1061                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1062                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1063                         ldb_asprintf_errstring(ldb,
1064                                                "setup_primary_kerberos_newer: "
1065                                                "failed to pull old package_PrimaryKerberosBlob: %s",
1066                                                nt_errstr(status));
1067                         return LDB_ERR_OPERATIONS_ERROR;
1068                 }
1069
1070                 if (_old_pkb.version != 4) {
1071                         ldb_asprintf_errstring(ldb,
1072                                                "setup_primary_kerberos_newer: "
1073                                                "package_PrimaryKerberosBlob version[%u] expected[4]",
1074                                                _old_pkb.version);
1075                         return LDB_ERR_OPERATIONS_ERROR;
1076                 }
1077
1078                 old_pkb4 = &_old_pkb.ctr.ctr4;
1079         }
1080
1081         /* if we didn't found the old keys we're done */
1082         if (!old_pkb4) {
1083                 return LDB_SUCCESS;
1084         }
1085
1086         /* fill in the old keys */
1087         pkb4->num_old_keys      = old_pkb4->num_keys;
1088         pkb4->old_keys          = old_pkb4->keys;
1089         pkb4->num_older_keys    = old_pkb4->num_old_keys;
1090         pkb4->older_keys        = old_pkb4->old_keys;
1091
1092         return LDB_SUCCESS;
1093 }
1094
1095 static int setup_primary_wdigest(struct setup_password_fields_io *io,
1096                                  const struct supplementalCredentialsBlob *old_scb,
1097                                  struct package_PrimaryWDigestBlob *pdb)
1098 {
1099         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1100         DATA_BLOB sAMAccountName;
1101         DATA_BLOB sAMAccountName_l;
1102         DATA_BLOB sAMAccountName_u;
1103         const char *user_principal_name = io->u.user_principal_name;
1104         DATA_BLOB userPrincipalName;
1105         DATA_BLOB userPrincipalName_l;
1106         DATA_BLOB userPrincipalName_u;
1107         DATA_BLOB netbios_domain;
1108         DATA_BLOB netbios_domain_l;
1109         DATA_BLOB netbios_domain_u;
1110         DATA_BLOB dns_domain;
1111         DATA_BLOB dns_domain_l;
1112         DATA_BLOB dns_domain_u;
1113         DATA_BLOB digest;
1114         DATA_BLOB delim;
1115         DATA_BLOB backslash;
1116         uint8_t i;
1117         struct {
1118                 DATA_BLOB *user;
1119                 DATA_BLOB *realm;
1120                 DATA_BLOB *nt4dom;
1121         } wdigest[] = {
1122         /*
1123          * See 3.1.1.8.11.3.1 WDIGEST_CREDENTIALS Construction
1124          *     https://msdn.microsoft.com/en-us/library/cc245680.aspx
1125          * for what precalculated hashes are supposed to be stored...
1126          *
1127          * I can't reproduce all values which should contain "Digest" as realm,
1128          * am I doing something wrong or is w2k3 just broken...?
1129          *
1130          * W2K3 fills in following for a user:
1131          *
1132          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1133          * sAMAccountName: NewUser2Sam
1134          * userPrincipalName: NewUser2Princ@sub1.w2k3.vmnet1.vm.base
1135          *
1136          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1137          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1138          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1139          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1140          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1141          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1142          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1143          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1144          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1145          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1146          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1147          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1148          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1149          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1150          * 221c55284451ae9b3aacaa2a3c86f10f => NewUser2Princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1151          * 74e1be668853d4324d38c07e2acfb8ea => (w2k3 has a bug here!) newuser2princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1152          * e1e244ab7f098e3ae1761be7f9229bbb => NEWUSER2PRINC@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1153          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1154          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1155          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1156          * 31dc704d3640335b2123d4ee28aa1f11 => ??? changes with NewUser2Sam => NewUser1Sam
1157          * 36349f5cecd07320fb3bb0e119230c43 => ??? changes with NewUser2Sam => NewUser1Sam
1158          * 12adf019d037fb535c01fd0608e78d9d => ??? changes with NewUser2Sam => NewUser1Sam
1159          * 6feecf8e724906f3ee1105819c5105a1 => ??? changes with NewUser2Princ => NewUser1Princ
1160          * 6c6911f3de6333422640221b9c51ff1f => ??? changes with NewUser2Princ => NewUser1Princ
1161          * 4b279877e742895f9348ac67a8de2f69 => ??? changes with NewUser2Princ => NewUser1Princ
1162          * db0c6bff069513e3ebb9870d29b57490 => ??? changes with NewUser2Sam => NewUser1Sam
1163          * 45072621e56b1c113a4e04a8ff68cd0e => ??? changes with NewUser2Sam => NewUser1Sam
1164          * 11d1220abc44a9c10cf91ef4a9c1de02 => ??? changes with NewUser2Sam => NewUser1Sam
1165          *
1166          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
1167          * sAMAccountName: NewUser2Sam
1168          *
1169          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1170          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
1171          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
1172          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
1173          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
1174          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
1175          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
1176          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1177          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1178          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1179          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1180          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1181          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
1182          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
1183          * 8a140d30b6f0a5912735dc1e3bc993b4 => NewUser2Sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1184          * 86d95b2faae6cae4ec261e7fbaccf093 => (here w2k3 is correct) newuser2sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
1185          * dfeff1493110220efcdfc6362e5f5450 => NEWUSER2SAM@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
1186          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
1187          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
1188          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
1189          * 31dc704d3640335b2123d4ee28aa1f11 => ???M1   changes with NewUser2Sam => NewUser1Sam
1190          * 36349f5cecd07320fb3bb0e119230c43 => ???M1.L changes with newuser2sam => newuser1sam
1191          * 12adf019d037fb535c01fd0608e78d9d => ???M1.U changes with NEWUSER2SAM => NEWUSER1SAM
1192          * 569b4533f2d9e580211dd040e5e360a8 => ???M2   changes with NewUser2Princ => NewUser1Princ
1193          * 52528bddf310a587c5d7e6a9ae2cbb20 => ???M2.L changes with newuser2princ => newuser1princ
1194          * 4f629a4f0361289ca4255ab0f658fcd5 => ???M3 changes with NewUser2Princ => NewUser1Princ (doesn't depend on case of userPrincipal )
1195          * db0c6bff069513e3ebb9870d29b57490 => ???M4 changes with NewUser2Sam => NewUser1Sam
1196          * 45072621e56b1c113a4e04a8ff68cd0e => ???M5 changes with NewUser2Sam => NewUser1Sam (doesn't depend on case of sAMAccountName)
1197          * 11d1220abc44a9c10cf91ef4a9c1de02 => ???M4.U changes with NEWUSER2SAM => NEWUSER1SAM
1198          */
1199
1200         /*
1201          * sAMAccountName, netbios_domain
1202          */
1203                 {
1204                 .user   = &sAMAccountName,
1205                 .realm  = &netbios_domain,
1206                 },
1207                 {
1208                 .user   = &sAMAccountName_l,
1209                 .realm  = &netbios_domain_l,
1210                 },
1211                 {
1212                 .user   = &sAMAccountName_u,
1213                 .realm  = &netbios_domain_u,
1214                 },
1215                 {
1216                 .user   = &sAMAccountName,
1217                 .realm  = &netbios_domain_u,
1218                 },
1219                 {
1220                 .user   = &sAMAccountName,
1221                 .realm  = &netbios_domain_l,
1222                 },
1223                 {
1224                 .user   = &sAMAccountName_u,
1225                 .realm  = &netbios_domain_l,
1226                 },
1227                 {
1228                 .user   = &sAMAccountName_l,
1229                 .realm  = &netbios_domain_u,
1230                 },
1231         /*
1232          * sAMAccountName, dns_domain
1233          *
1234          * TODO:
1235          * Windows preserves the case of the DNS domain,
1236          * Samba lower cases the domain at provision time
1237          * This means that for mixed case Domains, the WDigest08 hash
1238          * calculated by Samba differs from that calculated by Windows.
1239          * Until we get a real world use case this will remain a known
1240          * bug, as changing the case could have unforeseen impacts.
1241          *
1242          */
1243                 {
1244                 .user   = &sAMAccountName,
1245                 .realm  = &dns_domain,
1246                 },
1247                 {
1248                 .user   = &sAMAccountName_l,
1249                 .realm  = &dns_domain_l,
1250                 },
1251                 {
1252                 .user   = &sAMAccountName_u,
1253                 .realm  = &dns_domain_u,
1254                 },
1255                 {
1256                 .user   = &sAMAccountName,
1257                 .realm  = &dns_domain_u,
1258                 },
1259                 {
1260                 .user   = &sAMAccountName,
1261                 .realm  = &dns_domain_l,
1262                 },
1263                 {
1264                 .user   = &sAMAccountName_u,
1265                 .realm  = &dns_domain_l,
1266                 },
1267                 {
1268                 .user   = &sAMAccountName_l,
1269                 .realm  = &dns_domain_u,
1270                 },
1271         /* 
1272          * userPrincipalName, no realm
1273          */
1274                 {
1275                 .user   = &userPrincipalName,
1276                 },
1277                 {
1278                 /* 
1279                  * NOTE: w2k3 messes this up, if the user has a real userPrincipalName,
1280                  *       the fallback to the sAMAccountName based userPrincipalName is correct
1281                  */
1282                 .user   = &userPrincipalName_l,
1283                 },
1284                 {
1285                 .user   = &userPrincipalName_u,
1286                 },
1287         /* 
1288          * nt4dom\sAMAccountName, no realm
1289          */
1290                 {
1291                 .user   = &sAMAccountName,
1292                 .nt4dom = &netbios_domain
1293                 },
1294                 {
1295                 .user   = &sAMAccountName_l,
1296                 .nt4dom = &netbios_domain_l
1297                 },
1298                 {
1299                 .user   = &sAMAccountName_u,
1300                 .nt4dom = &netbios_domain_u
1301                 },
1302
1303         /*
1304          * the following ones are guessed depending on the technet2 article
1305          * but not reproducable on a w2k3 server
1306          */
1307         /* sAMAccountName with "Digest" realm */
1308                 {
1309                 .user   = &sAMAccountName,
1310                 .realm  = &digest
1311                 },
1312                 {
1313                 .user   = &sAMAccountName_l,
1314                 .realm  = &digest
1315                 },
1316                 {
1317                 .user   = &sAMAccountName_u,
1318                 .realm  = &digest
1319                 },
1320         /* userPrincipalName with "Digest" realm */
1321                 {
1322                 .user   = &userPrincipalName,
1323                 .realm  = &digest
1324                 },
1325                 {
1326                 .user   = &userPrincipalName_l,
1327                 .realm  = &digest
1328                 },
1329                 {
1330                 .user   = &userPrincipalName_u,
1331                 .realm  = &digest
1332                 },
1333         /* nt4dom\\sAMAccountName with "Digest" realm */
1334                 {
1335                 .user   = &sAMAccountName,
1336                 .nt4dom = &netbios_domain,
1337                 .realm  = &digest
1338                 },
1339                 {
1340                 .user   = &sAMAccountName_l,
1341                 .nt4dom = &netbios_domain_l,
1342                 .realm  = &digest
1343                 },
1344                 {
1345                 .user   = &sAMAccountName_u,
1346                 .nt4dom = &netbios_domain_u,
1347                 .realm  = &digest
1348                 },
1349         };
1350         int rc = LDB_ERR_OTHER;
1351
1352         /* prepare DATA_BLOB's used in the combinations array */
1353         sAMAccountName          = data_blob_string_const(io->u.sAMAccountName);
1354         sAMAccountName_l        = data_blob_string_const(strlower_talloc(io->ac, io->u.sAMAccountName));
1355         if (!sAMAccountName_l.data) {
1356                 return ldb_oom(ldb);
1357         }
1358         sAMAccountName_u        = data_blob_string_const(strupper_talloc(io->ac, io->u.sAMAccountName));
1359         if (!sAMAccountName_u.data) {
1360                 return ldb_oom(ldb);
1361         }
1362
1363         /* if the user doesn't have a userPrincipalName, create one (with lower case realm) */
1364         if (!user_principal_name) {
1365                 user_principal_name = talloc_asprintf(io->ac, "%s@%s",
1366                                                       io->u.sAMAccountName,
1367                                                       io->ac->status->domain_data.dns_domain);
1368                 if (!user_principal_name) {
1369                         return ldb_oom(ldb);
1370                 }       
1371         }
1372         userPrincipalName       = data_blob_string_const(user_principal_name);
1373         userPrincipalName_l     = data_blob_string_const(strlower_talloc(io->ac, user_principal_name));
1374         if (!userPrincipalName_l.data) {
1375                 return ldb_oom(ldb);
1376         }
1377         userPrincipalName_u     = data_blob_string_const(strupper_talloc(io->ac, user_principal_name));
1378         if (!userPrincipalName_u.data) {
1379                 return ldb_oom(ldb);
1380         }
1381
1382         netbios_domain          = data_blob_string_const(io->ac->status->domain_data.netbios_domain);
1383         netbios_domain_l        = data_blob_string_const(strlower_talloc(io->ac,
1384                                                                          io->ac->status->domain_data.netbios_domain));
1385         if (!netbios_domain_l.data) {
1386                 return ldb_oom(ldb);
1387         }
1388         netbios_domain_u        = data_blob_string_const(strupper_talloc(io->ac,
1389                                                                          io->ac->status->domain_data.netbios_domain));
1390         if (!netbios_domain_u.data) {
1391                 return ldb_oom(ldb);
1392         }
1393
1394         dns_domain              = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1395         dns_domain_l            = data_blob_string_const(io->ac->status->domain_data.dns_domain);
1396         dns_domain_u            = data_blob_string_const(io->ac->status->domain_data.realm);
1397
1398         digest                  = data_blob_string_const("Digest");
1399
1400         delim                   = data_blob_string_const(":");
1401         backslash               = data_blob_string_const("\\");
1402
1403         pdb->num_hashes = ARRAY_SIZE(wdigest);
1404         pdb->hashes     = talloc_array(io->ac, struct package_PrimaryWDigestHash,
1405                                        pdb->num_hashes);
1406         if (!pdb->hashes) {
1407                 return ldb_oom(ldb);
1408         }
1409
1410         for (i=0; i < ARRAY_SIZE(wdigest); i++) {
1411                 gnutls_hash_hd_t hash_hnd = NULL;
1412
1413                 rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
1414                 if (rc < 0) {
1415                         rc = ldb_oom(ldb);
1416                         goto out;
1417                 }
1418
1419                 if (wdigest[i].nt4dom) {
1420                         rc = gnutls_hash(hash_hnd,
1421                                           wdigest[i].nt4dom->data,
1422                                           wdigest[i].nt4dom->length);
1423                         if (rc < 0) {
1424                                 gnutls_hash_deinit(hash_hnd, NULL);
1425                                 rc = LDB_ERR_UNWILLING_TO_PERFORM;
1426                                 goto out;
1427                         }
1428                         rc = gnutls_hash(hash_hnd,
1429                                           backslash.data,
1430                                           backslash.length);
1431                         if (rc < 0) {
1432                                 gnutls_hash_deinit(hash_hnd, NULL);
1433                                 rc = LDB_ERR_UNWILLING_TO_PERFORM;
1434                                 goto out;
1435                         }
1436                 }
1437                 rc = gnutls_hash(hash_hnd,
1438                                  wdigest[i].user->data,
1439                                  wdigest[i].user->length);
1440                 if (rc < 0) {
1441                         gnutls_hash_deinit(hash_hnd, NULL);
1442                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1443                         goto out;
1444                 }
1445                 rc = gnutls_hash(hash_hnd, delim.data, delim.length);
1446                 if (rc < 0) {
1447                         gnutls_hash_deinit(hash_hnd, NULL);
1448                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1449                         goto out;
1450                 }
1451                 if (wdigest[i].realm) {
1452                         rc = gnutls_hash(hash_hnd,
1453                                          wdigest[i].realm->data,
1454                                          wdigest[i].realm->length);
1455                         if (rc < 0) {
1456                                 gnutls_hash_deinit(hash_hnd, NULL);
1457                                 rc = LDB_ERR_UNWILLING_TO_PERFORM;
1458                                 goto out;
1459                         }
1460                 }
1461                 rc = gnutls_hash(hash_hnd, delim.data, delim.length);
1462                 if (rc < 0) {
1463                         gnutls_hash_deinit(hash_hnd, NULL);
1464                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1465                         goto out;
1466                 }
1467                 rc = gnutls_hash(hash_hnd,
1468                                   io->n.cleartext_utf8->data,
1469                                   io->n.cleartext_utf8->length);
1470                 if (rc < 0) {
1471                         gnutls_hash_deinit(hash_hnd, NULL);
1472                         rc = LDB_ERR_UNWILLING_TO_PERFORM;
1473                         goto out;
1474                 }
1475
1476                 gnutls_hash_deinit(hash_hnd, pdb->hashes[i].hash);
1477         }
1478
1479         rc = LDB_SUCCESS;
1480 out:
1481         return rc;
1482 }
1483
1484 #define SHA_SALT_PERMITTED_CHARS "abcdefghijklmnopqrstuvwxyz" \
1485                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
1486                                  "0123456789./"
1487 #define SHA_SALT_SIZE 16
1488 #define SHA_256_SCHEME "CryptSHA256"
1489 #define SHA_512_SCHEME "CryptSHA512"
1490 #define CRYPT "{CRYPT}"
1491 #define SHA_ID_LEN 3
1492 #define SHA_256_ALGORITHM_ID 5
1493 #define SHA_512_ALGORITHM_ID 6
1494 #define ROUNDS_PARAMETER "rounds="
1495
1496 /*
1497  * Extract the crypt (3) algorithm number and number of hash rounds from the
1498  * supplied scheme string
1499  */
1500 static bool parse_scheme(const char *scheme, int *algorithm, int *rounds) {
1501
1502         const char *rp = NULL; /* Pointer to the 'rounds=' option */
1503         char digits[21];       /* digits extracted from the rounds option */
1504         int i = 0;             /* loop index variable */
1505
1506         if (strncasecmp(SHA_256_SCHEME, scheme, strlen(SHA_256_SCHEME)) == 0) {
1507                 *algorithm = SHA_256_ALGORITHM_ID;
1508         } else if (strncasecmp(SHA_512_SCHEME, scheme, strlen(SHA_256_SCHEME))
1509                    == 0) {
1510                 *algorithm = SHA_512_ALGORITHM_ID;
1511         } else {
1512                 return false;
1513         }
1514
1515         rp = strcasestr(scheme, ROUNDS_PARAMETER);
1516         if (rp == NULL) {
1517                 /* No options specified, use crypt default number of rounds */
1518                 *rounds = 0;
1519                 return true;
1520         }
1521         rp += strlen(ROUNDS_PARAMETER);
1522         for (i = 0; isdigit(rp[i]) && i < (sizeof(digits) - 1); i++) {
1523                 digits[i] = rp[i];
1524         }
1525         digits[i] = '\0';
1526         *rounds = atoi(digits);
1527         return true;
1528 }
1529
1530 /*
1531  * Calculate the password hash specified by scheme, and return it in
1532  * hash_value
1533  */
1534 static int setup_primary_userPassword_hash(
1535         TALLOC_CTX *ctx,
1536         struct setup_password_fields_io *io,
1537         const char* scheme,
1538         struct package_PrimaryUserPasswordValue *hash_value)
1539 {
1540         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1541         const char *salt = NULL;        /* Randomly generated salt */
1542         const char *cmd = NULL;         /* command passed to crypt */
1543         const char *hash = NULL;        /* password hash generated by crypt */
1544         int algorithm = 0;              /* crypt hash algorithm number */
1545         int rounds = 0;                 /* The number of hash rounds */
1546         DATA_BLOB *hash_blob = NULL;
1547         TALLOC_CTX *frame = talloc_stackframe();
1548 #if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT_RN)
1549         struct crypt_data crypt_data = {
1550                 .initialized = 0        /* working storage used by crypt */
1551         };
1552 #endif
1553
1554         /* Genrate a random password salt */
1555         salt = generate_random_str_list(frame,
1556                                         SHA_SALT_SIZE,
1557                                         SHA_SALT_PERMITTED_CHARS);
1558         if (salt == NULL) {
1559                 TALLOC_FREE(frame);
1560                 return ldb_oom(ldb);
1561         }
1562
1563         /* determine the hashing algoritm and number of rounds*/
1564         if (!parse_scheme(scheme, &algorithm, &rounds)) {
1565                 ldb_asprintf_errstring(
1566                         ldb,
1567                         "setup_primary_userPassword: Invalid scheme of [%s] "
1568                         "specified for 'password hash userPassword schemes' in "
1569                         "samba.conf",
1570                         scheme);
1571                 TALLOC_FREE(frame);
1572                 return LDB_ERR_OPERATIONS_ERROR;
1573         }
1574         hash_value->scheme = talloc_strdup(ctx, CRYPT);
1575         hash_value->scheme_len = strlen(CRYPT) + 1;
1576
1577         /* generate the id/salt parameter used by crypt */
1578         if (rounds) {
1579                 cmd = talloc_asprintf(frame,
1580                                       "$%d$rounds=%d$%s",
1581                                       algorithm,
1582                                       rounds,
1583                                       salt);
1584         } else {
1585                 cmd = talloc_asprintf(frame, "$%d$%s", algorithm, salt);
1586         }
1587
1588         /*
1589          * Relies on the assertion that cleartext_utf8->data is a zero
1590          * terminated UTF-8 string
1591          */
1592
1593         /*
1594          * crypt_r() and crypt() may return a null pointer upon error
1595          * depending on how libcrypt was configured, so we prefer
1596          * crypt_rn() from libcrypt / libxcrypt which always returns
1597          * NULL on error.
1598          *
1599          * POSIX specifies returning a null pointer and setting
1600          * errno.
1601          *
1602          * RHEL 7 (which does not use libcrypt / libxcrypt) returns a
1603          * non-NULL pointer from crypt_r() on success but (always?)
1604          * sets errno during internal processing in the NSS crypto
1605          * subsystem.
1606          *
1607          * By preferring crypt_rn we avoid the 'return non-NULL but
1608          * set-errno' that we otherwise cannot tell apart from the
1609          * RHEL 7 behaviour.
1610          */
1611         errno = 0;
1612
1613 #ifdef HAVE_CRYPT_RN
1614         hash = crypt_rn((char *)io->n.cleartext_utf8->data,
1615                         cmd,
1616                         &crypt_data,
1617                         sizeof(crypt_data));
1618 #elif HAVE_CRYPT_R
1619         hash = crypt_r((char *)io->n.cleartext_utf8->data, cmd, &crypt_data);
1620 #else
1621         /*
1622          * No crypt_r falling back to crypt, which is NOT thread safe
1623          * Thread safety MT-Unsafe race:crypt
1624          */
1625         hash = crypt((char *)io->n.cleartext_utf8->data, cmd);
1626 #endif
1627         /*
1628         * On error, crypt() and crypt_r() may return a null pointer,
1629         * or a pointer to an invalid hash beginning with a '*'.
1630         */
1631         if (hash == NULL || hash[0] == '*') {
1632                 char buf[1024];
1633                 const char *reason = NULL;
1634                 if (errno == ERANGE) {
1635                         reason = "Password exceeds maximum length allowed for crypt() hashing";
1636                 } else {
1637                         int err = strerror_r(errno, buf, sizeof(buf));
1638                         if (err == 0) {
1639                                 reason = buf;
1640                         } else {
1641                                 reason = "Unknown error";
1642                         }
1643                 }
1644                 ldb_asprintf_errstring(
1645                         ldb,
1646                         "setup_primary_userPassword: generation of a %s "
1647                         "password hash failed: (%s)",
1648                         scheme,
1649                         reason);
1650                 TALLOC_FREE(frame);
1651                 return LDB_ERR_OPERATIONS_ERROR;
1652         }
1653
1654         hash_blob = talloc_zero(ctx, DATA_BLOB);
1655
1656         if (hash_blob == NULL) {
1657                 TALLOC_FREE(frame);
1658                 return ldb_oom(ldb);
1659         }
1660
1661         *hash_blob =  data_blob_talloc(hash_blob,
1662                                        (const uint8_t *)hash,
1663                                        strlen(hash));
1664         if (hash_blob->data == NULL) {
1665                 TALLOC_FREE(frame);
1666                 return ldb_oom(ldb);
1667         }
1668         hash_value->value = hash_blob;
1669         TALLOC_FREE(frame);
1670         return LDB_SUCCESS;
1671 }
1672
1673 /*
1674  * Calculate the desired extra password hashes
1675  */
1676 static int setup_primary_userPassword(
1677         struct setup_password_fields_io *io,
1678         const struct supplementalCredentialsBlob *old_scb,
1679         struct package_PrimaryUserPasswordBlob *p_userPassword_b)
1680 {
1681         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1682         TALLOC_CTX *frame = talloc_stackframe();
1683         int i;
1684         int ret;
1685
1686         /*
1687          * Save the current nt_hash, use this to determine if the password
1688          * has been changed by windows. Which will invalidate the userPassword
1689          * hash. Note once NTLM-Strong-NOWTF becomes available it should be
1690          * used in preference to the NT password hash
1691          */
1692         if (io->g.nt_hash == NULL) {
1693                 /*
1694                  * When the NT hash is not available, we use this field to store
1695                  * the first 16 bytes of the AES256 key instead. This allows
1696                  * 'samba-tool user' to verify that the user's password is in
1697                  * sync with the userPassword package.
1698                  */
1699                 uint8_t hash_len = MIN(16, io->g.aes_256.length);
1700
1701                 ZERO_STRUCT(p_userPassword_b->current_nt_hash);
1702                 memcpy(p_userPassword_b->current_nt_hash.hash,
1703                        io->g.aes_256.data,
1704                        hash_len);
1705         } else {
1706                 p_userPassword_b->current_nt_hash = *io->g.nt_hash;
1707         }
1708
1709         /*
1710          * Determine the number of hashes
1711          * Note: that currently there is no limit on the number of hashes
1712          *       no checking is done on the number of schemes specified
1713          *       or for uniqueness.
1714          */
1715         p_userPassword_b->num_hashes = 0;
1716         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1717                 p_userPassword_b->num_hashes++;
1718         }
1719
1720         p_userPassword_b->hashes
1721                 = talloc_array(io->ac,
1722                                struct package_PrimaryUserPasswordValue,
1723                                p_userPassword_b->num_hashes);
1724         if (p_userPassword_b->hashes == NULL) {
1725                 TALLOC_FREE(frame);
1726                 return ldb_oom(ldb);
1727         }
1728
1729         for (i = 0; io->ac->userPassword_schemes[i]; i++) {
1730                 ret = setup_primary_userPassword_hash(
1731                         p_userPassword_b->hashes,
1732                         io,
1733                         io->ac->userPassword_schemes[i],
1734                         &p_userPassword_b->hashes[i]);
1735                 if (ret != LDB_SUCCESS) {
1736                         TALLOC_FREE(frame);
1737                         return ret;
1738                 }
1739         }
1740         return LDB_SUCCESS;
1741 }
1742
1743
1744 static int setup_primary_samba_gpg(struct setup_password_fields_io *io,
1745                                    struct package_PrimarySambaGPGBlob *pgb)
1746 {
1747         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
1748 #ifdef ENABLE_GPGME
1749         gpgme_error_t gret;
1750         gpgme_ctx_t ctx = NULL;
1751         size_t num_keys = str_list_length(io->ac->gpg_key_ids);
1752         gpgme_key_t keys[num_keys+1];
1753         size_t ki = 0;
1754         size_t kr = 0;
1755         gpgme_data_t plain_data = NULL;
1756         gpgme_data_t crypt_data = NULL;
1757         size_t crypt_length = 0;
1758         char *crypt_mem = NULL;
1759
1760         gret = gpgme_new(&ctx);
1761         if (gret != GPG_ERR_NO_ERROR) {
1762                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1763                           "%s:%s: gret[%u] %s\n",
1764                           __location__, __func__,
1765                           gret, gpgme_strerror(gret));
1766                 return ldb_module_operr(io->ac->module);
1767         }
1768
1769         gpgme_set_armor(ctx, 1);
1770
1771         gret = gpgme_data_new_from_mem(&plain_data,
1772                                        (const char *)io->n.cleartext_utf16->data,
1773                                        io->n.cleartext_utf16->length,
1774                                        0 /* no copy */);
1775         if (gret != GPG_ERR_NO_ERROR) {
1776                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1777                           "%s:%s: gret[%u] %s\n",
1778                           __location__, __func__,
1779                           gret, gpgme_strerror(gret));
1780                 gpgme_release(ctx);
1781                 return ldb_module_operr(io->ac->module);
1782         }
1783         gret = gpgme_data_new(&crypt_data);
1784         if (gret != GPG_ERR_NO_ERROR) {
1785                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1786                           "%s:%s: gret[%u] %s\n",
1787                           __location__, __func__,
1788                           gret, gpgme_strerror(gret));
1789                 gpgme_data_release(plain_data);
1790                 gpgme_release(ctx);
1791                 return ldb_module_operr(io->ac->module);
1792         }
1793
1794         for (ki = 0; ki < num_keys; ki++) {
1795                 const char *key_id = io->ac->gpg_key_ids[ki];
1796                 size_t len = strlen(key_id);
1797
1798                 keys[ki] = NULL;
1799
1800                 if (len < 16) {
1801                         ldb_debug(ldb, LDB_DEBUG_FATAL,
1802                                   "%s:%s: ki[%zu] key_id[%s] strlen < 16, "
1803                                   "please specify at least the 64bit key id\n",
1804                                   __location__, __func__,
1805                                   ki, key_id);
1806                         for (kr = 0; keys[kr] != NULL; kr++) {
1807                                 gpgme_key_release(keys[kr]);
1808                         }
1809                         gpgme_data_release(crypt_data);
1810                         gpgme_data_release(plain_data);
1811                         gpgme_release(ctx);
1812                         return ldb_module_operr(io->ac->module);
1813                 }
1814
1815                 gret = gpgme_get_key(ctx, key_id, &keys[ki], 0 /* public key */);
1816                 if (gret != GPG_ERR_NO_ERROR) {
1817                         keys[ki] = NULL;
1818                         if (gpg_err_source(gret) == GPG_ERR_SOURCE_GPGME
1819                             && gpg_err_code(gret) == GPG_ERR_EOF) {
1820                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1821                                           "Invalid "
1822                                           "'password hash gpg key ids': "
1823                                           "Public Key ID [%s] "
1824                                           "not found in keyring\n",
1825                                           key_id);
1826
1827                         } else {
1828                                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1829                                           "%s:%s: ki[%zu] key_id[%s] "
1830                                           "gret[%u] %s\n",
1831                                           __location__, __func__,
1832                                           ki, key_id,
1833                                           gret, gpgme_strerror(gret));
1834                         }
1835                         for (kr = 0; keys[kr] != NULL; kr++) {
1836                                 gpgme_key_release(keys[kr]);
1837                         }
1838                         gpgme_data_release(crypt_data);
1839                         gpgme_data_release(plain_data);
1840                         gpgme_release(ctx);
1841                         return ldb_module_operr(io->ac->module);
1842                 }
1843         }
1844         keys[ki] = NULL;
1845
1846         gret = gpgme_op_encrypt(ctx, keys,
1847                                 GPGME_ENCRYPT_ALWAYS_TRUST,
1848                                 plain_data, crypt_data);
1849         gpgme_data_release(plain_data);
1850         plain_data = NULL;
1851         for (kr = 0; keys[kr] != NULL; kr++) {
1852                 gpgme_key_release(keys[kr]);
1853                 keys[kr] = NULL;
1854         }
1855         gpgme_release(ctx);
1856         ctx = NULL;
1857         if (gret != GPG_ERR_NO_ERROR) {
1858                 ldb_debug(ldb, LDB_DEBUG_ERROR,
1859                           "%s:%s: gret[%u] %s\n",
1860                           __location__, __func__,
1861                           gret, gpgme_strerror(gret));
1862                 gpgme_data_release(crypt_data);
1863                 return ldb_module_operr(io->ac->module);
1864         }
1865
1866         crypt_mem = gpgme_data_release_and_get_mem(crypt_data, &crypt_length);
1867         crypt_data = NULL;
1868         if (crypt_mem == NULL) {
1869                 return ldb_module_oom(io->ac->module);
1870         }
1871
1872         pgb->gpg_blob = data_blob_talloc(io->ac,
1873                                          (const uint8_t *)crypt_mem,
1874                                          crypt_length);
1875         gpgme_free(crypt_mem);
1876         crypt_mem = NULL;
1877         crypt_length = 0;
1878         if (pgb->gpg_blob.data == NULL) {
1879                 return ldb_module_oom(io->ac->module);
1880         }
1881
1882         return LDB_SUCCESS;
1883 #else /* ENABLE_GPGME */
1884         ldb_debug_set(ldb, LDB_DEBUG_FATAL,
1885                       "You configured 'password hash gpg key ids', "
1886                       "but GPGME support is missing. (%s:%d)",
1887                       __FILE__, __LINE__);
1888         return LDB_ERR_UNWILLING_TO_PERFORM;
1889 #endif /* else ENABLE_GPGME */
1890 }
1891
1892 #define NUM_PACKAGES 6
1893 static int setup_supplemental_field(struct setup_password_fields_io *io)
1894 {
1895         struct ldb_context *ldb;
1896         struct supplementalCredentialsBlob scb;
1897         struct supplementalCredentialsBlob *old_scb = NULL;
1898         /*
1899          * Packages +
1900          * ( Kerberos-Newer-Keys, Kerberos,
1901          *   WDigest, CLEARTEXT, userPassword, SambaGPG)
1902          */
1903         uint32_t num_names = 0;
1904         const char *names[1+NUM_PACKAGES];
1905         uint32_t num_packages = 0;
1906         struct supplementalCredentialsPackage packages[1+NUM_PACKAGES];
1907         struct supplementalCredentialsPackage *pp = packages;
1908         int ret;
1909         enum ndr_err_code ndr_err;
1910         bool do_newer_keys = false;
1911         bool do_cleartext = false;
1912         bool do_samba_gpg = false;
1913         struct loadparm_context *lp_ctx = NULL;
1914
1915         ZERO_STRUCT(names);
1916         ZERO_STRUCT(packages);
1917
1918         ldb = ldb_module_get_ctx(io->ac->module);
1919         lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1920                                  struct loadparm_context);
1921
1922         if (!io->n.cleartext_utf8) {
1923                 /*
1924                  * when we don't have a cleartext password
1925                  * we can't setup a supplementalCredential value
1926                  */
1927                 return LDB_SUCCESS;
1928         }
1929
1930         /* if there's an old supplementaCredentials blob then use it */
1931         if (io->o.supplemental) {
1932                 if (io->o.scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
1933                         old_scb = &io->o.scb;
1934                 } else {
1935                         ldb_debug(ldb, LDB_DEBUG_ERROR,
1936                                   "setup_supplemental_field: "
1937                                   "supplementalCredentialsBlob "
1938                                   "signature[0x%04X] expected[0x%04X]",
1939                                   io->o.scb.sub.signature,
1940                                   SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
1941                 }
1942         }
1943         /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
1944
1945
1946
1947         /*
1948          * The ordering is this
1949          *
1950          * Primary:Kerberos-Newer-Keys (optional)
1951          * Primary:Kerberos
1952          * Primary:WDigest
1953          * Primary:CLEARTEXT (optional)
1954          * Primary:userPassword
1955          * Primary:SambaGPG (optional)
1956          *
1957          * And the 'Packages' package is insert before the last
1958          * other package.
1959          *
1960          * Note: it's important that Primary:SambaGPG is added as
1961          * the last element. This is the indication that it matches
1962          * the current password. When a password change happens on
1963          * a Windows DC, it will keep the old Primary:SambaGPG value,
1964          * but as the first element.
1965          */
1966         do_newer_keys = (dsdb_functional_level(ldb) >= DS_DOMAIN_FUNCTION_2008);
1967         if (do_newer_keys) {
1968                 struct package_PrimaryKerberosBlob pknb;
1969                 DATA_BLOB pknb_blob;
1970                 char *pknb_hexstr;
1971                 /*
1972                  * setup 'Primary:Kerberos-Newer-Keys' element
1973                  */
1974                 names[num_names++] = "Kerberos-Newer-Keys";
1975
1976                 ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
1977                 if (ret != LDB_SUCCESS) {
1978                         return ret;
1979                 }
1980
1981                 ndr_err = ndr_push_struct_blob(
1982                         &pknb_blob, io->ac,
1983                         &pknb,
1984                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1985                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1986                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1987                         ldb_asprintf_errstring(
1988                                 ldb,
1989                                 "setup_supplemental_field: "
1990                                 "failed to push "
1991                                 "package_PrimaryKerberosNeverBlob: %s",
1992                                 nt_errstr(status));
1993                         return LDB_ERR_OPERATIONS_ERROR;
1994                 }
1995                 pknb_hexstr = data_blob_hex_string_upper(io->ac, &pknb_blob);
1996                 if (!pknb_hexstr) {
1997                         return ldb_oom(ldb);
1998                 }
1999                 pp->name        = "Primary:Kerberos-Newer-Keys";
2000                 pp->reserved    = 1;
2001                 pp->data        = pknb_hexstr;
2002                 pp++;
2003                 num_packages++;
2004         }
2005
2006         {
2007                 /*
2008                  * setup 'Primary:Kerberos' element
2009                  */
2010                 /* Primary:Kerberos */
2011                 struct package_PrimaryKerberosBlob pkb;
2012                 DATA_BLOB pkb_blob;
2013                 char *pkb_hexstr;
2014
2015                 names[num_names++] = "Kerberos";
2016
2017                 ret = setup_primary_kerberos(io, old_scb, &pkb);
2018                 if (ret != LDB_SUCCESS) {
2019                         return ret;
2020                 }
2021
2022                 ndr_err = ndr_push_struct_blob(
2023                         &pkb_blob, io->ac,
2024                         &pkb,
2025                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
2026                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2027                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2028                         ldb_asprintf_errstring(
2029                                 ldb,
2030                                 "setup_supplemental_field: "
2031                                 "failed to push package_PrimaryKerberosBlob: %s",
2032                                 nt_errstr(status));
2033                         return LDB_ERR_OPERATIONS_ERROR;
2034                 }
2035                 pkb_hexstr = data_blob_hex_string_upper(io->ac, &pkb_blob);
2036                 if (!pkb_hexstr) {
2037                         return ldb_oom(ldb);
2038                 }
2039                 pp->name        = "Primary:Kerberos";
2040                 pp->reserved    = 1;
2041                 pp->data        = pkb_hexstr;
2042                 pp++;
2043                 num_packages++;
2044         }
2045
2046         if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_ALLOWED) {
2047                 /*
2048                  * setup 'Primary:WDigest' element
2049                  */
2050                 struct package_PrimaryWDigestBlob pdb;
2051                 DATA_BLOB pdb_blob;
2052                 char *pdb_hexstr;
2053
2054                 names[num_names++] = "WDigest";
2055
2056                 ret = setup_primary_wdigest(io, old_scb, &pdb);
2057                 if (ret != LDB_SUCCESS) {
2058                         return ret;
2059                 }
2060
2061                 ndr_err = ndr_push_struct_blob(
2062                         &pdb_blob, io->ac,
2063                         &pdb,
2064                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryWDigestBlob);
2065                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2066                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2067                         ldb_asprintf_errstring(
2068                                 ldb,
2069                                 "setup_supplemental_field: "
2070                                 "failed to push package_PrimaryWDigestBlob: %s",
2071                                 nt_errstr(status));
2072                         return LDB_ERR_OPERATIONS_ERROR;
2073                 }
2074                 pdb_hexstr = data_blob_hex_string_upper(io->ac, &pdb_blob);
2075                 if (!pdb_hexstr) {
2076                         return ldb_oom(ldb);
2077                 }
2078                 pp->name        = "Primary:WDigest";
2079                 pp->reserved    = 1;
2080                 pp->data        = pdb_hexstr;
2081                 pp++;
2082                 num_packages++;
2083         }
2084
2085         /*
2086          * setup 'Primary:CLEARTEXT' element
2087          */
2088         if (io->ac->status->domain_data.store_cleartext &&
2089             (io->u.userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
2090                 do_cleartext = true;
2091         }
2092         if (do_cleartext) {
2093                 struct package_PrimaryCLEARTEXTBlob pcb;
2094                 DATA_BLOB pcb_blob;
2095                 char *pcb_hexstr;
2096
2097                 names[num_names++] = "CLEARTEXT";
2098
2099                 pcb.cleartext   = *io->n.cleartext_utf16;
2100
2101                 ndr_err = ndr_push_struct_blob(
2102                         &pcb_blob, io->ac,
2103                         &pcb,
2104                         (ndr_push_flags_fn_t)ndr_push_package_PrimaryCLEARTEXTBlob);
2105                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2106                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2107                         ldb_asprintf_errstring(
2108                                 ldb,
2109                                 "setup_supplemental_field: "
2110                                 "failed to push package_PrimaryCLEARTEXTBlob: %s",
2111                                 nt_errstr(status));
2112                         return LDB_ERR_OPERATIONS_ERROR;
2113                 }
2114                 pcb_hexstr = data_blob_hex_string_upper(io->ac, &pcb_blob);
2115                 if (!pcb_hexstr) {
2116                         return ldb_oom(ldb);
2117                 }
2118                 pp->name        = "Primary:CLEARTEXT";
2119                 pp->reserved    = 1;
2120                 pp->data        = pcb_hexstr;
2121                 pp++;
2122                 num_packages++;
2123         }
2124
2125         /*
2126          * Don't generate crypt() or similar password for the krbtgt account.
2127          * It's unnecessary, and the length of the cleartext in UTF-8 form
2128          * exceeds the maximum (CRYPT_MAX_PASSPHRASE_SIZE) allowed by crypt().
2129          */
2130         if (io->ac->userPassword_schemes && !io->u.is_krbtgt) {
2131                 /*
2132                  * setup 'Primary:userPassword' element
2133                  */
2134                 struct package_PrimaryUserPasswordBlob
2135                         p_userPassword_b;
2136                 DATA_BLOB p_userPassword_b_blob;
2137                 char *p_userPassword_b_hexstr;
2138
2139                 names[num_names++] = "userPassword";
2140
2141                 ret = setup_primary_userPassword(io,
2142                                                  old_scb,
2143                                                  &p_userPassword_b);
2144                 if (ret != LDB_SUCCESS) {
2145                         return ret;
2146                 }
2147
2148                 ndr_err = ndr_push_struct_blob(
2149                         &p_userPassword_b_blob,
2150                         io->ac,
2151                         &p_userPassword_b,
2152                         (ndr_push_flags_fn_t)
2153                         ndr_push_package_PrimaryUserPasswordBlob);
2154                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2155                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2156                         ldb_asprintf_errstring(
2157                                 ldb,
2158                                 "setup_supplemental_field: failed to push "
2159                                 "package_PrimaryUserPasswordBlob: %s",
2160                                 nt_errstr(status));
2161                         return LDB_ERR_OPERATIONS_ERROR;
2162                 }
2163                 p_userPassword_b_hexstr
2164                         = data_blob_hex_string_upper(
2165                                 io->ac,
2166                                 &p_userPassword_b_blob);
2167                 if (!p_userPassword_b_hexstr) {
2168                         return ldb_oom(ldb);
2169                 }
2170                 pp->name     = "Primary:userPassword";
2171                 pp->reserved = 1;
2172                 pp->data     = p_userPassword_b_hexstr;
2173                 pp++;
2174                 num_packages++;
2175         }
2176
2177         /*
2178          * setup 'Primary:SambaGPG' element
2179          */
2180         if (io->ac->gpg_key_ids != NULL) {
2181                 do_samba_gpg = true;
2182         }
2183         if (do_samba_gpg) {
2184                 struct package_PrimarySambaGPGBlob pgb;
2185                 DATA_BLOB pgb_blob;
2186                 char *pgb_hexstr;
2187
2188                 names[num_names++] = "SambaGPG";
2189
2190                 ret = setup_primary_samba_gpg(io, &pgb);
2191                 if (ret != LDB_SUCCESS) {
2192                         return ret;
2193                 }
2194
2195                 ndr_err = ndr_push_struct_blob(&pgb_blob, io->ac, &pgb,
2196                         (ndr_push_flags_fn_t)ndr_push_package_PrimarySambaGPGBlob);
2197                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2198                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2199                         ldb_asprintf_errstring(ldb,
2200                                         "setup_supplemental_field: failed to "
2201                                         "push package_PrimarySambaGPGBlob: %s",
2202                                         nt_errstr(status));
2203                         return LDB_ERR_OPERATIONS_ERROR;
2204                 }
2205                 pgb_hexstr = data_blob_hex_string_upper(io->ac, &pgb_blob);
2206                 if (!pgb_hexstr) {
2207                         return ldb_oom(ldb);
2208                 }
2209                 pp->name        = "Primary:SambaGPG";
2210                 pp->reserved    = 1;
2211                 pp->data        = pgb_hexstr;
2212                 pp++;
2213                 num_packages++;
2214         }
2215
2216         /*
2217          * setup 'Packages' element
2218          */
2219         {
2220                 struct package_PackagesBlob pb;
2221                 DATA_BLOB pb_blob;
2222                 char *pb_hexstr;
2223
2224                 pb.names = names;
2225                 ndr_err = ndr_push_struct_blob(
2226                         &pb_blob, io->ac,
2227                         &pb,
2228                         (ndr_push_flags_fn_t)ndr_push_package_PackagesBlob);
2229                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2230                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2231                         ldb_asprintf_errstring(
2232                                 ldb,
2233                                 "setup_supplemental_field: "
2234                                 "failed to push package_PackagesBlob: %s",
2235                                 nt_errstr(status));
2236                         return LDB_ERR_OPERATIONS_ERROR;
2237                 }
2238                 pb_hexstr = data_blob_hex_string_upper(io->ac, &pb_blob);
2239                 if (!pb_hexstr) {
2240                         return ldb_oom(ldb);
2241                 }
2242                 pp->name        = "Packages";
2243                 pp->reserved    = 2;
2244                 pp->data        = pb_hexstr;
2245                 num_packages++;
2246                 /*
2247                  * We don't increment pp so it's pointing to the last package
2248                  */
2249         }
2250
2251         /*
2252          * setup 'supplementalCredentials' value
2253          */
2254         {
2255                 /*
2256                  * The 'Packages' element needs to be the second last element
2257                  * in supplementalCredentials
2258                  */
2259                 struct supplementalCredentialsPackage temp;
2260                 struct supplementalCredentialsPackage *prev;
2261
2262                 prev = pp-1;
2263                 temp = *prev;
2264                 *prev = *pp;
2265                 *pp = temp;
2266
2267                 ZERO_STRUCT(scb);
2268                 scb.sub.signature       = SUPPLEMENTAL_CREDENTIALS_SIGNATURE;
2269                 scb.sub.num_packages    = num_packages;
2270                 scb.sub.packages        = packages;
2271
2272                 ndr_err = ndr_push_struct_blob(
2273                         &io->g.supplemental, io->ac,
2274                         &scb,
2275                         (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2276                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2277                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2278                         ldb_asprintf_errstring(
2279                                 ldb,
2280                                 "setup_supplemental_field: "
2281                                 "failed to push supplementalCredentialsBlob: %s",
2282                                 nt_errstr(status));
2283                         return LDB_ERR_OPERATIONS_ERROR;
2284                 }
2285         }
2286
2287         return LDB_SUCCESS;
2288 }
2289
2290 static int setup_last_set_field(struct setup_password_fields_io *io)
2291 {
2292         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2293         const struct ldb_message *msg = NULL;
2294         struct timeval tv = { .tv_sec = 0 };
2295         const struct ldb_val *old_val = NULL;
2296         const struct ldb_val *new_val = NULL;
2297         int ret;
2298
2299         switch (io->ac->req->operation) {
2300         case LDB_ADD:
2301                 msg = io->ac->req->op.add.message;
2302                 break;
2303         case LDB_MODIFY:
2304                 msg = io->ac->req->op.mod.message;
2305                 break;
2306         default:
2307                 return LDB_ERR_OPERATIONS_ERROR;
2308                 break;
2309         }
2310
2311         if (io->ac->pwd_last_set_bypass) {
2312                 struct ldb_message_element *el = NULL;
2313                 size_t i;
2314                 size_t count = 0;
2315                 /*
2316                  * This is a message from pdb_samba_dsdb_replace_by_sam()
2317                  *
2318                  * We want to ensure there is only one pwdLastSet element, and
2319                  * it isn't deleting.
2320                  */
2321                 if (msg == NULL) {
2322                         return LDB_ERR_CONSTRAINT_VIOLATION;
2323                 }
2324
2325                 for (i = 0; i < msg->num_elements; i++) {
2326                         if (ldb_attr_cmp(msg->elements[i].name,
2327                                          "pwdLastSet") == 0) {
2328                                 count++;
2329                                 el = &msg->elements[i];
2330                         }
2331                 }
2332                 if (count != 1) {
2333                         return LDB_ERR_CONSTRAINT_VIOLATION;
2334                 }
2335
2336                 if (LDB_FLAG_MOD_TYPE(el->flags) == LDB_FLAG_MOD_DELETE) {
2337                         return LDB_ERR_CONSTRAINT_VIOLATION;
2338                 }
2339
2340                 io->g.last_set = samdb_result_nttime(msg, "pwdLastSet", 0);
2341                 return LDB_SUCCESS;
2342         }
2343
2344         ret = msg_find_old_and_new_pwd_val(msg, "pwdLastSet",
2345                                            io->ac->req->operation,
2346                                            &new_val, &old_val);
2347         if (ret != LDB_SUCCESS) {
2348                 return ret;
2349         }
2350
2351         if (old_val != NULL && new_val == NULL) {
2352                 ldb_set_errstring(ldb,
2353                                   "'pwdLastSet' deletion is not allowed!");
2354                 return LDB_ERR_UNWILLING_TO_PERFORM;
2355         }
2356
2357         io->g.last_set = UINT64_MAX;
2358         if (new_val != NULL) {
2359                 struct ldb_message *tmp_msg = NULL;
2360
2361                 tmp_msg = ldb_msg_new(io->ac);
2362                 if (tmp_msg == NULL) {
2363                         return ldb_module_oom(io->ac->module);
2364                 }
2365
2366                 if (old_val != NULL) {
2367                         NTTIME old_last_set = 0;
2368
2369                         ret = ldb_msg_add_value(tmp_msg, "oldval",
2370                                                 old_val, NULL);
2371                         if (ret != LDB_SUCCESS) {
2372                                 return ret;
2373                         }
2374
2375                         old_last_set = samdb_result_nttime(tmp_msg,
2376                                                            "oldval",
2377                                                            1);
2378                         if (io->u.pwdLastSet != old_last_set) {
2379                                 return dsdb_module_werror(io->ac->module,
2380                                         LDB_ERR_NO_SUCH_ATTRIBUTE,
2381                                         WERR_DS_CANT_REM_MISSING_ATT_VAL,
2382                                         "setup_last_set_field: old pwdLastSet "
2383                                         "value not found!");
2384                         }
2385                 }
2386
2387                 ret = ldb_msg_add_value(tmp_msg, "newval",
2388                                         new_val, NULL);
2389                 if (ret != LDB_SUCCESS) {
2390                         return ret;
2391                 }
2392
2393                 io->g.last_set = samdb_result_nttime(tmp_msg,
2394                                                      "newval",
2395                                                      1);
2396         } else if (ldb_msg_find_element(msg, "pwdLastSet")) {
2397                 ldb_set_errstring(ldb,
2398                                   "'pwdLastSet' deletion is not allowed!");
2399                 return LDB_ERR_UNWILLING_TO_PERFORM;
2400         } else if (io->ac->smartcard_reset) {
2401                 /*
2402                  * adding UF_SMARTCARD_REQUIRED doesn't update
2403                  * pwdLastSet implicitly.
2404                  */
2405                 io->ac->update_lastset = false;
2406         }
2407
2408         /* only 0 or -1 (0xFFFFFFFFFFFFFFFF) are allowed */
2409         switch (io->g.last_set) {
2410         case 0:
2411                 if (!io->ac->pwd_last_set_default) {
2412                         break;
2413                 }
2414                 if (!io->ac->update_password) {
2415                         break;
2416                 }
2417                 FALL_THROUGH;
2418         case UINT64_MAX:
2419                 if (!io->ac->update_password &&
2420                     io->u.pwdLastSet != 0 &&
2421                     io->u.pwdLastSet != UINT64_MAX)
2422                 {
2423                         /*
2424                          * Just setting pwdLastSet to -1, while not changing
2425                          * any password field has no effect if pwdLastSet
2426                          * is already non-zero.
2427                          */
2428                         io->ac->update_lastset = false;
2429                         break;
2430                 }
2431                 /* -1 means set it as now */
2432                 GetTimeOfDay(&tv);
2433                 io->g.last_set = timeval_to_nttime(&tv);
2434                 break;
2435         default:
2436                 return dsdb_module_werror(io->ac->module,
2437                                           LDB_ERR_OTHER,
2438                                           WERR_INVALID_PARAMETER,
2439                                           "setup_last_set_field: "
2440                                           "pwdLastSet must be 0 or -1 only!");
2441         }
2442
2443         if (io->ac->req->operation == LDB_ADD) {
2444                 /*
2445                  * We always need to store the value on add
2446                  * operations.
2447                  */
2448                 return LDB_SUCCESS;
2449         }
2450
2451         if (io->g.last_set == io->u.pwdLastSet) {
2452                 /*
2453                  * Just setting pwdLastSet to 0, is no-op if it's already 0.
2454                  */
2455                 io->ac->update_lastset = false;
2456         }
2457
2458         return LDB_SUCCESS;
2459 }
2460
2461 static int setup_given_passwords(struct setup_password_fields_io *io,
2462                                  struct setup_password_fields_given *g)
2463 {
2464         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2465
2466         if (g->cleartext_utf8) {
2467                 struct ldb_val *cleartext_utf16_blob;
2468
2469                 cleartext_utf16_blob = talloc(io->ac, struct ldb_val);
2470                 if (!cleartext_utf16_blob) {
2471                         return ldb_oom(ldb);
2472                 }
2473                 if (!convert_string_talloc(io->ac,
2474                                            CH_UTF8, CH_UTF16,
2475                                            g->cleartext_utf8->data,
2476                                            g->cleartext_utf8->length,
2477                                            (void *)&cleartext_utf16_blob->data,
2478                                            &cleartext_utf16_blob->length)) {
2479                         if (g->cleartext_utf8->length != 0) {
2480                                 talloc_free(cleartext_utf16_blob);
2481                                 ldb_asprintf_errstring(ldb,
2482                                                        "setup_password_fields: "
2483                                                        "failed to generate UTF16 password from cleartext UTF8 one for user '%s'!",
2484                                                        io->u.sAMAccountName);
2485                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2486                         } else {
2487                                 /* passwords with length "0" are valid! */
2488                                 cleartext_utf16_blob->data = NULL;
2489                                 cleartext_utf16_blob->length = 0;
2490                         }
2491                 }
2492                 g->cleartext_utf16 = cleartext_utf16_blob;
2493         } else if (g->cleartext_utf16) {
2494                 struct ldb_val *cleartext_utf8_blob;
2495
2496                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
2497                 if (!cleartext_utf8_blob) {
2498                         return ldb_oom(ldb);
2499                 }
2500                 if (!convert_string_talloc(io->ac,
2501                                            CH_UTF16MUNGED, CH_UTF8,
2502                                            g->cleartext_utf16->data,
2503                                            g->cleartext_utf16->length,
2504                                            (void *)&cleartext_utf8_blob->data,
2505                                            &cleartext_utf8_blob->length)) {
2506                         if (g->cleartext_utf16->length != 0) {
2507                                 /* We must bail out here, the input wasn't even
2508                                  * a multiple of 2 bytes */
2509                                 talloc_free(cleartext_utf8_blob);
2510                                 ldb_asprintf_errstring(ldb,
2511                                                        "setup_password_fields: "
2512                                                        "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)!",
2513                                                        io->u.sAMAccountName);
2514                                 return LDB_ERR_CONSTRAINT_VIOLATION;
2515                         } else {
2516                                 /* passwords with length "0" are valid! */
2517                                 cleartext_utf8_blob->data = NULL;
2518                                 cleartext_utf8_blob->length = 0;
2519                         }
2520                 }
2521                 g->cleartext_utf8 = cleartext_utf8_blob;
2522         }
2523
2524         if (g->cleartext_utf16) {
2525                 struct samr_Password *nt_hash;
2526
2527                 nt_hash = talloc(io->ac, struct samr_Password);
2528                 if (!nt_hash) {
2529                         return ldb_oom(ldb);
2530                 }
2531                 g->nt_hash = nt_hash;
2532
2533                 /* compute the new nt hash */
2534                 mdfour(nt_hash->hash,
2535                        g->cleartext_utf16->data,
2536                        g->cleartext_utf16->length);
2537         }
2538
2539         /*
2540          * We need to build one more hash, so we can compare with what might
2541          * have been stored in the old password (for the LDAP password change)
2542          *
2543          * We don't have any old salts, so we won't catch password reuse if said
2544          * password was used prior to an account rename and another password
2545          * change.
2546          *
2547          * We don't have to store the 'opaque' (string2key iterations)
2548          * as Heimdal doesn't allow that to be changed.
2549          */
2550         if (g->cleartext_utf8 != NULL) {
2551                 int ret = setup_kerberos_key_hash(io, g);
2552                 if (ret != LDB_SUCCESS) {
2553                         return ret;
2554                 }
2555         }
2556
2557         return LDB_SUCCESS;
2558 }
2559
2560 static int setup_password_fields(struct setup_password_fields_io *io)
2561 {
2562         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2563         int ret;
2564
2565         ret = setup_last_set_field(io);
2566         if (ret != LDB_SUCCESS) {
2567                 return ret;
2568         }
2569
2570         if (!io->ac->update_password) {
2571                 return LDB_SUCCESS;
2572         }
2573
2574         if (io->u.is_krbtgt) {
2575                 size_t min = 196;
2576                 size_t max = 255;
2577                 size_t diff = max - min;
2578                 size_t len = max;
2579                 struct ldb_val *krbtgt_utf16 = NULL;
2580
2581                 if (!io->ac->pwd_reset) {
2582                         return dsdb_module_werror(io->ac->module,
2583                                         LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
2584                                         WERR_DS_ATT_ALREADY_EXISTS,
2585                                         "Password change on krbtgt not permitted!");
2586                 }
2587
2588                 if (io->n.cleartext_utf16 == NULL) {
2589                         return dsdb_module_werror(io->ac->module,
2590                                         LDB_ERR_UNWILLING_TO_PERFORM,
2591                                         WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
2592                                         "Password reset on krbtgt requires UTF16!");
2593                 }
2594
2595                 /*
2596                  * Instead of taking the callers value,
2597                  * we just generate a new random value here.
2598                  *
2599                  * Include null termination in the array.
2600                  */
2601                 if (diff > 0) {
2602                         size_t tmp;
2603
2604                         generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
2605
2606                         tmp %= diff;
2607
2608                         len = min + tmp;
2609                 }
2610
2611                 krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
2612                 if (krbtgt_utf16 == NULL) {
2613                         return ldb_oom(ldb);
2614                 }
2615
2616                 *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
2617                                                       (len+1)*2);
2618                 if (krbtgt_utf16->data == NULL) {
2619                         return ldb_oom(ldb);
2620                 }
2621                 krbtgt_utf16->length = len * 2;
2622                 generate_secret_buffer(krbtgt_utf16->data,
2623                                        krbtgt_utf16->length);
2624                 io->n.cleartext_utf16 = krbtgt_utf16;
2625         }
2626
2627         /* transform the old password (for password changes) */
2628         ret = setup_given_passwords(io, &io->og);
2629         if (ret != LDB_SUCCESS) {
2630                 return ret;
2631         }
2632
2633         /* transform the new password */
2634         ret = setup_given_passwords(io, &io->n);
2635         if (ret != LDB_SUCCESS) {
2636                 return ret;
2637         }
2638
2639         if (io->n.cleartext_utf8) {
2640                 ret = setup_kerberos_keys(io);
2641                 if (ret != LDB_SUCCESS) {
2642                         return ret;
2643                 }
2644         }
2645
2646         /*
2647          * This relies on setup_kerberos_keys to make a NT-hash-like
2648          * value for password history purposes
2649          */
2650
2651         ret = setup_nt_fields(io);
2652         if (ret != LDB_SUCCESS) {
2653                 return ret;
2654         }
2655
2656         ret = setup_supplemental_field(io);
2657         if (ret != LDB_SUCCESS) {
2658                 return ret;
2659         }
2660
2661         return LDB_SUCCESS;
2662 }
2663
2664 static int setup_smartcard_reset(struct setup_password_fields_io *io)
2665 {
2666         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2667         struct supplementalCredentialsBlob scb = { .__ndr_size = 0 };
2668         enum ndr_err_code ndr_err;
2669
2670         if (!io->ac->smartcard_reset) {
2671                 return LDB_SUCCESS;
2672         }
2673
2674         io->g.nt_hash = talloc(io->ac, struct samr_Password);
2675         if (io->g.nt_hash == NULL) {
2676                 return ldb_module_oom(io->ac->module);
2677         }
2678         generate_secret_buffer(io->g.nt_hash->hash,
2679                                sizeof(io->g.nt_hash->hash));
2680         io->g.nt_history_len = 0;
2681
2682         /*
2683          * We take the "old" value and store it
2684          * with num_packages = 0.
2685          *
2686          * On "add" we have scb.sub.signature == 0, which
2687          * results in:
2688          *
2689          * [0000] 00 00 00 00 00 00 00 00   00 00 00 00 00
2690          *
2691          * On modify it's likely to be scb.sub.signature ==
2692          * SUPPLEMENTAL_CREDENTIALS_SIGNATURE (0x0050), which results in
2693          * something like:
2694          *
2695          * [0000] 00 00 00 00 62 00 00 00   00 00 00 00 20 00 20 00
2696          * [0010] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2697          * [0020] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2698          * [0030] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2699          * [0040] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2700          * [0050] 20 00 20 00 20 00 20 00   20 00 20 00 20 00 20 00
2701          * [0060] 20 00 20 00 20 00 20 00   20 00 20 00 50 00 00
2702          *
2703          * See https://bugzilla.samba.org/show_bug.cgi?id=11441
2704          * and ndr_{push,pull}_supplementalCredentialsSubBlob().
2705          */
2706         scb = io->o.scb;
2707         scb.sub.num_packages = 0;
2708
2709         /*
2710          * setup 'supplementalCredentials' value without packages
2711          */
2712         ndr_err = ndr_push_struct_blob(&io->g.supplemental, io->ac,
2713                                        &scb,
2714                                        (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
2715         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2716                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
2717                 ldb_asprintf_errstring(ldb,
2718                                        "setup_smartcard_reset: "
2719                                        "failed to push supplementalCredentialsBlob: %s",
2720                                        nt_errstr(status));
2721                 return LDB_ERR_OPERATIONS_ERROR;
2722         }
2723
2724         io->ac->update_password = true;
2725         return LDB_SUCCESS;
2726 }
2727
2728 static int make_error_and_update_badPwdCount(struct setup_password_fields_io *io, WERROR *werror)
2729 {
2730         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2731         struct ldb_message *mod_msg = NULL;
2732         struct ldb_message *pso_msg = NULL;
2733         struct ldb_message *current = NULL;
2734         NTSTATUS status = NT_STATUS_OK;
2735         int ret; /* The errors we will actually return */
2736         int dbg_ret; /* The errors we can only complain about in logs */
2737
2738         /*
2739          * OK, horrible semantics ahead.
2740          *
2741          * - We need to abort any existing transaction
2742          * - create a transaction arround the badPwdCount update
2743          * - re-open the transaction so the upper layer
2744          *   doesn't know what happened.
2745          *
2746          * This is needed because returning an error to the upper
2747          * layer will cancel the transaction and undo the badPwdCount
2748          * update.
2749          */
2750
2751         /*
2752          * Checking errors here is a bit pointless.
2753          * What can we do if we can't end the transaction?
2754          */
2755         dbg_ret = ldb_next_del_trans(io->ac->module);
2756         if (dbg_ret != LDB_SUCCESS) {
2757                 ldb_debug(ldb, LDB_DEBUG_FATAL,
2758                           "Failed to abort transaction prior to update of badPwdCount of %s: %s",
2759                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2760                           ldb_errstring(ldb));
2761                 /*
2762                  * just return the original error
2763                  */
2764                 goto done;
2765         }
2766
2767         /* Likewise, what should we do if we can't open a new transaction? */
2768         dbg_ret = ldb_next_start_trans(io->ac->module);
2769         if (dbg_ret != LDB_SUCCESS) {
2770                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2771                           "Failed to open transaction to update badPwdCount of %s: %s",
2772                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2773                           ldb_errstring(ldb));
2774                 /*
2775                  * just return the original error
2776                  */
2777                 goto done;
2778         }
2779
2780         /*
2781          * Re-read the account details, using the GUID in case the DN
2782          * is being changed.
2783          */
2784         status = authsam_reread_user_logon_data(
2785                 ldb, io->ac,
2786                 io->ac->search_res->message,
2787                 &current);
2788         if (!NT_STATUS_IS_OK(status)) {
2789                 /* The re-read can return account locked out, as well
2790                  * as an internal error
2791                  */
2792                 goto end_transaction;
2793         }
2794
2795         /* PSO search result is optional (NULL if no PSO applies) */
2796         if (io->ac->pso_res != NULL) {
2797                 pso_msg = io->ac->pso_res->message;
2798         }
2799
2800         status = dsdb_update_bad_pwd_count(io->ac, ldb,
2801                                            current,
2802                                            io->ac->dom_res->message,
2803                                            pso_msg,
2804                                            &mod_msg);
2805         if (!NT_STATUS_IS_OK(status)) {
2806                 goto end_transaction;
2807         }
2808
2809         if (mod_msg == NULL) {
2810                 goto end_transaction;
2811         }
2812
2813         dbg_ret = dsdb_module_modify(io->ac->module, mod_msg,
2814                                  DSDB_FLAG_NEXT_MODULE,
2815                                  io->ac->req);
2816         if (dbg_ret != LDB_SUCCESS) {
2817                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2818                           "Failed to update badPwdCount of %s: %s",
2819                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2820                           ldb_errstring(ldb));
2821                 /*
2822                  * We can only ignore this...
2823                  */
2824         }
2825
2826 end_transaction:
2827         dbg_ret = ldb_next_end_trans(io->ac->module);
2828         if (dbg_ret != LDB_SUCCESS) {
2829                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2830                           "Failed to close transaction to update badPwdCount of %s: %s",
2831                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2832                           ldb_errstring(ldb));
2833                 /*
2834                  * We can only ignore this...
2835                  */
2836         }
2837
2838         dbg_ret = ldb_next_start_trans(io->ac->module);
2839         if (dbg_ret != LDB_SUCCESS) {
2840                 ldb_debug(ldb, LDB_DEBUG_ERROR,
2841                           "Failed to open transaction after update of badPwdCount of %s: %s",
2842                           ldb_dn_get_linearized(io->ac->search_res->message->dn),
2843                           ldb_errstring(ldb));
2844                 /*
2845                  * We can only ignore this...
2846                  */
2847         }
2848
2849 done:
2850         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2851         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCOUNT_LOCKED_OUT)) {
2852                 *werror = WERR_ACCOUNT_LOCKED_OUT;
2853         } else {
2854                 *werror = WERR_INVALID_PASSWORD;
2855         }
2856         ldb_asprintf_errstring(ldb,
2857                                "%08X: %s - check_password_restrictions: "
2858                                "The old password specified doesn't match!",
2859                                W_ERROR_V(*werror),
2860                                ldb_strerror(ret));
2861         return ret;
2862 }
2863
2864 static int check_password_restrictions(struct setup_password_fields_io *io, WERROR *werror)
2865 {
2866         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
2867         int ret;
2868         uint32_t i;
2869         struct loadparm_context *lp_ctx =
2870                 talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
2871                                 struct loadparm_context);
2872
2873         *werror = WERR_INVALID_PARAMETER;
2874
2875         if (!io->ac->update_password) {
2876                 return LDB_SUCCESS;
2877         }
2878
2879         /*
2880          * First check the old password is correct, for password
2881          * changes when this hasn't already been checked by a
2882          * trustwrothy layer above
2883          */
2884         if (!io->ac->pwd_reset && !(io->ac->change
2885                                     && io->ac->change->old_password_checked == DSDB_PASSWORD_CHECKED_AND_CORRECT)) {
2886                 bool hash_checked = false;
2887                 /*
2888                  * we need the old nt hash given by the client (this
2889                  * is for the plaintext over LDAP password change,
2890                  * Kpasswd and SAMR supply the control)
2891                  */
2892                 if (io->og.nt_hash == NULL && io->og.aes_256.length == 0) {
2893                         ldb_asprintf_errstring(ldb,
2894                                 "check_password_restrictions: "
2895                                 "You need to provide the old password in order "
2896                                 "to change it!");
2897                         return LDB_ERR_UNWILLING_TO_PERFORM;
2898                 }
2899
2900                 /*
2901                  * First compare the ENCTYPE_AES256_CTS_HMAC_SHA1_96 password and see if we have a match
2902                  */
2903
2904                 if (io->og.aes_256.length > 0 && io->o.aes_256.length) {
2905                         hash_checked = data_blob_equal_const_time(&io->og.aes_256, &io->o.aes_256);
2906                 }
2907
2908                 /* The password modify through the NT hash is encouraged and
2909                    has no problems at all */
2910                 if (!hash_checked && io->og.nt_hash && io->o.nt_hash) {
2911                         hash_checked = mem_equal_const_time(io->og.nt_hash->hash, io->o.nt_hash->hash, 16);
2912                 }
2913
2914                 if (!hash_checked) {
2915                         return make_error_and_update_badPwdCount(io, werror);
2916                 }
2917         }
2918
2919         if (io->u.restrictions == 0) {
2920                 /* FIXME: Is this right? */
2921                 return LDB_SUCCESS;
2922         }
2923
2924         /* Password minimum age: yes, this is a minus. The ages are in negative 100nsec units! */
2925         if ((io->u.pwdLastSet - io->ac->status->domain_data.minPwdAge > io->g.last_set) &&
2926             !io->ac->pwd_reset)
2927         {
2928                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
2929                 *werror = WERR_PASSWORD_RESTRICTION;
2930                 ldb_asprintf_errstring(ldb,
2931                         "%08X: %s - check_password_restrictions: "
2932                         "password is too young to change!",
2933                         W_ERROR_V(*werror),
2934                         ldb_strerror(ret));
2935                 return ret;
2936         }
2937
2938         /*
2939          * Fundamental password checks done by the call
2940          * "samdb_check_password".
2941          * It is also in use by "dcesrv_samr_ValidatePassword".
2942          */
2943         if (io->n.cleartext_utf8 != NULL) {
2944                 enum samr_ValidationStatus vstat;
2945                 vstat = samdb_check_password(io->ac, lp_ctx,
2946                                              io->u.sAMAccountName,
2947                                              io->u.user_principal_name,
2948                                              io->u.displayName,
2949                                              io->n.cleartext_utf8,
2950                                              io->ac->status->domain_data.pwdProperties,
2951                                              io->ac->status->domain_data.minPwdLength);
2952                 switch (vstat) {
2953                 case SAMR_VALIDATION_STATUS_SUCCESS:
2954                                 /* perfect -> proceed! */
2955                         break;
2956
2957                 case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT:
2958                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2959                         *werror = WERR_PASSWORD_RESTRICTION;
2960                         ldb_asprintf_errstring(ldb,
2961                                 "%08X: %s - check_password_restrictions: "
2962                                 "the password is too short. It should be equal or longer than %u characters!",
2963                                 W_ERROR_V(*werror),
2964                                 ldb_strerror(ret),
2965                                 io->ac->status->domain_data.minPwdLength);
2966                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PASSWORD_TOO_SHORT;
2967                         return ret;
2968
2969                 case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH:
2970                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2971                         *werror = WERR_PASSWORD_RESTRICTION;
2972                         ldb_asprintf_errstring(ldb,
2973                                 "%08X: %s - check_password_restrictions: "
2974                                 "the password does not meet the complexity criteria!",
2975                                 W_ERROR_V(*werror),
2976                                 ldb_strerror(ret));
2977                         io->ac->status->reject_reason = SAM_PWD_CHANGE_NOT_COMPLEX;
2978                         return ret;
2979
2980                 default:
2981                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
2982                         *werror = WERR_PASSWORD_RESTRICTION;
2983                         ldb_asprintf_errstring(ldb,
2984                                 "%08X: %s - check_password_restrictions: "
2985                                 "the password doesn't fit due to a miscellaneous restriction!",
2986                                 W_ERROR_V(*werror),
2987                                 ldb_strerror(ret));
2988                         return ret;
2989                 }
2990         }
2991
2992         if (io->ac->pwd_reset) {
2993                 *werror = WERR_OK;
2994                 return LDB_SUCCESS;
2995         }
2996
2997         /*
2998          * This check works by using the current Kerberos password to
2999          * make up a password history.  We already did the salted hash
3000          * creation to pass the password change check.
3001          *
3002          * We check the pwdHistoryLength to ensure we honour the
3003          * policy on if the history should be checked
3004          */
3005         if (io->ac->status->domain_data.pwdHistoryLength > 0
3006             && io->g.aes_256.length && io->o.aes_256.length)
3007         {
3008                 bool equal = data_blob_equal_const_time(&io->g.aes_256,
3009                                                         &io->o.aes_256);
3010                 if (equal) {
3011                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3012                         *werror = WERR_PASSWORD_RESTRICTION;
3013                         ldb_asprintf_errstring(ldb,
3014                                                "%08X: %s - check_password_restrictions: "
3015                                                "the password was already used (previous password)!",
3016                                                W_ERROR_V(*werror),
3017                                                ldb_strerror(ret));
3018                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3019                         return ret;
3020                 }
3021         }
3022
3023         if (io->n.nt_hash) {
3024                 /*
3025                  * checks the NT hash password history, against the
3026                  * generated NT hash
3027                  */
3028                 for (i = 0; i < io->o.nt_history_len; i++) {
3029                         bool pw_cmp = mem_equal_const_time(io->n.nt_hash, io->o.nt_history[i].hash, 16);
3030                         if (pw_cmp) {
3031                                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3032                                 *werror = WERR_PASSWORD_RESTRICTION;
3033                                 ldb_asprintf_errstring(ldb,
3034                                         "%08X: %s - check_password_restrictions: "
3035                                         "the password was already used (in history)!",
3036                                         W_ERROR_V(*werror),
3037                                         ldb_strerror(ret));
3038                                 io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3039                                 return ret;
3040                         }
3041                 }
3042         }
3043
3044         /*
3045          * This check works by using the old Kerberos passwords
3046          * (old and older) to make up a password history.
3047          *
3048          * We check the pwdHistoryLength to ensure we honour the
3049          * policy on if the history should be checked
3050          */
3051         for (i = 1;
3052              i <= io->o.kvno && i < MIN(3, io->ac->status->domain_data.pwdHistoryLength);
3053              i++)
3054         {
3055                 krb5_error_code krb5_ret;
3056                 const uint32_t request_kvno = io->o.kvno - i;
3057                 DATA_BLOB db_key_blob;
3058                 bool pw_equal;
3059
3060                 if (io->n.cleartext_utf8 == NULL) {
3061                         /*
3062                          * No point checking history if we don't have
3063                          * a cleartext password.
3064                          */
3065                         break;
3066                 }
3067
3068                 if (io->ac->search_res == NULL) {
3069                         /*
3070                          * This is an ADD, no existing history to check
3071                          */
3072                         break;
3073                 }
3074
3075                 /*
3076                  * If this account requires a smartcard for login, we don't
3077                  * attempt a comparison with the old password.
3078                  */
3079                 if (io->u.userAccountControl & UF_SMARTCARD_REQUIRED) {
3080                         break;
3081                 }
3082
3083                 /*
3084                  * Extract the old ENCTYPE_AES256_CTS_HMAC_SHA1_96 value from
3085                  * the supplementalCredentials.
3086                  */
3087                 krb5_ret = dsdb_extract_aes_256_key(io->smb_krb5_context->krb5_context,
3088                                                     io->ac,
3089                                                     io->ac->search_res->message,
3090                                                     io->u.userAccountControl,
3091                                                     &request_kvno, /* kvno */
3092                                                     NULL, /* kvno_out */
3093                                                     &db_key_blob,
3094                                                     NULL); /* salt */
3095                 if (krb5_ret == ENOENT) {
3096                         /*
3097                          * If there is no old AES hash (perhaps an imported DB with
3098                          * just unicodePwd) then we just wont have an old
3099                          * password to compare to if there is no NT hash
3100                          */
3101                         break;
3102                 } else if (krb5_ret) {
3103                         ldb_asprintf_errstring(ldb,
3104                                                "check_password_restrictions: "
3105                                                "extraction of old[%u - %d = %d] aes256-cts-hmac-sha1-96 key failed: %s",
3106                                                io->o.kvno, i, io->o.kvno - i,
3107                                                smb_get_krb5_error_message(io->smb_krb5_context->krb5_context,
3108                                                                           krb5_ret, io->ac));
3109                         return LDB_ERR_OPERATIONS_ERROR;
3110                 }
3111
3112                 /* This is the actual history check */
3113                 pw_equal = data_blob_equal_const_time(&io->n.aes_256,
3114                                                       &db_key_blob);
3115                 if (pw_equal) {
3116                         ret = LDB_ERR_CONSTRAINT_VIOLATION;
3117                         *werror = WERR_PASSWORD_RESTRICTION;
3118                         ldb_asprintf_errstring(ldb,
3119                                                "%08X: %s - check_password_restrictions: "
3120                                                "the password was already used (in history)!",
3121                                                W_ERROR_V(*werror),
3122                                                ldb_strerror(ret));
3123                         io->ac->status->reject_reason = SAM_PWD_CHANGE_PWD_IN_HISTORY;
3124                         return ret;
3125                 }
3126         }
3127
3128         /* are all password changes disallowed? */
3129         if (io->ac->status->domain_data.pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
3130                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3131                 *werror = WERR_PASSWORD_RESTRICTION;
3132                 ldb_asprintf_errstring(ldb,
3133                         "%08X: %s - check_password_restrictions: "
3134                         "password changes disabled!",
3135                         W_ERROR_V(*werror),
3136                         ldb_strerror(ret));
3137                 return ret;
3138         }
3139
3140         /* can this user change the password? */
3141         if (io->u.userAccountControl & UF_PASSWD_CANT_CHANGE) {
3142                 ret = LDB_ERR_CONSTRAINT_VIOLATION;
3143                 *werror = WERR_PASSWORD_RESTRICTION;
3144                 ldb_asprintf_errstring(ldb,
3145                         "%08X: %s - check_password_restrictions: "
3146                         "password can't be changed on this account!",
3147                         W_ERROR_V(*werror),
3148                         ldb_strerror(ret));
3149                 return ret;
3150         }
3151
3152         return LDB_SUCCESS;
3153 }
3154
3155 static int check_password_restrictions_and_log(struct setup_password_fields_io *io)
3156 {
3157         WERROR werror;
3158         int ret = check_password_restrictions(io, &werror);
3159         struct ph_context *ac = io->ac;
3160         /*
3161          * Password resets are not authentication events, and if the
3162          * upper layer checked the password and supplied the hash
3163          * values as proof, then this is also not an authentication
3164          * even at this layer (already logged).  This is to log LDAP
3165          * password changes.
3166          */
3167
3168         /* Do not record a failure in the auth log below in the success case */
3169         if (ret == LDB_SUCCESS) {
3170                 werror = WERR_OK;
3171         }
3172
3173         if (ac->pwd_reset == false && ac->change == NULL) {
3174                 struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3175                 struct imessaging_context *msg_ctx;
3176                 struct loadparm_context *lp_ctx
3177                         = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"),
3178                                                 struct loadparm_context);
3179                 NTSTATUS status = werror_to_ntstatus(werror);
3180                 const char *domain_name = lpcfg_sam_name(lp_ctx);
3181                 void *opaque_remote_address = NULL;
3182                 /*
3183                  * Forcing this via the NTLM auth structure is not ideal, but
3184                  * it is the most practical option right now, and ensures the
3185                  * logs are consistent, even if some elements are always NULL.
3186                  */
3187                 struct auth_usersupplied_info ui = {
3188                         .was_mapped = true,
3189                         .client = {
3190                                 .account_name = io->u.sAMAccountName,
3191                                 .domain_name = domain_name,
3192                         },
3193                         .mapped = {
3194                                 .account_name = io->u.sAMAccountName,
3195                                 .domain_name = domain_name,
3196                         },
3197                         .service_description = "LDAP Password Change",
3198                         .auth_description = "LDAP Modify",
3199                         .password_type = "plaintext"
3200                 };
3201
3202                 opaque_remote_address = ldb_get_opaque(ldb,
3203                                                        "remoteAddress");
3204                 if (opaque_remote_address == NULL) {
3205                         ldb_asprintf_errstring(ldb,
3206                                                "Failed to obtain remote address for "
3207                                                "the LDAP client while changing the "
3208                                                "password");
3209                         return LDB_ERR_OPERATIONS_ERROR;
3210                 }
3211                 ui.remote_host = talloc_get_type(opaque_remote_address,
3212                                                  struct tsocket_address);
3213
3214                 msg_ctx = imessaging_client_init(ac, lp_ctx,
3215                                                  ldb_get_event_context(ldb));
3216                 if (!msg_ctx) {
3217                         ldb_asprintf_errstring(ldb,
3218                                                "Failed to generate client messaging context in %s",
3219                                                lpcfg_imessaging_path(ac, lp_ctx));
3220                         return LDB_ERR_OPERATIONS_ERROR;
3221                 }
3222                 log_authentication_event(msg_ctx,
3223                                          lp_ctx,
3224                                          NULL,
3225                                          &ui,
3226                                          status,
3227                                          domain_name,
3228                                          io->u.sAMAccountName,
3229                                          io->u.account_sid);
3230
3231         }
3232         return ret;
3233 }
3234
3235 static int update_final_msg(struct setup_password_fields_io *io)
3236 {
3237         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
3238         int ret;
3239         int el_flags = 0;
3240         bool update_password = io->ac->update_password;
3241         bool update_scb = io->ac->update_password;
3242
3243         /*
3244          * If we add a user without initial password,
3245          * we need to add replication meta data for
3246          * following attributes:
3247          * - unicodePwd
3248          * - dBCSPwd
3249          * - ntPwdHistory
3250          * - lmPwdHistory
3251          *
3252          * If we add a user with initial password or a
3253          * password is changed of an existing user,
3254          * we need to replace the following attributes
3255          * with a forced meta data update, e.g. also
3256          * when updating an empty attribute with an empty value:
3257          * - unicodePwd
3258          * - dBCSPwd
3259          * - ntPwdHistory
3260          * - lmPwdHistory
3261          * - supplementalCredentials
3262          */
3263
3264         switch (io->ac->req->operation) {
3265         case LDB_ADD:
3266                 update_password = true;
3267                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
3268                 break;
3269         case LDB_MODIFY:
3270                 el_flags |= LDB_FLAG_MOD_REPLACE;
3271                 el_flags |= DSDB_FLAG_INTERNAL_FORCE_META_DATA;
3272                 break;
3273         default:
3274                 return ldb_module_operr(io->ac->module);
3275         }
3276
3277         if (update_password) {
3278                 ret = ldb_msg_add_empty(io->ac->update_msg,
3279                                         "unicodePwd",
3280                                         el_flags, NULL);
3281                 if (ret != LDB_SUCCESS) {
3282                         return ret;
3283                 }
3284
3285                 /*
3286                  * This wipes any old LM password after any password
3287                  * update operation.
3288                  *
3289                  * This is the same as the previous default behaviour
3290                  * of 'lanman auth = no'
3291                  */
3292                 ret = ldb_msg_add_empty(io->ac->update_msg,
3293                                         "dBCSPwd",
3294                                         el_flags, NULL);
3295                 if (ret != LDB_SUCCESS) {
3296                         return ret;
3297                 }
3298                 ret = ldb_msg_add_empty(io->ac->update_msg,
3299                                         "ntPwdHistory",
3300                                         el_flags, NULL);
3301                 if (ret != LDB_SUCCESS) {
3302                         return ret;
3303                 }
3304                 /*
3305                  * This wipes any LM password history after any password
3306                  * update operation.
3307                  *
3308                  * This is the same as the previous default behaviour
3309                  * of 'lanman auth = no'
3310                  */
3311                 ret = ldb_msg_add_empty(io->ac->update_msg,
3312                                         "lmPwdHistory",
3313                                         el_flags, NULL);
3314                 if (ret != LDB_SUCCESS) {
3315                         return ret;
3316                 }
3317         }
3318         if (update_scb) {
3319                 ret = ldb_msg_add_empty(io->ac->update_msg,
3320                                         "supplementalCredentials",
3321                                         el_flags, NULL);
3322                 if (ret != LDB_SUCCESS) {
3323                         return ret;
3324                 }
3325         }
3326         if (io->ac->update_lastset) {
3327                 ret = ldb_msg_add_empty(io->ac->update_msg,
3328                                         "pwdLastSet",
3329                                         el_flags, NULL);
3330                 if (ret != LDB_SUCCESS) {
3331                         return ret;
3332                 }
3333         }
3334
3335         if (io->g.nt_hash != NULL) {
3336                 ret = samdb_msg_add_hash(ldb, io->ac,
3337                                          io->ac->update_msg,
3338                                          "unicodePwd",
3339                                          io->g.nt_hash);
3340                 if (ret != LDB_SUCCESS) {
3341                         return ret;
3342                 }
3343         }
3344
3345         if (io->g.nt_history_len > 0) {
3346                 ret = samdb_msg_add_hashes(ldb, io->ac,
3347                                            io->ac->update_msg,
3348                                            "ntPwdHistory",
3349                                            io->g.nt_history,
3350                                            io->g.nt_history_len);
3351                 if (ret != LDB_SUCCESS) {
3352                         return ret;
3353                 }
3354         }
3355         if (io->g.supplemental.length > 0) {
3356                 ret = ldb_msg_add_value(io->ac->update_msg,
3357                                         "supplementalCredentials",
3358                                         &io->g.supplemental, NULL);
3359                 if (ret != LDB_SUCCESS) {
3360                         return ret;
3361                 }
3362         }
3363         if (io->ac->update_lastset) {
3364                 ret = samdb_msg_add_uint64(ldb, io->ac,
3365                                            io->ac->update_msg,
3366                                            "pwdLastSet",
3367                                            io->g.last_set);
3368                 if (ret != LDB_SUCCESS) {
3369                         return ret;
3370                 }
3371         }
3372
3373         return LDB_SUCCESS;
3374 }
3375
3376 /*
3377  * This is intended for use by the "password_hash" module since there
3378  * password changes can be specified through one message element with the
3379  * new password (to set) and another one with the old password (to unset).
3380  *
3381  * The first which sets a password (new value) can have flags
3382  * (LDB_FLAG_MOD_ADD, LDB_FLAG_MOD_REPLACE) but also none (on "add" operations
3383  * for entries). The latter (old value) has always specified
3384  * LDB_FLAG_MOD_DELETE.
3385  *
3386  * Returns LDB_ERR_CONSTRAINT_VIOLATION and LDB_ERR_UNWILLING_TO_PERFORM if
3387  * matching message elements are malformed in respect to the set/change rules.
3388  * Otherwise it returns LDB_SUCCESS.
3389  */
3390 static int msg_find_old_and_new_pwd_val(const struct ldb_message *msg,
3391                                         const char *name,
3392                                         enum ldb_request_type operation,
3393                                         const struct ldb_val **new_val,
3394                                         const struct ldb_val **old_val)
3395 {
3396         unsigned int i;
3397
3398         *new_val = NULL;
3399         *old_val = NULL;
3400
3401         if (msg == NULL) {
3402                 return LDB_SUCCESS;
3403         }
3404
3405         for (i = 0; i < msg->num_elements; i++) {
3406                 if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
3407                         continue;
3408                 }
3409
3410                 if ((operation == LDB_MODIFY) &&
3411                     (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_DELETE)) {
3412                         /* 0 values are allowed */
3413                         if (msg->elements[i].num_values == 1) {
3414                                 *old_val = &msg->elements[i].values[0];
3415                         } else if (msg->elements[i].num_values > 1) {
3416                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3417                         }
3418                 } else if ((operation == LDB_MODIFY) &&
3419                            (LDB_FLAG_MOD_TYPE(msg->elements[i].flags) == LDB_FLAG_MOD_REPLACE)) {
3420                         if (msg->elements[i].num_values > 0) {
3421                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3422                         } else {
3423                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3424                         }
3425                 } else {
3426                         /* Add operations and LDB_FLAG_MOD_ADD */
3427                         if (msg->elements[i].num_values > 0) {
3428                                 *new_val = &msg->elements[i].values[msg->elements[i].num_values - 1];
3429                         } else {
3430                                 return LDB_ERR_CONSTRAINT_VIOLATION;
3431                         }
3432                 }
3433         }
3434
3435         return LDB_SUCCESS;
3436 }
3437
3438 static int setup_io(struct ph_context *ac, 
3439                     const struct ldb_message *client_msg,
3440                     const struct ldb_message *existing_msg,
3441                     struct setup_password_fields_io *io) 
3442
3443         const struct ldb_val *quoted_utf16, *old_quoted_utf16, *lm_hash, *old_lm_hash;
3444         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
3445         struct loadparm_context *lp_ctx = talloc_get_type(
3446                 ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
3447         enum store_nt_hash store_hash_setting =
3448                 lpcfg_nt_hash_store(lp_ctx);
3449         int ret;
3450         const struct ldb_message *info_msg = NULL;
3451         struct dom_sid *account_sid = NULL;
3452         int rodc_krbtgt = 0;
3453
3454         ZERO_STRUCTP(io);
3455
3456         /* Some operations below require kerberos contexts */
3457
3458         if (existing_msg != NULL) {
3459                 /*
3460                  * This is a modify operation
3461                  */
3462                 info_msg = existing_msg;
3463         } else {
3464                 /*
3465                  * This is an add operation
3466                  */
3467                 info_msg = client_msg;
3468         }
3469
3470         ret = smb_krb5_init_context(ac,
3471                                   (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
3472                                   &io->smb_krb5_context);
3473
3474         if (ret != 0) {
3475                 /*
3476                  * In the special case of mit krb5.conf vs heimdal, the includedir
3477                  * statement causes ret == 22 (KRB5_CONFIG_BADFORMAT) to be returned.
3478                  * We look for this case so that we can give a more instructional
3479                  * message to the administrator.
3480                  */
3481                 if (ret == KRB5_CONFIG_BADFORMAT || ret == EINVAL) {
3482                         ldb_asprintf_errstring(ldb, "Failed to setup krb5_context: %s - "
3483                                 "This could be due to an invalid krb5 configuration. "
3484                                 "Please check your system's krb5 configuration is correct.",
3485                                 error_message(ret));
3486                 } else {
3487                         ldb_asprintf_errstring(ldb, "Failed to setup krb5_context: %s",
3488                                 error_message(ret));
3489                 }
3490                 return LDB_ERR_OPERATIONS_ERROR;
3491         }
3492
3493         io->ac                          = ac;
3494
3495         io->u.userAccountControl        = ldb_msg_find_attr_as_uint(info_msg,
3496                                                                     "userAccountControl", 0);
3497         if (info_msg == existing_msg) {
3498                 /*
3499                  * We only take pwdLastSet from the existing object
3500                  * otherwise we leave it as 0.
3501                  *
3502                  * If no attribute is available, e.g. on deleted objects
3503                  * we remember that as UINT64_MAX.
3504                  */
3505                 io->u.pwdLastSet = samdb_result_nttime(info_msg, "pwdLastSet",
3506                                                        UINT64_MAX);
3507         }
3508         io->u.sAMAccountName            = ldb_msg_find_attr_as_string(info_msg,
3509                                                                       "sAMAccountName", NULL);
3510         io->u.user_principal_name       = ldb_msg_find_attr_as_string(info_msg,
3511                                                                       "userPrincipalName", NULL);
3512         io->u.displayName               = ldb_msg_find_attr_as_string(info_msg,
3513                                                                       "displayName", NULL);
3514
3515         /* Ensure it has an objectSID too */
3516         io->u.account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
3517         if (io->u.account_sid != NULL) {
3518                 NTSTATUS status;
3519                 uint32_t rid = 0;
3520
3521                 status = dom_sid_split_rid(account_sid, io->u.account_sid, NULL, &rid);
3522                 if (NT_STATUS_IS_OK(status)) {
3523                         if (rid == DOMAIN_RID_KRBTGT) {
3524                                 io->u.is_krbtgt = true;
3525                         }
3526                 }
3527         }
3528
3529         rodc_krbtgt = ldb_msg_find_attr_as_int(info_msg,
3530                         "msDS-SecondaryKrbTgtNumber", 0);
3531         if (rodc_krbtgt != 0) {
3532                 io->u.is_krbtgt = true;
3533         }
3534
3535         if (io->u.sAMAccountName == NULL) {
3536                 ldb_asprintf_errstring(ldb,
3537                                        "setup_io: sAMAccountName attribute is missing on %s for attempted password set/change",
3538                                        ldb_dn_get_linearized(info_msg->dn));
3539
3540                 return LDB_ERR_CONSTRAINT_VIOLATION;
3541         }
3542
3543         if (io->u.userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
3544                 struct ldb_control *permit_trust = ldb_request_get_control(ac->req,
3545                                 DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID);
3546
3547                 if (permit_trust == NULL) {
3548                         ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
3549                         ldb_asprintf_errstring(ldb,
3550                                 "%08X: %s - setup_io: changing the interdomain trust password "
3551                                 "on %s not allowed via LDAP. Use LSA or NETLOGON",
3552                                 W_ERROR_V(WERR_ACCESS_DENIED),
3553                                 ldb_strerror(ret),
3554                                 ldb_dn_get_linearized(info_msg->dn));
3555                         return ret;
3556                 }
3557         }
3558
3559         /* Only non-trust accounts have restrictions (possibly this test is the
3560          * wrong way around, but we like to be restrictive if possible */
3561         io->u.restrictions = !(io->u.userAccountControl & UF_TRUST_ACCOUNT_MASK);
3562
3563         if (io->u.is_krbtgt) {
3564                 io->u.restrictions = 0;
3565                 io->ac->status->domain_data.pwdHistoryLength =
3566                         MAX(io->ac->status->domain_data.pwdHistoryLength, 3);
3567         }
3568
3569         /*
3570          * Machine accounts need the NT hash to operate the NETLOGON
3571          * ServerAuthenticate{,2,3} logic
3572          */
3573         if (!(io->u.userAccountControl & UF_NORMAL_ACCOUNT)) {
3574                 store_hash_setting = NT_HASH_STORE_ALWAYS;
3575         }
3576
3577         switch (store_hash_setting) {
3578         case NT_HASH_STORE_ALWAYS:
3579                 io->u.store_nt_hash = true;
3580                 break;
3581         case NT_HASH_STORE_NEVER:
3582                 io->u.store_nt_hash = false;
3583                 break;
3584         case NT_HASH_STORE_AUTO:
3585                 if (lpcfg_ntlm_auth(lp_ctx) == NTLM_AUTH_DISABLED) {
3586                         io->u.store_nt_hash = false;
3587                         break;
3588                 }
3589                 io->u.store_nt_hash = true;
3590                 break;
3591         }
3592
3593         if (ac->userPassword) {
3594                 ret = msg_find_old_and_new_pwd_val(client_msg, "userPassword",
3595                                                    ac->req->operation,
3596                                                    &io->n.cleartext_utf8,
3597                                                    &io->og.cleartext_utf8);
3598                 if (ret != LDB_SUCCESS) {
3599                         ldb_asprintf_errstring(ldb,
3600                                 "setup_io: "
3601                                 "it's only allowed to set the old password once!");
3602                         return ret;
3603                 }
3604         }
3605
3606         if (io->n.cleartext_utf8 != NULL) {
3607                 struct ldb_val *cleartext_utf8_blob;
3608                 char *p;
3609
3610                 cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
3611                 if (!cleartext_utf8_blob) {
3612                         return ldb_oom(ldb);
3613                 }
3614
3615                 *cleartext_utf8_blob = *io->n.cleartext_utf8;
3616
3617                 /* make sure we have a null terminated string */
3618                 p = talloc_strndup(cleartext_utf8_blob,
3619                                    (const char *)io->n.cleartext_utf8->data,
3620                                    io->n.cleartext_utf8->length);
3621                 if ((p == NULL) && (io->n.cleartext_utf8->length > 0)) {
3622                         return ldb_oom(ldb);
3623                 }
3624                 cleartext_utf8_blob->data = (uint8_t *)p;
3625
3626                 io->n.cleartext_utf8 = cleartext_utf8_blob;
3627         }
3628
3629         ret = msg_find_old_and_new_pwd_val(client_msg, "clearTextPassword",
3630                                            ac->req->operation,
3631                                            &io->n.cleartext_utf16,
3632                                            &io->og.cleartext_utf16);
3633         if (ret != LDB_SUCCESS) {
3634                 ldb_asprintf_errstring(ldb,
3635                         "setup_io: "
3636                         "it's only allowed to set the old password once!");
3637                 return ret;
3638         }
3639
3640         /* this rather strange looking piece of code is there to
3641            handle a ldap client setting a password remotely using the
3642            unicodePwd ldap field. The syntax is that the password is
3643            in UTF-16LE, with a " at either end. Unfortunately the
3644            unicodePwd field is also used to store the nt hashes
3645            internally in Samba, and is used in the nt hash format on
3646            the wire in DRS replication, so we have a single name for
3647            two distinct values. The code below leaves us with a small
3648            chance (less than 1 in 2^32) of a mixup, if someone manages
3649            to create a MD4 hash which starts and ends in 0x22 0x00, as
3650            that would then be treated as a UTF16 password rather than
3651            a nthash */
3652
3653         ret = msg_find_old_and_new_pwd_val(client_msg, "unicodePwd",
3654                                            ac->req->operation,
3655                                            &quoted_utf16,
3656                                            &old_quoted_utf16);
3657         if (ret != LDB_SUCCESS) {
3658                 ldb_asprintf_errstring(ldb,
3659                         "setup_io: "
3660                         "it's only allowed to set the old password once!");
3661                 return ret;
3662         }
3663
3664         /* Checks and converts the actual "unicodePwd" attribute */
3665         if (!ac->hash_values &&
3666             quoted_utf16 &&
3667             quoted_utf16->length >= 4 &&
3668             quoted_utf16->data[0] == '"' &&
3669             quoted_utf16->data[1] == 0 &&
3670             quoted_utf16->data[quoted_utf16->length-2] == '"' &&
3671             quoted_utf16->data[quoted_utf16->length-1] == 0) {
3672                 struct ldb_val *quoted_utf16_2;
3673
3674                 if (io->n.cleartext_utf16) {
3675                         /* refuse the change if someone wants to change with
3676                            with both UTF16 possibilities at the same time... */
3677                         ldb_asprintf_errstring(ldb,
3678                                 "setup_io: "
3679                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3680                         return LDB_ERR_UNWILLING_TO_PERFORM;
3681                 }
3682
3683                 /*
3684                  * adapt the quoted UTF16 string to be a real
3685                  * cleartext one
3686                  */
3687                 quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3688                 if (quoted_utf16_2 == NULL) {
3689                         return ldb_oom(ldb);
3690                 }
3691
3692                 quoted_utf16_2->data = quoted_utf16->data + 2;
3693                 quoted_utf16_2->length = quoted_utf16->length-4;
3694                 io->n.cleartext_utf16 = quoted_utf16_2;
3695                 io->n.nt_hash = NULL;
3696
3697         } else if (quoted_utf16) {
3698                 /* We have only the hash available -> so no plaintext here */
3699                 if (!ac->hash_values) {
3700                         /* refuse the change if someone wants to change
3701                            the hash without control specified... */
3702                         ldb_asprintf_errstring(ldb,
3703                                 "setup_io: "
3704                                 "it's not allowed to set the NT hash password directly'");
3705                         /* this looks odd but this is what Windows does:
3706                            returns "UNWILLING_TO_PERFORM" on wrong
3707                            password sets and "CONSTRAINT_VIOLATION" on
3708                            wrong password changes. */
3709                         if (old_quoted_utf16 == NULL) {
3710                                 return LDB_ERR_UNWILLING_TO_PERFORM;
3711                         }
3712
3713                         return LDB_ERR_CONSTRAINT_VIOLATION;
3714                 }
3715
3716                 io->n.nt_hash = talloc(io->ac, struct samr_Password);
3717                 memcpy(io->n.nt_hash->hash, quoted_utf16->data,
3718                        MIN(quoted_utf16->length, sizeof(io->n.nt_hash->hash)));
3719         }
3720
3721         /* Checks and converts the previous "unicodePwd" attribute */
3722         if (!ac->hash_values &&
3723             old_quoted_utf16 &&
3724             old_quoted_utf16->length >= 4 &&
3725             old_quoted_utf16->data[0] == '"' &&
3726             old_quoted_utf16->data[1] == 0 &&
3727             old_quoted_utf16->data[old_quoted_utf16->length-2] == '"' &&
3728             old_quoted_utf16->data[old_quoted_utf16->length-1] == 0) {
3729                 struct ldb_val *old_quoted_utf16_2;
3730
3731                 if (io->og.cleartext_utf16) {
3732                         /* refuse the change if someone wants to change with
3733                            both UTF16 possibilities at the same time... */
3734                         ldb_asprintf_errstring(ldb,
3735                                 "setup_io: "
3736                                 "it's only allowed to set the cleartext password as 'unicodePwd' or as 'clearTextPassword'");
3737                         return LDB_ERR_UNWILLING_TO_PERFORM;
3738                 }
3739
3740                 /*
3741                  * adapt the quoted UTF16 string to be a real
3742                  * cleartext one
3743                  */
3744                 old_quoted_utf16_2 = talloc(io->ac, struct ldb_val);
3745                 if (old_quoted_utf16_2 == NULL) {
3746                         return ldb_oom(ldb);
3747                 }
3748
3749                 old_quoted_utf16_2->data = old_quoted_utf16->data + 2;
3750                 old_quoted_utf16_2->length = old_quoted_utf16->length-4;
3751