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