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