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