7779a1752be8e093c06240c4e3835301cccb5e0f
[ira/wip.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
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 /*
24  *  Name: ldb
25  *
26  *  Component: ldb password_hash module
27  *
28  *  Description: correctly update hash values based on changes to userPassword and friends
29  *
30  *  Author: Andrew Bartlett
31  *  Author: Stefan Metzmacher
32  */
33
34 #include "includes.h"
35 #include "libcli/ldap/ldap_ndr.h"
36 #include "ldb_module.h"
37 #include "librpc/gen_ndr/misc.h"
38 #include "librpc/gen_ndr/samr.h"
39 #include "libcli/auth/libcli_auth.h"
40 #include "libcli/security/security.h"
41 #include "system/kerberos.h"
42 #include "auth/kerberos/kerberos.h"
43 #include "system/time.h"
44 #include "dsdb/samdb/samdb.h"
45 #include "../libds/common/flags.h"
46 #include "dsdb/samdb/ldb_modules/password_modules.h"
47 #include "librpc/ndr/libndr.h"
48 #include "librpc/gen_ndr/ndr_drsblobs.h"
49 #include "../lib/crypto/crypto.h"
50 #include "param/param.h"
51
52 /* If we have decided there is reason to work on this request, then
53  * setup all the password hash types correctly.
54  *
55  * If the administrator doesn't want the userPassword stored (set in the
56  * domain and per-account policies) then we must strip that out before
57  * we do the first operation.
58  *
59  * Once this is done (which could update anything at all), we
60  * calculate the password hashes.
61  *
62  * This function must not only update the unicodePwd, dBCSPwd and
63  * supplementalCredentials fields, it must also atomicly increment the
64  * msDS-KeyVersionNumber.  We should be in a transaction, so all this
65  * should be quite safe...
66  *
67  * Finally, if the administrator has requested that a password history
68  * be maintained, then this should also be written out.
69  *
70  */
71
72 struct ph_context {
73
74         struct ldb_module *module;
75         struct ldb_request *req;
76
77         struct ldb_request *dom_req;
78         struct ldb_reply *dom_res;
79
80         struct ldb_reply *search_res;
81
82         struct domain_data *domain;
83 };
84
85 struct domain_data {
86         bool store_cleartext;
87         uint_t pwdProperties;
88         uint_t pwdHistoryLength;
89         const char *netbios_domain;
90         const char *dns_domain;
91         const char *realm;
92 };
93
94 struct setup_password_fields_io {
95         struct ph_context *ac;
96         struct domain_data *domain;
97         struct smb_krb5_context *smb_krb5_context;
98
99         /* infos about the user account */
100         struct {
101                 uint32_t user_account_control;
102                 const char *sAMAccountName;
103                 const char *user_principal_name;
104                 bool is_computer;
105         } u;
106
107         /* new credentials */
108         struct {
109                 const struct ldb_val *cleartext_utf8;
110                 const struct ldb_val *cleartext_utf16;
111                 struct ldb_val quoted_utf16;
112                 struct samr_Password *nt_hash;
113                 struct samr_Password *lm_hash;
114         } n;
115
116         /* old credentials */
117         struct {
118                 uint32_t nt_history_len;
119                 struct samr_Password *nt_history;
120                 uint32_t lm_history_len;
121                 struct samr_Password *lm_history;
122                 const struct ldb_val *supplemental;
123                 struct supplementalCredentialsBlob scb;
124                 uint32_t kvno;
125         } o;
126
127         /* generated credentials */
128         struct {
129                 struct samr_Password *nt_hash;
130                 struct samr_Password *lm_hash;
131                 uint32_t nt_history_len;
132                 struct samr_Password *nt_history;
133                 uint32_t lm_history_len;
134                 struct samr_Password *lm_history;
135                 const char *salt;
136                 DATA_BLOB aes_256;
137                 DATA_BLOB aes_128;
138                 DATA_BLOB des_md5;
139                 DATA_BLOB des_crc;
140                 struct ldb_val supplemental;
141                 NTTIME last_set;
142                 uint32_t kvno;
143         } g;
144 };
145
146 /* Get the NT hash, and fill it in as an entry in the password history, 
147    and specify it into io->g.nt_hash */
148
149 static int setup_nt_fields(struct setup_password_fields_io *io)
150 {
151         struct ldb_context *ldb;
152         uint32_t i;
153
154         io->g.nt_hash = io->n.nt_hash;
155         ldb = ldb_module_get_ctx(io->ac->module);
156
157         if (io->domain->pwdHistoryLength == 0) {
158                 return LDB_SUCCESS;
159         }
160
161         /* We might not have an old NT password */
162         io->g.nt_history = talloc_array(io->ac,
163                                         struct samr_Password,
164                                         io->domain->pwdHistoryLength);
165         if (!io->g.nt_history) {
166                 ldb_oom(ldb);
167                 return LDB_ERR_OPERATIONS_ERROR;
168         }
169
170         for (i = 0; i < MIN(io->domain->pwdHistoryLength-1, io->o.nt_history_len); i++) {
171                 io->g.nt_history[i+1] = io->o.nt_history[i];
172         }
173         io->g.nt_history_len = i + 1;
174
175         if (io->g.nt_hash) {
176                 io->g.nt_history[0] = *io->g.nt_hash;
177         } else {
178                 /* 
179                  * TODO: is this correct?
180                  * the simular behavior is correct for the lm history case
181                  */
182                 E_md4hash("", io->g.nt_history[0].hash);
183         }
184
185         return LDB_SUCCESS;
186 }
187
188 /* Get the LANMAN hash, and fill it in as an entry in the password history, 
189    and specify it into io->g.lm_hash */
190
191 static int setup_lm_fields(struct setup_password_fields_io *io)
192 {
193         struct ldb_context *ldb;
194         uint32_t i;
195
196         io->g.lm_hash = io->n.lm_hash;
197         ldb = ldb_module_get_ctx(io->ac->module);
198
199         if (io->domain->pwdHistoryLength == 0) {
200                 return LDB_SUCCESS;
201         }
202
203         /* We might not have an old NT password */
204         io->g.lm_history = talloc_array(io->ac,
205                                         struct samr_Password,
206                                         io->domain->pwdHistoryLength);
207         if (!io->g.lm_history) {
208                 ldb_oom(ldb);
209                 return LDB_ERR_OPERATIONS_ERROR;
210         }
211
212         for (i = 0; i < MIN(io->domain->pwdHistoryLength-1, io->o.lm_history_len); i++) {
213                 io->g.lm_history[i+1] = io->o.lm_history[i];
214         }
215         io->g.lm_history_len = i + 1;
216
217         if (io->g.lm_hash) {
218                 io->g.lm_history[0] = *io->g.lm_hash;
219         } else {
220                 E_deshash("", io->g.lm_history[0].hash);
221         }
222
223         return LDB_SUCCESS;
224 }
225
226 static int setup_kerberos_keys(struct setup_password_fields_io *io)
227 {
228         struct ldb_context *ldb;
229         krb5_error_code krb5_ret;
230         Principal *salt_principal;
231         krb5_salt salt;
232         krb5_keyblock key;
233         krb5_data cleartext_data;
234
235         ldb = ldb_module_get_ctx(io->ac->module);
236         cleartext_data.data = io->n.cleartext_utf8->data;
237         cleartext_data.length = io->n.cleartext_utf8->length;
238
239         /* Many, many thanks to lukeh@padl.com for this
240          * algorithm, described in his Nov 10 2004 mail to
241          * samba-technical@samba.org */
242
243         /*
244          * Determine a salting principal
245          */
246         if (io->u.is_computer) {
247                 char *name;
248                 char *saltbody;
249
250                 name = strlower_talloc(io->ac, io->u.sAMAccountName);
251                 if (!name) {
252                         ldb_oom(ldb);
253                         return LDB_ERR_OPERATIONS_ERROR;
254                 }
255
256                 if (name[strlen(name)-1] == '$') {
257                         name[strlen(name)-1] = '\0';
258                 }
259
260                 saltbody = talloc_asprintf(io->ac, "%s.%s", name, io->domain->dns_domain);
261                 if (!saltbody) {
262                         ldb_oom(ldb);
263                         return LDB_ERR_OPERATIONS_ERROR;
264                 }
265                 
266                 krb5_ret = krb5_make_principal(io->smb_krb5_context->krb5_context,
267                                                &salt_principal,
268                                                io->domain->realm, "host",
269                                                saltbody, NULL);
270         } else if (io->u.user_principal_name) {
271                 char *user_principal_name;
272                 char *p;
273
274                 user_principal_name = talloc_strdup(io->ac, io->u.user_principal_name);
275                 if (!user_principal_name) {
276                         ldb_oom(ldb);
277                         return LDB_ERR_OPERATIONS_ERROR;
278                 }
279
280                 p = strchr(user_principal_name, '@');
281                 if (p) {
282                         p[0] = '\0';
283                 }
284
285                 krb5_ret = krb5_make_principal(io->smb_krb5_context->krb5_context,
286                                                &salt_principal,
287                                                io->domain->realm, user_principal_name,
288                                                NULL);
289         } else {
290                 krb5_ret = krb5_make_principal(io->smb_krb5_context->krb5_context,
291                                                &salt_principal,
292                                                io->domain->realm, io->u.sAMAccountName,
293                                                NULL);
294         }
295         if (krb5_ret) {
296                 ldb_asprintf_errstring(ldb,
297                                        "setup_kerberos_keys: "
298                                        "generation of a salting principal failed: %s",
299                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
300                 return LDB_ERR_OPERATIONS_ERROR;
301         }
302
303         /*
304          * create salt from salt_principal
305          */
306         krb5_ret = krb5_get_pw_salt(io->smb_krb5_context->krb5_context,
307                                     salt_principal, &salt);
308         krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
309         if (krb5_ret) {
310                 ldb_asprintf_errstring(ldb,
311                                        "setup_kerberos_keys: "
312                                        "generation of krb5_salt failed: %s",
313                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
314                 return LDB_ERR_OPERATIONS_ERROR;
315         }
316         /* create a talloc copy */
317         io->g.salt = talloc_strndup(io->ac,
318                                     salt.saltvalue.data,
319                                     salt.saltvalue.length);
320         krb5_free_salt(io->smb_krb5_context->krb5_context, salt);
321         if (!io->g.salt) {
322                 ldb_oom(ldb);
323                 return LDB_ERR_OPERATIONS_ERROR;
324         }
325         salt.saltvalue.data     = discard_const(io->g.salt);
326         salt.saltvalue.length   = strlen(io->g.salt);
327
328         /*
329          * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
330          * the salt and the cleartext password
331          */
332         krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context,
333                                                 ENCTYPE_AES256_CTS_HMAC_SHA1_96,
334                                                 cleartext_data,
335                                                 salt,
336                                                 &key);
337         if (krb5_ret) {
338                 ldb_asprintf_errstring(ldb,
339                                        "setup_kerberos_keys: "
340                                        "generation of a aes256-cts-hmac-sha1-96 key failed: %s",
341                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
342                 return LDB_ERR_OPERATIONS_ERROR;
343         }
344         io->g.aes_256 = data_blob_talloc(io->ac,
345                                          key.keyvalue.data,
346                                          key.keyvalue.length);
347         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
348         if (!io->g.aes_256.data) {
349                 ldb_oom(ldb);
350                 return LDB_ERR_OPERATIONS_ERROR;
351         }
352
353         /*
354          * create ENCTYPE_AES128_CTS_HMAC_SHA1_96 key out of
355          * the salt and the cleartext password
356          */
357         krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context,
358                                                 ENCTYPE_AES128_CTS_HMAC_SHA1_96,
359                                                 cleartext_data,
360                                                 salt,
361                                                 &key);
362         if (krb5_ret) {
363                 ldb_asprintf_errstring(ldb,
364                                        "setup_kerberos_keys: "
365                                        "generation of a aes128-cts-hmac-sha1-96 key failed: %s",
366                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
367                 return LDB_ERR_OPERATIONS_ERROR;
368         }
369         io->g.aes_128 = data_blob_talloc(io->ac,
370                                          key.keyvalue.data,
371                                          key.keyvalue.length);
372         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
373         if (!io->g.aes_128.data) {
374                 ldb_oom(ldb);
375                 return LDB_ERR_OPERATIONS_ERROR;
376         }
377
378         /*
379          * create ENCTYPE_DES_CBC_MD5 key out of
380          * the salt and the cleartext password
381          */
382         krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context,
383                                                 ENCTYPE_DES_CBC_MD5,
384                                                 cleartext_data,
385                                                 salt,
386                                                 &key);
387         if (krb5_ret) {
388                 ldb_asprintf_errstring(ldb,
389                                        "setup_kerberos_keys: "
390                                        "generation of a des-cbc-md5 key failed: %s",
391                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
392                 return LDB_ERR_OPERATIONS_ERROR;
393         }
394         io->g.des_md5 = data_blob_talloc(io->ac,
395                                          key.keyvalue.data,
396                                          key.keyvalue.length);
397         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
398         if (!io->g.des_md5.data) {
399                 ldb_oom(ldb);
400                 return LDB_ERR_OPERATIONS_ERROR;
401         }
402
403         /*
404          * create ENCTYPE_DES_CBC_CRC key out of
405          * the salt and the cleartext password
406          */
407         krb5_ret = krb5_string_to_key_data_salt(io->smb_krb5_context->krb5_context,
408                                                 ENCTYPE_DES_CBC_CRC,
409                                                 cleartext_data,
410                                                 salt,
411                                                 &key);
412         if (krb5_ret) {
413                 ldb_asprintf_errstring(ldb,
414                                        "setup_kerberos_keys: "
415                                        "generation of a des-cbc-crc key failed: %s",
416                                        smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
417                 return LDB_ERR_OPERATIONS_ERROR;
418         }
419         io->g.des_crc = data_blob_talloc(io->ac,
420                                          key.keyvalue.data,
421                                          key.keyvalue.length);
422         krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
423         if (!io->g.des_crc.data) {
424                 ldb_oom(ldb);
425                 return LDB_ERR_OPERATIONS_ERROR;
426         }
427
428         return LDB_SUCCESS;
429 }
430
431 static int setup_primary_kerberos(struct setup_password_fields_io *io,
432                                   const struct supplementalCredentialsBlob *old_scb,
433                                   struct package_PrimaryKerberosBlob *pkb)
434 {
435         struct ldb_context *ldb;
436         struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
437         struct supplementalCredentialsPackage *old_scp = NULL;
438         struct package_PrimaryKerberosBlob _old_pkb;
439         struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
440         uint32_t i;
441         enum ndr_err_code ndr_err;
442
443         ldb = ldb_module_get_ctx(io->ac->module);
444
445         /*
446          * prepare generation of keys
447          *
448          * ENCTYPE_DES_CBC_MD5
449          * ENCTYPE_DES_CBC_CRC
450          */
451         pkb->version            = 3;
452         pkb3->salt.string       = io->g.salt;
453         pkb3->num_keys          = 2;
454         pkb3->keys              = talloc_array(io->ac,
455                                                struct package_PrimaryKerberosKey3,
456                                                pkb3->num_keys);
457         if (!pkb3->keys) {
458                 ldb_oom(ldb);
459                 return LDB_ERR_OPERATIONS_ERROR;
460         }
461
462         pkb3->keys[0].keytype   = ENCTYPE_DES_CBC_MD5;
463         pkb3->keys[0].value     = &io->g.des_md5;
464         pkb3->keys[1].keytype   = ENCTYPE_DES_CBC_CRC;
465         pkb3->keys[1].value     = &io->g.des_crc;
466
467         /* initialize the old keys to zero */
468         pkb3->num_old_keys      = 0;
469         pkb3->old_keys          = NULL;
470
471         /* if there're no old keys, then we're done */
472         if (!old_scb) {
473                 return LDB_SUCCESS;
474         }
475
476         for (i=0; i < old_scb->sub.num_packages; i++) {
477                 if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
478                         continue;
479                 }
480
481                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
482                         continue;
483                 }
484
485                 old_scp = &old_scb->sub.packages[i];
486                 break;
487         }
488         /* Primary:Kerberos element of supplementalCredentials */
489         if (old_scp) {
490                 DATA_BLOB blob;
491
492                 blob = strhex_to_data_blob(io->ac, old_scp->data);
493                 if (!blob.data) {
494                         ldb_oom(ldb);
495                         return LDB_ERR_OPERATIONS_ERROR;
496                 }
497
498                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
499                 ndr_err = ndr_pull_struct_blob(&blob, io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), &_old_pkb,
500                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
501                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
502                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
503                         ldb_asprintf_errstring(ldb,
504                                                "setup_primary_kerberos: "
505                                                "failed to pull old package_PrimaryKerberosBlob: %s",
506                                                nt_errstr(status));
507                         return LDB_ERR_OPERATIONS_ERROR;
508                 }
509
510                 if (_old_pkb.version != 3) {
511                         ldb_asprintf_errstring(ldb,
512                                                "setup_primary_kerberos: "
513                                                "package_PrimaryKerberosBlob version[%u] expected[3]",
514                                                _old_pkb.version);
515                         return LDB_ERR_OPERATIONS_ERROR;
516                 }
517
518                 old_pkb3 = &_old_pkb.ctr.ctr3;
519         }
520
521         /* if we didn't found the old keys we're done */
522         if (!old_pkb3) {
523                 return LDB_SUCCESS;
524         }
525
526         /* fill in the old keys */
527         pkb3->num_old_keys      = old_pkb3->num_keys;
528         pkb3->old_keys          = old_pkb3->keys;
529
530         return LDB_SUCCESS;
531 }
532
533 static int setup_primary_kerberos_newer(struct setup_password_fields_io *io,
534                                         const struct supplementalCredentialsBlob *old_scb,
535                                         struct package_PrimaryKerberosBlob *pkb)
536 {
537         struct ldb_context *ldb;
538         struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4;
539         struct supplementalCredentialsPackage *old_scp = NULL;
540         struct package_PrimaryKerberosBlob _old_pkb;
541         struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL;
542         uint32_t i;
543         enum ndr_err_code ndr_err;
544
545         ldb = ldb_module_get_ctx(io->ac->module);
546
547         /*
548          * prepare generation of keys
549          *
550          * ENCTYPE_AES256_CTS_HMAC_SHA1_96
551          * ENCTYPE_AES128_CTS_HMAC_SHA1_96
552          * ENCTYPE_DES_CBC_MD5
553          * ENCTYPE_DES_CBC_CRC
554          */
555         pkb->version                    = 4;
556         pkb4->salt.string               = io->g.salt;
557         pkb4->default_iteration_count   = 4096;
558         pkb4->num_keys                  = 4;
559
560         pkb4->keys = talloc_array(io->ac,
561                                   struct package_PrimaryKerberosKey4,
562                                   pkb4->num_keys);
563         if (!pkb4->keys) {
564                 ldb_oom(ldb);
565                 return LDB_ERR_OPERATIONS_ERROR;
566         }
567
568         pkb4->keys[0].iteration_count   = 4096;
569         pkb4->keys[0].keytype           = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
570         pkb4->keys[0].value             = &io->g.aes_256;
571         pkb4->keys[1].iteration_count   = 4096;
572         pkb4->keys[1].keytype           = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
573         pkb4->keys[1].value             = &io->g.aes_128;
574         pkb4->keys[2].iteration_count   = 4096;
575         pkb4->keys[2].keytype           = ENCTYPE_DES_CBC_MD5;
576         pkb4->keys[2].value             = &io->g.des_md5;
577         pkb4->keys[3].iteration_count   = 4096;
578         pkb4->keys[3].keytype           = ENCTYPE_DES_CBC_CRC;
579         pkb4->keys[3].value             = &io->g.des_crc;
580
581         /* initialize the old keys to zero */
582         pkb4->num_old_keys      = 0;
583         pkb4->old_keys          = NULL;
584         pkb4->num_older_keys    = 0;
585         pkb4->older_keys        = NULL;
586
587         /* if there're no old keys, then we're done */
588         if (!old_scb) {
589                 return LDB_SUCCESS;
590         }
591
592         for (i=0; i < old_scb->sub.num_packages; i++) {
593                 if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) {
594                         continue;
595                 }
596
597                 if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
598                         continue;
599                 }
600
601                 old_scp = &old_scb->sub.packages[i];
602                 break;
603         }
604         /* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
605         if (old_scp) {
606                 DATA_BLOB blob;
607
608                 blob = strhex_to_data_blob(io->ac, old_scp->data);
609                 if (!blob.data) {
610                         ldb_oom(ldb);
611                         return LDB_ERR_OPERATIONS_ERROR;
612                 }
613
614                 /* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
615                 ndr_err = ndr_pull_struct_blob(&blob, io->ac,
616                                                lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
617                                                &_old_pkb,
618                                                (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
619                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
620                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
621                         ldb_asprintf_errstring(ldb,
622                                                "setup_primary_kerberos_newer: "
623                                                "failed to pull old package_PrimaryKerberosBlob: %s",
624                                                nt_errstr(status));
625                         return LDB_ERR_OPERATIONS_ERROR;
626                 }
627
628                 if (_old_pkb.version != 4) {
629                         ldb_asprintf_errstring(ldb,
630                                                "setup_primary_kerberos_newer: "
631                                                "package_PrimaryKerberosBlob version[%u] expected[4]",
632                                                _old_pkb.version);
633                         return LDB_ERR_OPERATIONS_ERROR;
634                 }
635
636                 old_pkb4 = &_old_pkb.ctr.ctr4;
637         }
638
639         /* if we didn't found the old keys we're done */
640         if (!old_pkb4) {
641                 return LDB_SUCCESS;
642         }
643
644         /* fill in the old keys */
645         pkb4->num_old_keys      = old_pkb4->num_keys;
646         pkb4->old_keys          = old_pkb4->keys;
647         pkb4->num_older_keys    = old_pkb4->num_old_keys;
648         pkb4->older_keys        = old_pkb4->old_keys;
649
650         return LDB_SUCCESS;
651 }
652
653 static int setup_primary_wdigest(struct setup_password_fields_io *io,
654                                  const struct supplementalCredentialsBlob *old_scb,
655                                  struct package_PrimaryWDigestBlob *pdb)
656 {
657         struct ldb_context *ldb = ldb_module_get_ctx(io->ac->module);
658         DATA_BLOB sAMAccountName;
659         DATA_BLOB sAMAccountName_l;
660         DATA_BLOB sAMAccountName_u;
661         const char *user_principal_name = io->u.user_principal_name;
662         DATA_BLOB userPrincipalName;
663         DATA_BLOB userPrincipalName_l;
664         DATA_BLOB userPrincipalName_u;
665         DATA_BLOB netbios_domain;
666         DATA_BLOB netbios_domain_l;
667         DATA_BLOB netbios_domain_u;
668         DATA_BLOB dns_domain;
669         DATA_BLOB dns_domain_l;
670         DATA_BLOB dns_domain_u;
671         DATA_BLOB digest;
672         DATA_BLOB delim;
673         DATA_BLOB backslash;
674         uint8_t i;
675         struct {
676                 DATA_BLOB *user;
677                 DATA_BLOB *realm;
678                 DATA_BLOB *nt4dom;
679         } wdigest[] = {
680         /*
681          * See
682          * http://technet2.microsoft.com/WindowsServer/en/library/717b450c-f4a0-4cc9-86f4-cc0633aae5f91033.mspx?mfr=true
683          * for what precalculated hashes are supposed to be stored...
684          *
685          * I can't reproduce all values which should contain "Digest" as realm,
686          * am I doing something wrong or is w2k3 just broken...?
687          *
688          * W2K3 fills in following for a user:
689          *
690          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
691          * sAMAccountName: NewUser2Sam
692          * userPrincipalName: NewUser2Princ@sub1.w2k3.vmnet1.vm.base
693          *
694          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
695          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
696          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
697          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
698          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
699          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
700          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
701          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
702          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
703          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
704          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
705          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
706          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
707          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
708          * 221c55284451ae9b3aacaa2a3c86f10f => NewUser2Princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
709          * 74e1be668853d4324d38c07e2acfb8ea => (w2k3 has a bug here!) newuser2princ@sub1.w2k3.vmnet1.vm.base::TestPwd2007
710          * e1e244ab7f098e3ae1761be7f9229bbb => NEWUSER2PRINC@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
711          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
712          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
713          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
714          * 31dc704d3640335b2123d4ee28aa1f11 => ??? changes with NewUser2Sam => NewUser1Sam
715          * 36349f5cecd07320fb3bb0e119230c43 => ??? changes with NewUser2Sam => NewUser1Sam
716          * 12adf019d037fb535c01fd0608e78d9d => ??? changes with NewUser2Sam => NewUser1Sam
717          * 6feecf8e724906f3ee1105819c5105a1 => ??? changes with NewUser2Princ => NewUser1Princ
718          * 6c6911f3de6333422640221b9c51ff1f => ??? changes with NewUser2Princ => NewUser1Princ
719          * 4b279877e742895f9348ac67a8de2f69 => ??? changes with NewUser2Princ => NewUser1Princ
720          * db0c6bff069513e3ebb9870d29b57490 => ??? changes with NewUser2Sam => NewUser1Sam
721          * 45072621e56b1c113a4e04a8ff68cd0e => ??? changes with NewUser2Sam => NewUser1Sam
722          * 11d1220abc44a9c10cf91ef4a9c1de02 => ??? changes with NewUser2Sam => NewUser1Sam
723          *
724          * dn: CN=NewUser,OU=newtop,DC=sub1,DC=w2k3,DC=vmnet1,DC=vm,DC=base
725          * sAMAccountName: NewUser2Sam
726          *
727          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
728          * b7ec9da91062199aee7d121e6710fe23 => newuser2sam:sub1:TestPwd2007
729          * 17d290bc5c9f463fac54c37a8cea134d => NEWUSER2SAM:SUB1:TestPwd2007
730          * 4279815024bda54fc074a5f8bd0a6e6f => NewUser2Sam:SUB1:TestPwd2007
731          * 5d57e7823938348127322e08cd81bcb5 => NewUser2Sam:sub1:TestPwd2007
732          * 07dd701bf8a011ece585de3d47237140 => NEWUSER2SAM:sub1:TestPwd2007
733          * e14fb0eb401498d2cb33c9aae1cc7f37 => newuser2sam:SUB1:TestPwd2007
734          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
735          * f52da1266a6bdd290ffd48b2c823dda7 => newuser2sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
736          * d2b42f171248cec37a3c5c6b55404062 => NEWUSER2SAM:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
737          * fff8d790ff6c152aaeb6ebe17b4021de => NewUser2Sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
738          * 8dadc90250f873d8b883f79d890bef82 => NewUser2Sam:sub1.w2k3.vmnet1.vm.base:TestPwd2007
739          * 2a7563c3715bc418d626dabef378c008 => NEWUSER2SAM:sub1.w2k3.vmnet1.vm.base:TestPwd2007
740          * c8e9557a87cd4200fda0c11d2fa03f96 => newuser2sam:SUB1.W2K3.VMNET1.VM.BASE:TestPwd2007
741          * 8a140d30b6f0a5912735dc1e3bc993b4 => NewUser2Sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
742          * 86d95b2faae6cae4ec261e7fbaccf093 => (here w2k3 is correct) newuser2sam@sub1.w2k3.vmnet1.vm.base::TestPwd2007
743          * dfeff1493110220efcdfc6362e5f5450 => NEWUSER2SAM@SUB1.W2K3.VMNET1.VM.BASE::TestPwd2007
744          * 86db637df42513039920e605499c3af6 => SUB1\NewUser2Sam::TestPwd2007
745          * f5e43474dfaf067fee8197a253debaa2 => sub1\newuser2sam::TestPwd2007
746          * 2ecaa8382e2518e4b77a52422b279467 => SUB1\NEWUSER2SAM::TestPwd2007
747          * 31dc704d3640335b2123d4ee28aa1f11 => ???M1   changes with NewUser2Sam => NewUser1Sam
748          * 36349f5cecd07320fb3bb0e119230c43 => ???M1.L changes with newuser2sam => newuser1sam
749          * 12adf019d037fb535c01fd0608e78d9d => ???M1.U changes with NEWUSER2SAM => NEWUSER1SAM
750          * 569b4533f2d9e580211dd040e5e360a8 => ???M2   changes with NewUser2Princ => NewUser1Princ
751          * 52528bddf310a587c5d7e6a9ae2cbb20 => ???M2.L changes with newuser2princ => newuser1princ
752          * 4f629a4f0361289ca4255ab0f658fcd5 => ???M3 changes with NewUser2Princ => NewUser1Princ (doesn't depend on case of userPrincipal )
753          * db0c6bff069513e3ebb9870d29b57490 => ???M4 changes with NewUser2Sam => NewUser1Sam
754          * 45072621e56b1c113a4e04a8ff68cd0e => ???M5 changes with NewUser2Sam => NewUser1Sam (doesn't depend on case of sAMAccountName)
755          * 11d1220abc44a9c10cf91ef4a9c1de02 => ???M4.U changes with NEWUSER2SAM => NEWUSER1SAM
756          */
757
758         /*
759          * sAMAccountName, netbios_domain
760          */
761                 {
762                 .user   = &sAMAccountName,
763                 .realm  = &netbios_domain,
764                 },
765                 {
766                 .user   = &sAMAccountName_l,
767                 .realm  = &netbios_domain_l,
768                 },
769                 {
770                 .user   = &sAMAccountName_u,
771                 .realm  = &netbios_domain_u,
772                 },
773                 {
774                 .user   = &sAMAccountName,
775                 .realm  = &netbios_domain_u,
776                 },
777                 {
778                 .user   = &sAMAccountName,
779                 .realm  = &netbios_domain_l,
780                 },
781                 {
782                 .user   = &sAMAccountName_u,
783                 .realm  = &netbios_domain_l,
784                 },
785                 {
786                 .user   = &sAMAccountName_l,
787                 .realm  = &netbios_domain_u,
788                 },
789         /* 
790          * sAMAccountName, dns_domain
791          */
792                 {
793                 .user   = &sAMAccountName,
794                 .realm  = &dns_domain,
795                 },
796                 {
797                 .user   = &sAMAccountName_l,
798                 .realm  = &dns_domain_l,
799                 },
800                 {
801                 .user   = &sAMAccountName_u,
802                 .realm  = &dns_domain_u,
803                 },
804                 {
805                 .user   = &sAMAccountName,
806                 .realm  = &dns_domain_u,
807                 },
808                 {
809                 .user   = &sAMAccountName,
810                 .realm  = &dns_domain_l,
811                 },
812                 {
813                 .user   = &sAMAccountName_u,
814                 .realm  = &dns_domain_l,
815                 },
816                 {
817                 .user   = &sAMAccountName_l,
818                 .realm  = &dns_domain_u,
819                 },
820         /* 
821          * userPrincipalName, no realm
822          */
823                 {
824                 .user   = &userPrincipalName,
825                 },
826                 {
827                 /* 
828                  * NOTE: w2k3 messes this up, if the user has a real userPrincipalName,
829                  *       the fallback to the sAMAccountName based userPrincipalName is correct
830                  */
831                 .user   = &userPrincipalName_l,
832                 },
833                 {
834                 .user   = &userPrincipalName_u,
835                 },
836         /* 
837          * nt4dom\sAMAccountName, no realm
838          */
839                 {
840                 .user   = &sAMAccountName,
841                 .nt4dom = &netbios_domain
842                 },
843                 {
844                 .user   = &sAMAccountName_l,
845                 .nt4dom = &netbios_domain_l
846                 },
847                 {
848                 .user   = &sAMAccountName_u,
849                 .nt4dom = &netbios_domain_u
850                 },
851
852         /*
853          * the following ones are guessed depending on the technet2 article
854          * but not reproducable on a w2k3 server
855          */
856         /* sAMAccountName with "Digest" realm */
857                 {
858                 .user   = &sAMAccountName,
859                 .realm  = &digest
860                 },
861                 {
862                 .user   = &sAMAccountName_l,
863                 .realm  = &digest
864                 },
865                 {
866                 .user   = &sAMAccountName_u,
867                 .realm  = &digest
868                 },
869         /* userPrincipalName with "Digest" realm */
870                 {
871                 .user   = &userPrincipalName,
872                 .realm  = &digest
873                 },
874                 {
875                 .user   = &userPrincipalName_l,
876                 .realm  = &digest
877                 },
878                 {
879                 .user   = &userPrincipalName_u,
880                 .realm  = &digest
881                 },
882         /* nt4dom\\sAMAccountName with "Digest" realm */
883                 {
884                 .user   = &sAMAccountName,
885                 .nt4dom = &netbios_domain,
886                 .realm  = &digest
887                 },
888                 {
889                 .user   = &sAMAccountName_l,
890                 .nt4dom = &netbios_domain_l,
891                 .realm  = &digest
892                 },
893                 {
894                 .user   = &sAMAccountName_u,
895                 .nt4dom = &netbios_domain_u,
896                 .realm  = &digest
897                 },
898         };
899
900         /* prepare DATA_BLOB's used in the combinations array */
901         sAMAccountName          = data_blob_string_const(io->u.sAMAccountName);
902         sAMAccountName_l        = data_blob_string_const(strlower_talloc(io->ac, io->u.sAMAccountName));
903         if (!sAMAccountName_l.data) {
904                 ldb_oom(ldb);
905                 return LDB_ERR_OPERATIONS_ERROR;
906         }
907         sAMAccountName_u        = data_blob_string_const(strupper_talloc(io->ac, io->u.sAMAccountName));
908         if (!sAMAccountName_u.data) {
909                 ldb_oom(ldb);
910                 return LDB_ERR_OPERATIONS_ERROR;
911         }
912
913         /* if the user doesn't have a userPrincipalName, create one (with lower case realm) */
914         if (!user_principal_name) {
915                 user_principal_name = talloc_asprintf(io->ac, "%s@%s",
916                                                       io->u.sAMAccountName,
917                                                       io->domain->dns_domain);
918                 if (!user_principal_name) {
919                         ldb_oom(ldb);
920                         return LDB_ERR_OPERATIONS_ERROR;
921                 }       
922         }
923         userPrincipalName       = data_blob_string_const(user_principal_name);
924         userPrincipalName_l     = data_blob_string_const(strlower_talloc(io->ac, user_principal_name));
925         if (!userPrincipalName_l.data) {
926                 ldb_oom(ldb);
927                 return LDB_ERR_OPERATIONS_ERROR;
928         }
929         userPrincipalName_u     = data_blob_string_const(strupper_talloc(io->ac, user_principal_name));
930         if (!userPrincipalName_u.data) {
931                 ldb_oom(ldb);
932                 return LDB_ERR_OPERATIONS_ERROR;
933         }
934
935         netbios_domain          = data_blob_string_const(io->domain->netbios_domain);
936         netbios_domain_l        = data_blob_string_const(strlower_talloc(io->ac, io->domain->netbios_domain));
937         if (!netbios_domain_l.data) {
938                 ldb_oom(ldb);
939                 return LDB_ERR_OPERATIONS_ERROR;
940         }
941         netbios_domain_u        = data_blob_string_const(strupper_talloc(io->ac, io->domain->netbios_domain));
942         if (!netbios_domain_u.data) {
943                 ldb_oom(ldb);
944                 return LDB_ERR_OPERATIONS_ERROR;
945         }
946
947         dns_domain              = data_blob_string_const(io->domain->dns_domain);
948         dns_domain_l            = data_blob_string_const(io->domain->dns_domain);
949         dns_domain_u            = data_blob_string_const(io->domain->realm);
950
951         digest                  = data_blob_string_const("Digest");
952
953         delim                   = data_blob_string_const(":");
954         backslash               = data_blob_string_const("\\");
955
956         pdb->num_hashes = ARRAY_SIZE(wdigest);
957         pdb->hashes     = talloc_array(io->ac, struct package_PrimaryWDigestHash, pdb->num_hashes);
958         if (!pdb->hashes) {
959                 ldb_oom(ldb);
960                 return LDB_ERR_OPERATIONS_ERROR;
961         }
962
963         for (i=0; i < ARRAY_SIZE(wdigest); i++) {
964                 struct MD5Context md5;
965                 MD5Init(&md5);
966                 if (wdigest[i].nt4dom) {
967                         MD5Update(&md5, wdigest[i].nt4dom->data, wdigest[i].nt4dom->length);
968                         MD5Update(&md5, backslash.data, backslash.length);
969                 }
970                 MD5Update(&md5, wdigest[i].user->data, wdigest[i].user->length);
971                 MD5Update(&md5, delim.data, delim.length);
972                 if (wdigest[i].realm) {
973                         MD5Update(&md5, wdigest[i].realm->data, wdigest[i].realm->length);
974                 }
975                 MD5Update(&md5, delim.data, delim.length);
976                 MD5Update(&md5, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length);
977                 MD5Final(pdb->hashes[i].hash, &md5);
978         }
979
980         return LDB_SUCCESS;
981 }
982
983 static int setup_supplemental_field(struct setup_password_fields_io *io)
984 {
985         struct ldb_context *ldb;
986         struct supplementalCredentialsBlob scb;
987         struct supplementalCredentialsBlob _old_scb;
988         struct supplementalCredentialsBlob *old_scb = NULL;
989         /* Packages + (Kerberos-Newer-Keys, Kerberos, WDigest and CLEARTEXT) */
990         uint32_t num_names = 0;
991         const char *names[1+4];
992         uint32_t num_packages = 0;
993         struct supplementalCredentialsPackage packages[1+4];
994         /* Packages */
995         struct supplementalCredentialsPackage *pp = NULL;
996         struct package_PackagesBlob pb;
997         DATA_BLOB pb_blob;
998         char *pb_hexstr;
999         /* Primary:Kerberos-Newer-Keys */
1000         const char **nkn = NULL;
1001         struct supplementalCredentialsPackage *pkn = NULL;
1002         struct package_PrimaryKerberosBlob pknb;
1003         DATA_BLOB pknb_blob;
1004         char *pknb_hexstr;
1005         /* Primary:Kerberos */
1006         const char **nk = NULL;
1007         struct supplementalCredentialsPackage *pk = NULL;
1008         struct package_PrimaryKerberosBlob pkb;
1009         DATA_BLOB pkb_blob;
1010         char *pkb_hexstr;
1011         /* Primary:WDigest */
1012         const char **nd = NULL;
1013         struct supplementalCredentialsPackage *pd = NULL;
1014         struct package_PrimaryWDigestBlob pdb;
1015         DATA_BLOB pdb_blob;
1016         char *pdb_hexstr;
1017         /* Primary:CLEARTEXT */
1018         const char **nc = NULL;
1019         struct supplementalCredentialsPackage *pc = NULL;
1020         struct package_PrimaryCLEARTEXTBlob pcb;
1021         DATA_BLOB pcb_blob;
1022         char *pcb_hexstr;
1023         int ret;
1024         enum ndr_err_code ndr_err;
1025         uint8_t zero16[16];
1026         bool do_newer_keys = false;
1027         bool do_cleartext = false;
1028         int *domainFunctionality;
1029
1030         ZERO_STRUCT(zero16);
1031         ZERO_STRUCT(names);
1032
1033         ldb = ldb_module_get_ctx(io->ac->module);
1034
1035         if (!io->n.cleartext_utf8) {
1036                 /* 
1037                  * when we don't have a cleartext password
1038                  * we can't setup a supplementalCredential value
1039                  */
1040                 return LDB_SUCCESS;
1041         }
1042
1043         /* if there's an old supplementaCredentials blob then parse it */
1044         if (io->o.supplemental) {
1045                 ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac,
1046                                                    lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1047                                                    &_old_scb,
1048                                                    (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
1049                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1050                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1051                         ldb_asprintf_errstring(ldb,
1052                                                "setup_supplemental_field: "
1053                                                "failed to pull old supplementalCredentialsBlob: %s",
1054                                                nt_errstr(status));
1055                         return LDB_ERR_OPERATIONS_ERROR;
1056                 }
1057
1058                 if (_old_scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
1059                         old_scb = &_old_scb;
1060                 } else {
1061                         ldb_debug(ldb, LDB_DEBUG_ERROR,
1062                                                "setup_supplemental_field: "
1063                                                "supplementalCredentialsBlob signature[0x%04X] expected[0x%04X]",
1064                                                _old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
1065                 }
1066         }
1067         /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
1068         domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
1069
1070         do_newer_keys = *domainFunctionality &&
1071                 (*domainFunctionality >= DS_DOMAIN_FUNCTION_2008);
1072
1073         if (io->domain->store_cleartext &&
1074             (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
1075                 do_cleartext = true;
1076         }
1077
1078         /*
1079          * The ordering is this
1080          *
1081          * Primary:Kerberos-Newer-Keys (optional)
1082          * Primary:Kerberos
1083          * Primary:WDigest
1084          * Primary:CLEARTEXT (optional)
1085          *
1086          * And the 'Packages' package is insert before the last
1087          * other package.
1088          */
1089         if (do_newer_keys) {
1090                 /* Primary:Kerberos-Newer-Keys */
1091                 nkn = &names[num_names++];
1092                 pkn = &packages[num_packages++];
1093         }
1094
1095         /* Primary:Kerberos */
1096         nk = &names[num_names++];
1097         pk = &packages[num_packages++];
1098
1099         if (!do_cleartext) {
1100                 /* Packages */
1101                 pp = &packages[num_packages++];
1102         }
1103
1104         /* Primary:WDigest */
1105         nd = &names[num_names++];
1106         pd = &packages[num_packages++];
1107
1108         if (do_cleartext) {
1109                 /* Packages */
1110                 pp = &packages[num_packages++];
1111
1112                 /* Primary:CLEARTEXT */
1113                 nc = &names[num_names++];
1114                 pc = &packages[num_packages++];
1115         }
1116
1117         if (pkn) {
1118                 /*
1119                  * setup 'Primary:Kerberos-Newer-Keys' element
1120                  */
1121                 *nkn = "Kerberos-Newer-Keys";
1122
1123                 ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
1124                 if (ret != LDB_SUCCESS) {
1125                         return ret;
1126                 }
1127
1128                 ndr_err = ndr_push_struct_blob(&pknb_blob, io->ac,
1129                                                lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1130                                                &pknb,
1131                                                (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1132                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1133                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1134                         ldb_asprintf_errstring(ldb,
1135                                                "setup_supplemental_field: "
1136                                                "failed to push package_PrimaryKerberosNeverBlob: %s",
1137                                                nt_errstr(status));
1138                         return LDB_ERR_OPERATIONS_ERROR;
1139                 }
1140                 pknb_hexstr = data_blob_hex_string(io->ac, &pknb_blob);
1141                 if (!pknb_hexstr) {
1142                         ldb_oom(ldb);
1143                         return LDB_ERR_OPERATIONS_ERROR;
1144                 }
1145                 pkn->name       = "Primary:Kerberos-Newer-Keys";
1146                 pkn->reserved   = 1;
1147                 pkn->data       = pknb_hexstr;
1148         }
1149
1150         /*
1151          * setup 'Primary:Kerberos' element
1152          */
1153         *nk = "Kerberos";
1154
1155         ret = setup_primary_kerberos(io, old_scb, &pkb);
1156         if (ret != LDB_SUCCESS) {
1157                 return ret;
1158         }
1159
1160         ndr_err = ndr_push_struct_blob(&pkb_blob, io->ac, 
1161                                        lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1162                                        &pkb,
1163                                        (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1164         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1165                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1166                 ldb_asprintf_errstring(ldb,
1167                                        "setup_supplemental_field: "
1168                                        "failed to push package_PrimaryKerberosBlob: %s",
1169                                        nt_errstr(status));
1170                 return LDB_ERR_OPERATIONS_ERROR;
1171         }
1172         pkb_hexstr = data_blob_hex_string(io->ac, &pkb_blob);
1173         if (!pkb_hexstr) {
1174                 ldb_oom(ldb);
1175                 return LDB_ERR_OPERATIONS_ERROR;
1176         }
1177         pk->name        = "Primary:Kerberos";
1178         pk->reserved    = 1;
1179         pk->data        = pkb_hexstr;
1180
1181         /*
1182          * setup 'Primary:WDigest' element
1183          */
1184         *nd = "WDigest";
1185
1186         ret = setup_primary_wdigest(io, old_scb, &pdb);
1187         if (ret != LDB_SUCCESS) {
1188                 return ret;
1189         }
1190
1191         ndr_err = ndr_push_struct_blob(&pdb_blob, io->ac, 
1192                                        lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1193                                        &pdb,
1194                                        (ndr_push_flags_fn_t)ndr_push_package_PrimaryWDigestBlob);
1195         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1196                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1197                 ldb_asprintf_errstring(ldb,
1198                                        "setup_supplemental_field: "
1199                                        "failed to push package_PrimaryWDigestBlob: %s",
1200                                        nt_errstr(status));
1201                 return LDB_ERR_OPERATIONS_ERROR;
1202         }
1203         pdb_hexstr = data_blob_hex_string(io->ac, &pdb_blob);
1204         if (!pdb_hexstr) {
1205                 ldb_oom(ldb);
1206                 return LDB_ERR_OPERATIONS_ERROR;
1207         }
1208         pd->name        = "Primary:WDigest";
1209         pd->reserved    = 1;
1210         pd->data        = pdb_hexstr;
1211
1212         /*
1213          * setup 'Primary:CLEARTEXT' element
1214          */
1215         if (pc) {
1216                 *nc             = "CLEARTEXT";
1217
1218                 pcb.cleartext   = *io->n.cleartext_utf16;
1219
1220                 ndr_err = ndr_push_struct_blob(&pcb_blob, io->ac, 
1221                                                lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1222                                                &pcb,
1223                                                (ndr_push_flags_fn_t)ndr_push_package_PrimaryCLEARTEXTBlob);
1224                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1225                         NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1226                         ldb_asprintf_errstring(ldb,
1227                                                "setup_supplemental_field: "
1228                                                "failed to push package_PrimaryCLEARTEXTBlob: %s",
1229                                                nt_errstr(status));
1230                         return LDB_ERR_OPERATIONS_ERROR;
1231                 }
1232                 pcb_hexstr = data_blob_hex_string(io->ac, &pcb_blob);
1233                 if (!pcb_hexstr) {
1234                         ldb_oom(ldb);
1235                         return LDB_ERR_OPERATIONS_ERROR;
1236                 }
1237                 pc->name        = "Primary:CLEARTEXT";
1238                 pc->reserved    = 1;
1239                 pc->data        = pcb_hexstr;
1240         }
1241
1242         /*
1243          * setup 'Packages' element
1244          */
1245         pb.names = names;
1246         ndr_err = ndr_push_struct_blob(&pb_blob, io->ac, 
1247                                        lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 
1248                                        &pb,
1249                                        (ndr_push_flags_fn_t)ndr_push_package_PackagesBlob);
1250         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1251                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1252                 ldb_asprintf_errstring(ldb,
1253                                        "setup_supplemental_field: "
1254                                        "failed to push package_PackagesBlob: %s",
1255                                        nt_errstr(status));
1256                 return LDB_ERR_OPERATIONS_ERROR;
1257         }
1258         pb_hexstr = data_blob_hex_string(io->ac, &pb_blob);
1259         if (!pb_hexstr) {
1260                 ldb_oom(ldb);
1261                 return LDB_ERR_OPERATIONS_ERROR;
1262         }
1263         pp->name        = "Packages";
1264         pp->reserved    = 2;
1265         pp->data        = pb_hexstr;
1266
1267         /*
1268          * setup 'supplementalCredentials' value
1269          */
1270         ZERO_STRUCT(scb);
1271         scb.sub.num_packages    = num_packages;
1272         scb.sub.packages        = packages;
1273
1274         ndr_err = ndr_push_struct_blob(&io->g.supplemental, io->ac, 
1275                                        lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1276                                        &scb,
1277                                        (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
1278         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1279                 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1280                 ldb_asprintf_errstring(ldb,
1281                                        "setup_supplemental_field: "
1282                                        "failed to push supplementalCredentialsBlob: %s",
1283                                        nt_errstr(status));
1284                 return LDB_ERR_OPERATIONS_ERROR;
1285         }
1286
1287         return LDB_SUCCESS;
1288 }
1289
1290 static int setup_last_set_field(struct setup_password_fields_io *io)
1291 {
1292         /* set it as now */
1293         unix_to_nt_time(&io->g.last_set, time(NULL));
1294
1295         return LDB_SUCCESS;
1296 }
1297
1298 static int setup_kvno_field(struct setup_password_fields_io *io)
1299 {
1300         /* increment by one */
1301         io->g.kvno = io->o.kvno + 1;
1302
1303         return LDB_SUCCESS;
1304 }
1305
1306 static int setup_password_fields(struct setup_password_fields_io *io)
1307 {
1308         struct ldb_context *ldb;
1309         bool ok;
1310         int ret;
1311         size_t converted_pw_len;
1312
1313         ldb = ldb_module_get_ctx(io->ac->module);
1314
1315         /*
1316          * refuse the change if someone want to change the cleartext
1317          * and supply his own hashes at the same time...
1318          */
1319         if ((io->n.cleartext_utf8 || io->n.cleartext_utf16) && (io->n.nt_hash || io->n.lm_hash)) {
1320                 ldb_asprintf_errstring(ldb,
1321                                        "setup_password_fields: "
1322                                        "it's only allowed to set the cleartext password or the password hashes");
1323                 return LDB_ERR_UNWILLING_TO_PERFORM;
1324         }
1325         
1326         if (io->n.cleartext_utf8 && io->n.cleartext_utf16) {
1327                 ldb_asprintf_errstring(ldb,
1328                                        "setup_password_fields: "
1329                                        "it's only allowed to set the cleartext password as userPassword or clearTextPasssword, not both at once");
1330                 return LDB_ERR_UNWILLING_TO_PERFORM;
1331         }
1332         
1333         if (io->n.cleartext_utf8) {
1334                 char **cleartext_utf16_str;
1335                 struct ldb_val *cleartext_utf16_blob;
1336                 io->n.cleartext_utf16 = cleartext_utf16_blob = talloc(io->ac, struct ldb_val);
1337                 if (!io->n.cleartext_utf16) {
1338                         ldb_oom(ldb);
1339                         return LDB_ERR_OPERATIONS_ERROR;
1340                 }
1341                 if (!convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 
1342                                                          CH_UTF8, CH_UTF16, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length, 
1343                                                          (void **)&cleartext_utf16_str, &converted_pw_len, false)) {
1344                         ldb_asprintf_errstring(ldb,
1345                                                "setup_password_fields: "
1346                                                "failed to generate UTF16 password from cleartext UTF8 password");
1347                         return LDB_ERR_OPERATIONS_ERROR;
1348                 }
1349                 *cleartext_utf16_blob = data_blob_const(cleartext_utf16_str, converted_pw_len);
1350         } else if (io->n.cleartext_utf16) {
1351                 char *cleartext_utf8_str;
1352                 struct ldb_val *cleartext_utf8_blob;
1353                 io->n.cleartext_utf8 = cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
1354                 if (!io->n.cleartext_utf8) {
1355                         ldb_oom(ldb);
1356                         return LDB_ERR_OPERATIONS_ERROR;
1357                 }
1358                 if (!convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 
1359                                                          CH_UTF16MUNGED, CH_UTF8, io->n.cleartext_utf16->data, io->n.cleartext_utf16->length, 
1360                                                          (void **)&cleartext_utf8_str, &converted_pw_len, false)) {
1361                         /* We can't bail out entirely, as these unconvertable passwords are frustratingly valid */
1362                         io->n.cleartext_utf8 = NULL;    
1363                         talloc_free(cleartext_utf8_blob);
1364                 }
1365                 *cleartext_utf8_blob = data_blob_const(cleartext_utf8_str, converted_pw_len);
1366         }
1367         if (io->n.cleartext_utf16) {
1368                 struct samr_Password *nt_hash;
1369                 nt_hash = talloc(io->ac, struct samr_Password);
1370                 if (!nt_hash) {
1371                         ldb_oom(ldb);
1372                         return LDB_ERR_OPERATIONS_ERROR;
1373                 }
1374                 io->n.nt_hash = nt_hash;
1375
1376                 /* compute the new nt hash */
1377                 mdfour(nt_hash->hash, io->n.cleartext_utf16->data, io->n.cleartext_utf16->length);
1378         }
1379
1380         if (io->n.cleartext_utf8) {
1381                 struct samr_Password *lm_hash;
1382                 char *cleartext_unix;
1383                 if (lp_lanman_auth(ldb_get_opaque(ldb, "loadparm")) &&
1384                     convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), 
1385                                                          CH_UTF8, CH_UNIX, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length, 
1386                                                          (void **)&cleartext_unix, &converted_pw_len, false)) {
1387                         lm_hash = talloc(io->ac, struct samr_Password);
1388                         if (!lm_hash) {
1389                                 ldb_oom(ldb);
1390                                 return LDB_ERR_OPERATIONS_ERROR;
1391                         }
1392                         
1393                         /* compute the new lm hash.   */
1394                         ok = E_deshash((char *)cleartext_unix, lm_hash->hash);
1395                         if (ok) {
1396                                 io->n.lm_hash = lm_hash;
1397                         } else {
1398                                 talloc_free(lm_hash->hash);
1399                         }
1400                 }
1401
1402                 ret = setup_kerberos_keys(io);
1403                 if (ret != LDB_SUCCESS) {
1404                         return ret;
1405                 }
1406         }
1407
1408         ret = setup_nt_fields(io);
1409         if (ret != LDB_SUCCESS) {
1410                 return ret;
1411         }
1412
1413         ret = setup_lm_fields(io);
1414         if (ret != LDB_SUCCESS) {
1415                 return ret;
1416         }
1417
1418         ret = setup_supplemental_field(io);
1419         if (ret != LDB_SUCCESS) {
1420                 return ret;
1421         }
1422
1423         ret = setup_last_set_field(io);
1424         if (ret != LDB_SUCCESS) {
1425                 return ret;
1426         }
1427
1428         ret = setup_kvno_field(io);
1429         if (ret != LDB_SUCCESS) {
1430                 return ret;
1431         }
1432
1433         return LDB_SUCCESS;
1434 }
1435
1436 static int setup_io(struct ph_context *ac, 
1437                     const struct ldb_message *new_msg, 
1438                     const struct ldb_message *searched_msg, 
1439                     struct setup_password_fields_io *io) 
1440
1441         const struct ldb_val *quoted_utf16;
1442         struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
1443
1444         ZERO_STRUCTP(io);
1445
1446         /* Some operations below require kerberos contexts */
1447         if (smb_krb5_init_context(ac,
1448                                   ldb_get_event_context(ldb),
1449                                   (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
1450                                   &io->smb_krb5_context) != 0) {
1451                 return LDB_ERR_OPERATIONS_ERROR;
1452         }
1453
1454         io->ac                          = ac;
1455         io->domain                      = ac->domain;
1456
1457         io->u.user_account_control      = samdb_result_uint(searched_msg, "userAccountControl", 0);
1458         io->u.sAMAccountName            = samdb_result_string(searched_msg, "samAccountName", NULL);
1459         io->u.user_principal_name       = samdb_result_string(searched_msg, "userPrincipalName", NULL);
1460         io->u.is_computer               = ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");
1461
1462         io->n.cleartext_utf8            = ldb_msg_find_ldb_val(new_msg, "userPassword");
1463         io->n.cleartext_utf16           = ldb_msg_find_ldb_val(new_msg, "clearTextPassword");
1464
1465         /* this rather strange looking piece of code is there to
1466            handle a ldap client setting a password remotely using the
1467            unicodePwd ldap field. The syntax is that the password is
1468            in UTF-16LE, with a " at either end. Unfortunately the
1469            unicodePwd field is also used to store the nt hashes
1470            internally in Samba, and is used in the nt hash format on
1471            the wire in DRS replication, so we have a single name for
1472            two distinct values. The code below leaves us with a small
1473            chance (less than 1 in 2^32) of a mixup, if someone manages
1474            to create a MD4 hash which starts and ends in 0x22 0x00, as
1475            that would then be treated as a UTF16 password rather than
1476            a nthash */
1477         quoted_utf16                    = ldb_msg_find_ldb_val(new_msg, "unicodePwd");
1478         if (quoted_utf16 && 
1479             quoted_utf16->length >= 4 &&
1480             quoted_utf16->data[0] == '"' && 
1481             quoted_utf16->data[1] == 0 && 
1482             quoted_utf16->data[quoted_utf16->length-2] == '"' && 
1483             quoted_utf16->data[quoted_utf16->length-1] == 0) {
1484                 io->n.quoted_utf16.data = talloc_memdup(io->ac, quoted_utf16->data+2, quoted_utf16->length-4);
1485                 io->n.quoted_utf16.length = quoted_utf16->length-4;
1486                 io->n.cleartext_utf16 = &io->n.quoted_utf16;
1487                 io->n.nt_hash = NULL;
1488         } else {
1489                 io->n.nt_hash           = samdb_result_hash(io->ac, new_msg, "unicodePwd");
1490         }
1491
1492         io->n.lm_hash                   = samdb_result_hash(io->ac, new_msg, "dBCSPwd");
1493
1494         return LDB_SUCCESS;
1495 }
1496
1497 static struct ph_context *ph_init_context(struct ldb_module *module,
1498                                           struct ldb_request *req)
1499 {
1500         struct ldb_context *ldb;
1501         struct ph_context *ac;
1502
1503         ldb = ldb_module_get_ctx(module);
1504
1505         ac = talloc_zero(req, struct ph_context);
1506         if (ac == NULL) {
1507                 ldb_set_errstring(ldb, "Out of Memory");
1508                 return NULL;
1509         }
1510
1511         ac->module = module;
1512         ac->req = req;
1513
1514         return ac;
1515 }
1516
1517 static int ph_op_callback(struct ldb_request *req, struct ldb_reply *ares)
1518 {
1519         struct ph_context *ac;
1520
1521         ac = talloc_get_type(req->context, struct ph_context);
1522
1523         if (!ares) {
1524                 return ldb_module_done(ac->req, NULL, NULL,
1525                                         LDB_ERR_OPERATIONS_ERROR);
1526         }
1527         if (ares->error != LDB_SUCCESS) {
1528                 return ldb_module_done(ac->req, ares->controls,
1529                                         ares->response, ares->error);
1530         }
1531
1532         if (ares->type != LDB_REPLY_DONE) {
1533                 talloc_free(ares);
1534                 return ldb_module_done(ac->req, NULL, NULL,
1535                                         LDB_ERR_OPERATIONS_ERROR);
1536         }
1537
1538         return ldb_module_done(ac->req, ares->controls,
1539                                 ares->response, ares->error);
1540 }
1541
1542 static int password_hash_add_do_add(struct ph_context *ac);
1543 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares);
1544 static int password_hash_mod_search_self(struct ph_context *ac);
1545 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares);
1546 static int password_hash_mod_do_mod(struct ph_context *ac);
1547
1548 static int get_domain_data_callback(struct ldb_request *req,
1549                                     struct ldb_reply *ares)
1550 {
1551         struct ldb_context *ldb;
1552         struct domain_data *data;
1553         struct ph_context *ac;
1554         struct loadparm_context *lp_ctx;
1555         int ret;
1556
1557         ac = talloc_get_type(req->context, struct ph_context);
1558         ldb = ldb_module_get_ctx(ac->module);
1559
1560         if (!ares) {
1561                 return ldb_module_done(ac->req, NULL, NULL,
1562                                         LDB_ERR_OPERATIONS_ERROR);
1563         }
1564         if (ares->error != LDB_SUCCESS) {
1565                 return ldb_module_done(ac->req, ares->controls,
1566                                         ares->response, ares->error);
1567         }
1568
1569         switch (ares->type) {
1570         case LDB_REPLY_ENTRY:
1571                 if (ac->domain != NULL) {
1572                         ldb_set_errstring(ldb, "Too many results");
1573                         return ldb_module_done(ac->req, NULL, NULL,
1574                                                 LDB_ERR_OPERATIONS_ERROR);
1575                 }
1576
1577                 data = talloc_zero(ac, struct domain_data);
1578                 if (data == NULL) {
1579                         return ldb_module_done(ac->req, NULL, NULL,
1580                                                 LDB_ERR_OPERATIONS_ERROR);
1581                 }
1582
1583                 data->pwdProperties = samdb_result_uint(ares->message, "pwdProperties", 0);
1584                 data->store_cleartext = data->pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT;
1585                 data->pwdHistoryLength = samdb_result_uint(ares->message, "pwdHistoryLength", 0);
1586
1587                 /* For a domain DN, this puts things in dotted notation */
1588                 /* For builtin domains, this will give details for the host,
1589                  * but that doesn't really matter, as it's just used for salt
1590                  * and kerberos principals, which don't exist here */
1591
1592                 lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
1593                                          struct loadparm_context);
1594
1595                 data->dns_domain = lp_dnsdomain(lp_ctx);
1596                 data->realm = lp_realm(lp_ctx);
1597                 data->netbios_domain = lp_sam_name(lp_ctx);
1598
1599                 ac->domain = data;
1600                 break;
1601
1602         case LDB_REPLY_DONE:
1603
1604                 /* call the next step */
1605                 switch (ac->req->operation) {
1606                 case LDB_ADD:
1607                         ret = password_hash_add_do_add(ac);
1608                         break;
1609
1610                 case LDB_MODIFY:
1611                         ret = password_hash_mod_do_mod(ac);
1612                         break;
1613
1614                 default:
1615                         ret = LDB_ERR_OPERATIONS_ERROR;
1616                         break;
1617                 }
1618                 if (ret != LDB_SUCCESS) {
1619                         return ldb_module_done(ac->req, NULL, NULL, ret);
1620                 }
1621                 break;
1622
1623         case LDB_REPLY_REFERRAL:
1624                 /* ignore */
1625                 break;
1626         }
1627
1628         talloc_free(ares);
1629         return LDB_SUCCESS;
1630 }
1631
1632 static int build_domain_data_request(struct ph_context *ac)
1633 {
1634         /* attrs[] is returned from this function in
1635            ac->dom_req->op.search.attrs, so it must be static, as
1636            otherwise the compiler can put it on the stack */
1637         struct ldb_context *ldb;
1638         static const char * const attrs[] = { "pwdProperties", "pwdHistoryLength", NULL };
1639
1640         ldb = ldb_module_get_ctx(ac->module);
1641
1642         return ldb_build_search_req(&ac->dom_req, ldb, ac,
1643                                     ldb_get_default_basedn(ldb),
1644                                     LDB_SCOPE_BASE,
1645                                     NULL, attrs,
1646                                     NULL,
1647                                     ac, get_domain_data_callback,
1648                                     ac->req);
1649 }
1650
1651 static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
1652 {
1653         struct ldb_context *ldb;
1654         struct ph_context *ac;
1655         struct ldb_message_element *sambaAttr;
1656         struct ldb_message_element *clearTextPasswordAttr;
1657         struct ldb_message_element *ntAttr;
1658         struct ldb_message_element *lmAttr;
1659         int ret;
1660
1661         ldb = ldb_module_get_ctx(module);
1662
1663         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_add\n");
1664
1665         if (ldb_dn_is_special(req->op.add.message->dn)) { /* do not manipulate our control entries */
1666                 return ldb_next_request(module, req);
1667         }
1668
1669         /* If the caller is manipulating the local passwords directly, let them pass */
1670         if (ldb_dn_compare_base(ldb_dn_new(req, ldb, LOCAL_BASE),
1671                                 req->op.add.message->dn) == 0) {
1672                 return ldb_next_request(module, req);
1673         }
1674
1675         /* nobody must touch these fields */
1676         if (ldb_msg_find_element(req->op.add.message, "ntPwdHistory")) {
1677                 return LDB_ERR_UNWILLING_TO_PERFORM;
1678         }
1679         if (ldb_msg_find_element(req->op.add.message, "lmPwdHistory")) {
1680                 return LDB_ERR_UNWILLING_TO_PERFORM;
1681         }
1682         if (ldb_msg_find_element(req->op.add.message, "supplementalCredentials")) {
1683                 return LDB_ERR_UNWILLING_TO_PERFORM;
1684         }
1685
1686         /* If no part of this ADD touches the userPassword, or the NT
1687          * or LM hashes, then we don't need to make any changes.  */
1688
1689         sambaAttr = ldb_msg_find_element(req->op.mod.message, "userPassword");
1690         clearTextPasswordAttr = ldb_msg_find_element(req->op.mod.message, "clearTextPassword");
1691         ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd");
1692         lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd");
1693
1694         if ((!sambaAttr) && (!clearTextPasswordAttr) && (!ntAttr) && (!lmAttr)) {
1695                 return ldb_next_request(module, req);
1696         }
1697
1698         /* if it is not an entry of type person its an error */
1699         /* TODO: remove this when userPassword will be in schema */
1700         if (!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "person")) {
1701                 ldb_set_errstring(ldb, "Cannot set a password on entry that does not have objectClass 'person'");
1702                 return LDB_ERR_OBJECT_CLASS_VIOLATION;
1703         }
1704
1705         /* check userPassword is single valued here */
1706         /* TODO: remove this when userPassword will be single valued in schema */
1707         if (sambaAttr && sambaAttr->num_values > 1) {
1708                 ldb_set_errstring(ldb, "mupltiple values for userPassword not allowed!\n");
1709                 return LDB_ERR_CONSTRAINT_VIOLATION;
1710         }
1711         if (clearTextPasswordAttr && clearTextPasswordAttr->num_values > 1) {
1712                 ldb_set_errstring(ldb, "mupltiple values for clearTextPassword not allowed!\n");
1713                 return LDB_ERR_CONSTRAINT_VIOLATION;
1714         }
1715
1716         if (ntAttr && (ntAttr->num_values > 1)) {
1717                 ldb_set_errstring(ldb, "mupltiple values for unicodePwd not allowed!\n");
1718                 return LDB_ERR_CONSTRAINT_VIOLATION;
1719         }
1720         if (lmAttr && (lmAttr->num_values > 1)) {
1721                 ldb_set_errstring(ldb, "mupltiple values for dBCSPwd not allowed!\n");
1722                 return LDB_ERR_CONSTRAINT_VIOLATION;
1723         }
1724
1725         if (sambaAttr && sambaAttr->num_values == 0) {
1726                 ldb_set_errstring(ldb, "userPassword must have a value!\n");
1727                 return LDB_ERR_CONSTRAINT_VIOLATION;
1728         }
1729
1730         if (clearTextPasswordAttr && clearTextPasswordAttr->num_values == 0) {
1731                 ldb_set_errstring(ldb, "clearTextPassword must have a value!\n");
1732                 return LDB_ERR_CONSTRAINT_VIOLATION;
1733         }
1734
1735         if (ntAttr && (ntAttr->num_values == 0)) {
1736                 ldb_set_errstring(ldb, "unicodePwd must have a value!\n");
1737                 return LDB_ERR_CONSTRAINT_VIOLATION;
1738         }
1739         if (lmAttr && (lmAttr->num_values == 0)) {
1740                 ldb_set_errstring(ldb, "dBCSPwd must have a value!\n");
1741                 return LDB_ERR_CONSTRAINT_VIOLATION;
1742         }
1743
1744         ac = ph_init_context(module, req);
1745         if (ac == NULL) {
1746                 return LDB_ERR_OPERATIONS_ERROR;
1747         }
1748
1749         /* get user domain data */
1750         ret = build_domain_data_request(ac);
1751         if (ret != LDB_SUCCESS) {
1752                 return ret;
1753         }
1754
1755         return ldb_next_request(module, ac->dom_req);
1756 }
1757
1758 static int password_hash_add_do_add(struct ph_context *ac)
1759 {
1760         struct ldb_context *ldb;
1761         struct ldb_request *down_req;
1762         struct ldb_message *msg;
1763         struct setup_password_fields_io io;
1764         int ret;
1765
1766         /* Prepare the internal data structure containing the passwords */
1767         ret = setup_io(ac, ac->req->op.add.message, ac->req->op.add.message, &io);
1768         if (ret != LDB_SUCCESS) {
1769                 return ret;
1770         }
1771
1772         msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
1773         if (msg == NULL) {
1774                 return LDB_ERR_OPERATIONS_ERROR;
1775         }
1776
1777         /* remove attributes that we just read into 'io' */
1778         ldb_msg_remove_attr(msg, "userPassword");
1779         ldb_msg_remove_attr(msg, "clearTextPassword");
1780         ldb_msg_remove_attr(msg, "unicodePwd");
1781         ldb_msg_remove_attr(msg, "dBCSPwd");
1782         ldb_msg_remove_attr(msg, "pwdLastSet");
1783         io.o.kvno = samdb_result_uint(msg, "msDs-KeyVersionNumber", 1) - 1;
1784         ldb_msg_remove_attr(msg, "msDs-KeyVersionNumber");
1785
1786         ldb = ldb_module_get_ctx(ac->module);
1787
1788         ret = setup_password_fields(&io);
1789         if (ret != LDB_SUCCESS) {
1790                 return ret;
1791         }
1792
1793         if (io.g.nt_hash) {
1794                 ret = samdb_msg_add_hash(ldb, ac, msg,
1795                                          "unicodePwd", io.g.nt_hash);
1796                 if (ret != LDB_SUCCESS) {
1797                         return ret;
1798                 }
1799         }
1800         if (io.g.lm_hash) {
1801                 ret = samdb_msg_add_hash(ldb, ac, msg,
1802                                          "dBCSPwd", io.g.lm_hash);
1803                 if (ret != LDB_SUCCESS) {
1804                         return ret;
1805                 }
1806         }
1807         if (io.g.nt_history_len > 0) {
1808                 ret = samdb_msg_add_hashes(ac, msg,
1809                                            "ntPwdHistory",
1810                                            io.g.nt_history,
1811                                            io.g.nt_history_len);
1812                 if (ret != LDB_SUCCESS) {
1813                         return ret;
1814                 }
1815         }
1816         if (io.g.lm_history_len > 0) {
1817                 ret = samdb_msg_add_hashes(ac, msg,
1818                                            "lmPwdHistory",
1819                                            io.g.lm_history,
1820                                            io.g.lm_history_len);
1821                 if (ret != LDB_SUCCESS) {
1822                         return ret;
1823                 }
1824         }
1825         if (io.g.supplemental.length > 0) {
1826                 ret = ldb_msg_add_value(msg, "supplementalCredentials",
1827                                         &io.g.supplemental, NULL);
1828                 if (ret != LDB_SUCCESS) {
1829                         return ret;
1830                 }
1831         }
1832         ret = samdb_msg_add_uint64(ldb, ac, msg,
1833                                    "pwdLastSet",
1834                                    io.g.last_set);
1835         if (ret != LDB_SUCCESS) {
1836                 return ret;
1837         }
1838         ret = samdb_msg_add_uint(ldb, ac, msg,
1839                                  "msDs-KeyVersionNumber",
1840                                  io.g.kvno);
1841         if (ret != LDB_SUCCESS) {
1842                 return ret;
1843         }
1844
1845         ret = ldb_build_add_req(&down_req, ldb, ac,
1846                                 msg,
1847                                 ac->req->controls,
1848                                 ac, ph_op_callback,
1849                                 ac->req);
1850         if (ret != LDB_SUCCESS) {
1851                 return ret;
1852         }
1853
1854         return ldb_next_request(ac->module, down_req);
1855 }
1856
1857 static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
1858 {
1859         struct ldb_context *ldb;
1860         struct ph_context *ac;
1861         struct ldb_message_element *sambaAttr;
1862         struct ldb_message_element *clearTextAttr;
1863         struct ldb_message_element *ntAttr;
1864         struct ldb_message_element *lmAttr;
1865         struct ldb_message *msg;
1866         struct ldb_request *down_req;
1867         int ret;
1868
1869         ldb = ldb_module_get_ctx(module);
1870
1871         ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");
1872
1873         if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */
1874                 return ldb_next_request(module, req);
1875         }
1876         
1877         /* If the caller is manipulating the local passwords directly, let them pass */
1878         if (ldb_dn_compare_base(ldb_dn_new(req, ldb, LOCAL_BASE),
1879                                 req->op.mod.message->dn) == 0) {
1880                 return ldb_next_request(module, req);
1881         }
1882
1883         /* nobody must touch password Histories */
1884         if (ldb_msg_find_element(req->op.add.message, "ntPwdHistory")) {
1885                 return LDB_ERR_UNWILLING_TO_PERFORM;
1886         }
1887         if (ldb_msg_find_element(req->op.add.message, "lmPwdHistory")) {
1888                 return LDB_ERR_UNWILLING_TO_PERFORM;
1889         }
1890         if (ldb_msg_find_element(req->op.add.message, "supplementalCredentials")) {
1891                 return LDB_ERR_UNWILLING_TO_PERFORM;
1892         }
1893
1894         sambaAttr = ldb_msg_find_element(req->op.mod.message, "userPassword");
1895         clearTextAttr = ldb_msg_find_element(req->op.mod.message, "clearTextPassword");
1896         ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd");
1897         lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd");
1898
1899         /* If no part of this touches the userPassword OR
1900          * clearTextPassword OR unicodePwd and/or dBCSPwd, then we
1901          * don't need to make any changes.  For password changes/set
1902          * there should be a 'delete' or a 'modify' on this
1903          * attribute. */
1904         if ((!sambaAttr) && (!clearTextAttr) && (!ntAttr) && (!lmAttr)) {
1905                 return ldb_next_request(module, req);
1906         }
1907
1908         /* check passwords are single valued here */
1909         /* TODO: remove this when passwords will be single valued in schema */
1910         if (sambaAttr && (sambaAttr->num_values > 1)) {
1911                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1912                 return LDB_ERR_CONSTRAINT_VIOLATION;
1913         }
1914         if (clearTextAttr && (clearTextAttr->num_values > 1)) {
1915                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1916                 return LDB_ERR_CONSTRAINT_VIOLATION;
1917         }
1918         if (ntAttr && (ntAttr->num_values > 1)) {
1919                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1920                 return LDB_ERR_CONSTRAINT_VIOLATION;
1921         }
1922         if (lmAttr && (lmAttr->num_values > 1)) {
1923                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1924                 return LDB_ERR_CONSTRAINT_VIOLATION;
1925         }
1926
1927         ac = ph_init_context(module, req);
1928         if (!ac) {
1929                 DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1930                 return LDB_ERR_OPERATIONS_ERROR;
1931         }
1932
1933         /* use a new message structure so that we can modify it */
1934         msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
1935         if (msg == NULL) {
1936                 ldb_oom(ldb);
1937                 return LDB_ERR_OPERATIONS_ERROR;
1938         }
1939
1940         /* - remove any modification to the password from the first commit
1941          *   we will make the real modification later */
1942         if (sambaAttr) ldb_msg_remove_attr(msg, "userPassword");
1943         if (clearTextAttr) ldb_msg_remove_attr(msg, "clearTextPassword");
1944         if (ntAttr) ldb_msg_remove_attr(msg, "unicodePwd");
1945         if (lmAttr) ldb_msg_remove_attr(msg, "dBCSPwd");
1946
1947         /* if there was nothing else to be modified skip to next step */
1948         if (msg->num_elements == 0) {
1949                 return password_hash_mod_search_self(ac);
1950         }
1951
1952         ret = ldb_build_mod_req(&down_req, ldb, ac,
1953                                 msg,
1954                                 req->controls,
1955                                 ac, ph_modify_callback,
1956                                 req);
1957         if (ret != LDB_SUCCESS) {
1958                 return ret;
1959         }
1960
1961         return ldb_next_request(module, down_req);
1962 }
1963
1964 static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
1965 {
1966         struct ph_context *ac;
1967         int ret;
1968
1969         ac = talloc_get_type(req->context, struct ph_context);
1970
1971         if (!ares) {
1972                 return ldb_module_done(ac->req, NULL, NULL,
1973                                         LDB_ERR_OPERATIONS_ERROR);
1974         }
1975         if (ares->error != LDB_SUCCESS) {
1976                 return ldb_module_done(ac->req, ares->controls,
1977                                         ares->response, ares->error);
1978         }
1979
1980         if (ares->type != LDB_REPLY_DONE) {
1981                 talloc_free(ares);
1982                 return ldb_module_done(ac->req, NULL, NULL,
1983                                         LDB_ERR_OPERATIONS_ERROR);
1984         }
1985
1986         ret = password_hash_mod_search_self(ac);
1987         if (ret != LDB_SUCCESS) {
1988                 return ldb_module_done(ac->req, NULL, NULL, ret);
1989         }
1990
1991         talloc_free(ares);
1992         return LDB_SUCCESS;
1993 }
1994
1995 static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
1996 {
1997         struct ldb_context *ldb;
1998         struct ph_context *ac;
1999         int ret;
2000
2001         ac = talloc_get_type(req->context, struct ph_context);
2002         ldb = ldb_module_get_ctx(ac->module);
2003
2004         if (!ares) {
2005                 return ldb_module_done(ac->req, NULL, NULL,
2006                                         LDB_ERR_OPERATIONS_ERROR);
2007         }
2008         if (ares->error != LDB_SUCCESS) {
2009                 return ldb_module_done(ac->req, ares->controls,
2010                                         ares->response, ares->error);
2011         }
2012
2013         /* we are interested only in the single reply (base search) */
2014         switch (ares->type) {
2015         case LDB_REPLY_ENTRY:
2016
2017                 if (ac->search_res != NULL) {
2018                         ldb_set_errstring(ldb, "Too many results");
2019                         talloc_free(ares);
2020                         return ldb_module_done(ac->req, NULL, NULL,
2021                                                 LDB_ERR_OPERATIONS_ERROR);
2022                 }
2023
2024                 /* if it is not an entry of type person this is an error */
2025                 /* TODO: remove this when sambaPassword will be in schema */
2026                 if (!ldb_msg_check_string_attribute(ares->message, "objectClass", "person")) {
2027                         ldb_set_errstring(ldb, "Object class violation");
2028                         talloc_free(ares);
2029                         return ldb_module_done(ac->req, NULL, NULL,
2030                                         LDB_ERR_OBJECT_CLASS_VIOLATION);
2031                 }
2032
2033                 ac->search_res = talloc_steal(ac, ares);
2034                 return LDB_SUCCESS;
2035
2036         case LDB_REPLY_DONE:
2037
2038                 /* get user domain data */
2039                 ret = build_domain_data_request(ac);
2040                 if (ret != LDB_SUCCESS) {
2041                         return ldb_module_done(ac->req, NULL, NULL,ret);
2042                 }
2043
2044                 return ldb_next_request(ac->module, ac->dom_req);
2045
2046         case LDB_REPLY_REFERRAL:
2047                 /*ignore anything else for now */
2048                 break;
2049         }
2050
2051         talloc_free(ares);
2052         return LDB_SUCCESS;
2053 }
2054
2055 static int password_hash_mod_search_self(struct ph_context *ac)
2056 {
2057         struct ldb_context *ldb;
2058         static const char * const attrs[] = { "userAccountControl", "lmPwdHistory", 
2059                                               "ntPwdHistory", 
2060                                               "objectSid", "msDS-KeyVersionNumber", 
2061                                               "objectClass", "userPrincipalName",
2062                                               "sAMAccountName", 
2063                                               "dBCSPwd", "unicodePwd",
2064                                               "supplementalCredentials",
2065                                               NULL };
2066         struct ldb_request *search_req;
2067         int ret;
2068
2069         ldb = ldb_module_get_ctx(ac->module);
2070
2071         ret = ldb_build_search_req(&search_req, ldb, ac,
2072                                    ac->req->op.mod.message->dn,
2073                                    LDB_SCOPE_BASE,
2074                                    "(objectclass=*)",
2075                                    attrs,
2076                                    NULL,
2077                                    ac, ph_mod_search_callback,
2078                                    ac->req);
2079
2080         if (ret != LDB_SUCCESS) {
2081                 return ret;
2082         }
2083
2084         return ldb_next_request(ac->module, search_req);
2085 }
2086
2087 static int password_hash_mod_do_mod(struct ph_context *ac)
2088 {
2089         struct ldb_context *ldb;
2090         struct ldb_request *mod_req;
2091         struct ldb_message *msg;
2092         const struct ldb_message *searched_msg;
2093         struct setup_password_fields_io io;
2094         int ret;
2095
2096         ldb = ldb_module_get_ctx(ac->module);
2097
2098         /* use a new message structure so that we can modify it */
2099         msg = ldb_msg_new(ac);
2100         if (msg == NULL) {
2101                 return LDB_ERR_OPERATIONS_ERROR;
2102         }
2103
2104         /* modify dn */
2105         msg->dn = ac->req->op.mod.message->dn;
2106
2107         /* Prepare the internal data structure containing the passwords */
2108         ret = setup_io(ac, 
2109                        ac->req->op.mod.message, 
2110                        ac->search_res->message, 
2111                        &io);
2112         if (ret != LDB_SUCCESS) {
2113                 return ret;
2114         }
2115         
2116         searched_msg = ac->search_res->message;
2117
2118         /* Fill in some final details (only relevent once the password has been set) */
2119         io.o.kvno                       = samdb_result_uint(searched_msg, "msDs-KeyVersionNumber", 0);
2120         io.o.nt_history_len             = samdb_result_hashes(io.ac, searched_msg, "ntPwdHistory", &io.o.nt_history);
2121         io.o.lm_history_len             = samdb_result_hashes(io.ac, searched_msg, "lmPwdHistory", &io.o.lm_history);
2122         io.o.supplemental               = ldb_msg_find_ldb_val(searched_msg, "supplementalCredentials");
2123
2124         ret = setup_password_fields(&io);
2125         if (ret != LDB_SUCCESS) {
2126                 return ret;
2127         }
2128
2129         /* make sure we replace all the old attributes */
2130         ret = ldb_msg_add_empty(msg, "unicodePwd", LDB_FLAG_MOD_REPLACE, NULL);
2131         ret = ldb_msg_add_empty(msg, "dBCSPwd", LDB_FLAG_MOD_REPLACE, NULL);
2132         ret = ldb_msg_add_empty(msg, "ntPwdHistory", LDB_FLAG_MOD_REPLACE, NULL);
2133         ret = ldb_msg_add_empty(msg, "lmPwdHistory", LDB_FLAG_MOD_REPLACE, NULL);
2134         ret = ldb_msg_add_empty(msg, "supplementalCredentials", LDB_FLAG_MOD_REPLACE, NULL);
2135         ret = ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE, NULL);
2136         ret = ldb_msg_add_empty(msg, "msDs-KeyVersionNumber", LDB_FLAG_MOD_REPLACE, NULL);
2137
2138         if (io.g.nt_hash) {
2139                 ret = samdb_msg_add_hash(ldb, ac, msg,
2140                                          "unicodePwd", io.g.nt_hash);
2141                 if (ret != LDB_SUCCESS) {
2142                         return ret;
2143                 }
2144         }
2145         if (io.g.lm_hash) {
2146                 ret = samdb_msg_add_hash(ldb, ac, msg,
2147                                          "dBCSPwd", io.g.lm_hash);
2148                 if (ret != LDB_SUCCESS) {
2149                         return ret;
2150                 }
2151         }
2152         if (io.g.nt_history_len > 0) {
2153                 ret = samdb_msg_add_hashes(ac, msg,
2154                                            "ntPwdHistory",
2155                                            io.g.nt_history,
2156                                            io.g.nt_history_len);
2157                 if (ret != LDB_SUCCESS) {
2158                         return ret;
2159                 }
2160         }
2161         if (io.g.lm_history_len > 0) {
2162                 ret = samdb_msg_add_hashes(ac, msg,
2163                                            "lmPwdHistory",
2164                                            io.g.lm_history,
2165                                            io.g.lm_history_len);
2166                 if (ret != LDB_SUCCESS) {
2167                         return ret;
2168                 }
2169         }
2170         if (io.g.supplemental.length > 0) {
2171                 ret = ldb_msg_add_value(msg, "supplementalCredentials",
2172                                         &io.g.supplemental, NULL);
2173                 if (ret != LDB_SUCCESS) {
2174                         return ret;
2175                 }
2176         }
2177         ret = samdb_msg_add_uint64(ldb, ac, msg,
2178                                    "pwdLastSet",
2179                                    io.g.last_set);
2180         if (ret != LDB_SUCCESS) {
2181                 return ret;
2182         }
2183         ret = samdb_msg_add_uint(ldb, ac, msg,
2184                                  "msDs-KeyVersionNumber",
2185                                  io.g.kvno);
2186         if (ret != LDB_SUCCESS) {
2187                 return ret;
2188         }
2189
2190         ret = ldb_build_mod_req(&mod_req, ldb, ac,
2191                                 msg,
2192                                 ac->req->controls,
2193                                 ac, ph_op_callback,
2194                                 ac->req);
2195         if (ret != LDB_SUCCESS) {
2196                 return ret;
2197         }
2198
2199         return ldb_next_request(ac->module, mod_req);
2200 }
2201
2202 _PUBLIC_ const struct ldb_module_ops ldb_password_hash_module_ops = {
2203         .name          = "password_hash",
2204         .add           = password_hash_add,
2205         .modify        = password_hash_modify,
2206 };