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