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