• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/dsdb/samdb/ldb_modules/
1/*
2   ldb database module
3
4   Copyright (C) Simo Sorce  2004-2008
5   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
6   Copyright (C) Andrew Tridgell 2004
7   Copyright (C) Stefan Metzmacher 2007
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <http://www.gnu.org/licenses/>.
21*/
22
23/*
24 *  Name: ldb
25 *
26 *  Component: ldb password_hash module
27 *
28 *  Description: correctly update hash values based on changes to userPassword and friends
29 *
30 *  Author: Andrew Bartlett
31 *  Author: Stefan Metzmacher
32 */
33
34#include "includes.h"
35#include "libcli/ldap/ldap_ndr.h"
36#include "ldb_module.h"
37#include "librpc/gen_ndr/misc.h"
38#include "librpc/gen_ndr/samr.h"
39#include "libcli/auth/libcli_auth.h"
40#include "libcli/security/security.h"
41#include "system/kerberos.h"
42#include "auth/kerberos/kerberos.h"
43#include "system/time.h"
44#include "dsdb/samdb/samdb.h"
45#include "../libds/common/flags.h"
46#include "dsdb/samdb/ldb_modules/password_modules.h"
47#include "librpc/ndr/libndr.h"
48#include "librpc/gen_ndr/ndr_drsblobs.h"
49#include "../lib/crypto/crypto.h"
50#include "param/param.h"
51
52/* If we have decided there is reason to work on this request, then
53 * setup all the password hash types correctly.
54 *
55 * If the administrator doesn't want the userPassword stored (set in the
56 * domain and per-account policies) then we must strip that out before
57 * we do the first operation.
58 *
59 * Once this is done (which could update anything at all), we
60 * calculate the password hashes.
61 *
62 * This function must not only update the unicodePwd, dBCSPwd and
63 * supplementalCredentials fields, it must also atomicly increment the
64 * msDS-KeyVersionNumber.  We should be in a transaction, so all this
65 * should be quite safe...
66 *
67 * Finally, if the administrator has requested that a password history
68 * be maintained, then this should also be written out.
69 *
70 */
71
72struct 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
86struct 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
95struct 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
150static 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
192static 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
227static 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 = strlower_talloc(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
432static 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
534static 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
654static 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
984static 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	int *domainFunctionality;
1030
1031	ZERO_STRUCT(zero16);
1032	ZERO_STRUCT(names);
1033
1034	ldb = ldb_module_get_ctx(io->ac->module);
1035
1036	if (!io->n.cleartext_utf8) {
1037		/*
1038		 * when we don't have a cleartext password
1039		 * we can't setup a supplementalCredential value
1040		 */
1041		return LDB_SUCCESS;
1042	}
1043
1044	/* if there's an old supplementaCredentials blob then parse it */
1045	if (io->o.supplemental) {
1046		ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac,
1047						   lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1048						   &_old_scb,
1049						   (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
1050		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1051			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1052			ldb_asprintf_errstring(ldb,
1053					       "setup_supplemental_field: "
1054					       "failed to pull old supplementalCredentialsBlob: %s",
1055					       nt_errstr(status));
1056			return LDB_ERR_OPERATIONS_ERROR;
1057		}
1058
1059		if (_old_scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
1060			old_scb = &_old_scb;
1061		} else {
1062			ldb_debug(ldb, LDB_DEBUG_ERROR,
1063					       "setup_supplemental_field: "
1064					       "supplementalCredentialsBlob signature[0x%04X] expected[0x%04X]",
1065					       _old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
1066		}
1067	}
1068	/* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
1069	domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
1070
1071	do_newer_keys = *domainFunctionality &&
1072		(*domainFunctionality >= DS_DOMAIN_FUNCTION_2008);
1073
1074	if (io->domain->store_cleartext &&
1075	    (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
1076		do_cleartext = true;
1077	}
1078
1079	/*
1080	 * The ordering is this
1081	 *
1082	 * Primary:Kerberos-Newer-Keys (optional)
1083	 * Primary:Kerberos
1084	 * Primary:WDigest
1085	 * Primary:CLEARTEXT (optional)
1086	 *
1087	 * And the 'Packages' package is insert before the last
1088	 * other package.
1089	 */
1090	if (do_newer_keys) {
1091		/* Primary:Kerberos-Newer-Keys */
1092		nkn = &names[num_names++];
1093		pkn = &packages[num_packages++];
1094	}
1095
1096	/* Primary:Kerberos */
1097	nk = &names[num_names++];
1098	pk = &packages[num_packages++];
1099
1100	if (!do_cleartext) {
1101		/* Packages */
1102		pp = &packages[num_packages++];
1103	}
1104
1105	/* Primary:WDigest */
1106	nd = &names[num_names++];
1107	pd = &packages[num_packages++];
1108
1109	if (do_cleartext) {
1110		/* Packages */
1111		pp = &packages[num_packages++];
1112
1113		/* Primary:CLEARTEXT */
1114		nc = &names[num_names++];
1115		pc = &packages[num_packages++];
1116	}
1117
1118	if (pkn) {
1119		/*
1120		 * setup 'Primary:Kerberos-Newer-Keys' element
1121		 */
1122		*nkn = "Kerberos-Newer-Keys";
1123
1124		ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
1125		if (ret != LDB_SUCCESS) {
1126			return ret;
1127		}
1128
1129		ndr_err = ndr_push_struct_blob(&pknb_blob, io->ac,
1130					       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1131					       &pknb,
1132					       (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1133		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1134			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1135			ldb_asprintf_errstring(ldb,
1136					       "setup_supplemental_field: "
1137					       "failed to push package_PrimaryKerberosNeverBlob: %s",
1138					       nt_errstr(status));
1139			return LDB_ERR_OPERATIONS_ERROR;
1140		}
1141		pknb_hexstr = data_blob_hex_string(io->ac, &pknb_blob);
1142		if (!pknb_hexstr) {
1143			ldb_oom(ldb);
1144			return LDB_ERR_OPERATIONS_ERROR;
1145		}
1146		pkn->name	= "Primary:Kerberos-Newer-Keys";
1147		pkn->reserved	= 1;
1148		pkn->data	= pknb_hexstr;
1149	}
1150
1151	/*
1152	 * setup 'Primary:Kerberos' element
1153	 */
1154	*nk = "Kerberos";
1155
1156	ret = setup_primary_kerberos(io, old_scb, &pkb);
1157	if (ret != LDB_SUCCESS) {
1158		return ret;
1159	}
1160
1161	ndr_err = ndr_push_struct_blob(&pkb_blob, io->ac,
1162				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1163				       &pkb,
1164				       (ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
1165	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1166		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1167		ldb_asprintf_errstring(ldb,
1168				       "setup_supplemental_field: "
1169				       "failed to push package_PrimaryKerberosBlob: %s",
1170				       nt_errstr(status));
1171		return LDB_ERR_OPERATIONS_ERROR;
1172	}
1173	pkb_hexstr = data_blob_hex_string(io->ac, &pkb_blob);
1174	if (!pkb_hexstr) {
1175		ldb_oom(ldb);
1176		return LDB_ERR_OPERATIONS_ERROR;
1177	}
1178	pk->name	= "Primary:Kerberos";
1179	pk->reserved	= 1;
1180	pk->data	= pkb_hexstr;
1181
1182	/*
1183	 * setup 'Primary:WDigest' element
1184	 */
1185	*nd = "WDigest";
1186
1187	ret = setup_primary_wdigest(io, old_scb, &pdb);
1188	if (ret != LDB_SUCCESS) {
1189		return ret;
1190	}
1191
1192	ndr_err = ndr_push_struct_blob(&pdb_blob, io->ac,
1193				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1194				       &pdb,
1195				       (ndr_push_flags_fn_t)ndr_push_package_PrimaryWDigestBlob);
1196	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1197		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1198		ldb_asprintf_errstring(ldb,
1199				       "setup_supplemental_field: "
1200				       "failed to push package_PrimaryWDigestBlob: %s",
1201				       nt_errstr(status));
1202		return LDB_ERR_OPERATIONS_ERROR;
1203	}
1204	pdb_hexstr = data_blob_hex_string(io->ac, &pdb_blob);
1205	if (!pdb_hexstr) {
1206		ldb_oom(ldb);
1207		return LDB_ERR_OPERATIONS_ERROR;
1208	}
1209	pd->name	= "Primary:WDigest";
1210	pd->reserved	= 1;
1211	pd->data	= pdb_hexstr;
1212
1213	/*
1214	 * setup 'Primary:CLEARTEXT' element
1215	 */
1216	if (pc) {
1217		*nc		= "CLEARTEXT";
1218
1219		pcb.cleartext	= *io->n.cleartext_utf16;
1220
1221		ndr_err = ndr_push_struct_blob(&pcb_blob, io->ac,
1222					       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1223					       &pcb,
1224					       (ndr_push_flags_fn_t)ndr_push_package_PrimaryCLEARTEXTBlob);
1225		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1226			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1227			ldb_asprintf_errstring(ldb,
1228					       "setup_supplemental_field: "
1229					       "failed to push package_PrimaryCLEARTEXTBlob: %s",
1230					       nt_errstr(status));
1231			return LDB_ERR_OPERATIONS_ERROR;
1232		}
1233		pcb_hexstr = data_blob_hex_string(io->ac, &pcb_blob);
1234		if (!pcb_hexstr) {
1235			ldb_oom(ldb);
1236			return LDB_ERR_OPERATIONS_ERROR;
1237		}
1238		pc->name	= "Primary:CLEARTEXT";
1239		pc->reserved	= 1;
1240		pc->data	= pcb_hexstr;
1241	}
1242
1243	/*
1244	 * setup 'Packages' element
1245	 */
1246	pb.names = names;
1247	ndr_err = ndr_push_struct_blob(&pb_blob, io->ac,
1248				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1249				       &pb,
1250				       (ndr_push_flags_fn_t)ndr_push_package_PackagesBlob);
1251	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1252		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1253		ldb_asprintf_errstring(ldb,
1254				       "setup_supplemental_field: "
1255				       "failed to push package_PackagesBlob: %s",
1256				       nt_errstr(status));
1257		return LDB_ERR_OPERATIONS_ERROR;
1258	}
1259	pb_hexstr = data_blob_hex_string(io->ac, &pb_blob);
1260	if (!pb_hexstr) {
1261		ldb_oom(ldb);
1262		return LDB_ERR_OPERATIONS_ERROR;
1263	}
1264	pp->name	= "Packages";
1265	pp->reserved	= 2;
1266	pp->data	= pb_hexstr;
1267
1268	/*
1269	 * setup 'supplementalCredentials' value
1270	 */
1271	ZERO_STRUCT(scb);
1272	scb.sub.num_packages	= num_packages;
1273	scb.sub.packages	= packages;
1274
1275	ndr_err = ndr_push_struct_blob(&io->g.supplemental, io->ac,
1276				       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1277				       &scb,
1278				       (ndr_push_flags_fn_t)ndr_push_supplementalCredentialsBlob);
1279	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1280		NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1281		ldb_asprintf_errstring(ldb,
1282				       "setup_supplemental_field: "
1283				       "failed to push supplementalCredentialsBlob: %s",
1284				       nt_errstr(status));
1285		return LDB_ERR_OPERATIONS_ERROR;
1286	}
1287
1288	return LDB_SUCCESS;
1289}
1290
1291static int setup_last_set_field(struct setup_password_fields_io *io)
1292{
1293	/* set it as now */
1294	unix_to_nt_time(&io->g.last_set, time(NULL));
1295
1296	return LDB_SUCCESS;
1297}
1298
1299static int setup_kvno_field(struct setup_password_fields_io *io)
1300{
1301	/* increment by one */
1302	io->g.kvno = io->o.kvno + 1;
1303
1304	return LDB_SUCCESS;
1305}
1306
1307static int setup_password_fields(struct setup_password_fields_io *io)
1308{
1309	struct ldb_context *ldb;
1310	bool ok;
1311	int ret;
1312	size_t converted_pw_len;
1313
1314	ldb = ldb_module_get_ctx(io->ac->module);
1315
1316	/*
1317	 * refuse the change if someone want to change the cleartext
1318	 * and supply his own hashes at the same time...
1319	 */
1320	if ((io->n.cleartext_utf8 || io->n.cleartext_utf16) && (io->n.nt_hash || io->n.lm_hash)) {
1321		ldb_asprintf_errstring(ldb,
1322				       "setup_password_fields: "
1323				       "it's only allowed to set the cleartext password or the password hashes");
1324		return LDB_ERR_UNWILLING_TO_PERFORM;
1325	}
1326
1327	if (io->n.cleartext_utf8 && io->n.cleartext_utf16) {
1328		ldb_asprintf_errstring(ldb,
1329				       "setup_password_fields: "
1330				       "it's only allowed to set the cleartext password as userPassword or clearTextPasssword, not both at once");
1331		return LDB_ERR_UNWILLING_TO_PERFORM;
1332	}
1333
1334	if (io->n.cleartext_utf8) {
1335		char **cleartext_utf16_str;
1336		struct ldb_val *cleartext_utf16_blob;
1337		io->n.cleartext_utf16 = cleartext_utf16_blob = talloc(io->ac, struct ldb_val);
1338		if (!io->n.cleartext_utf16) {
1339			ldb_oom(ldb);
1340			return LDB_ERR_OPERATIONS_ERROR;
1341		}
1342		if (!convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1343							 CH_UTF8, CH_UTF16, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length,
1344							 (void **)&cleartext_utf16_str, &converted_pw_len, false)) {
1345			ldb_asprintf_errstring(ldb,
1346					       "setup_password_fields: "
1347					       "failed to generate UTF16 password from cleartext UTF8 password");
1348			return LDB_ERR_OPERATIONS_ERROR;
1349		}
1350		*cleartext_utf16_blob = data_blob_const(cleartext_utf16_str, converted_pw_len);
1351	} else if (io->n.cleartext_utf16) {
1352		char *cleartext_utf8_str;
1353		struct ldb_val *cleartext_utf8_blob;
1354		io->n.cleartext_utf8 = cleartext_utf8_blob = talloc(io->ac, struct ldb_val);
1355		if (!io->n.cleartext_utf8) {
1356			ldb_oom(ldb);
1357			return LDB_ERR_OPERATIONS_ERROR;
1358		}
1359		if (!convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1360							 CH_UTF16MUNGED, CH_UTF8, io->n.cleartext_utf16->data, io->n.cleartext_utf16->length,
1361							 (void **)&cleartext_utf8_str, &converted_pw_len, false)) {
1362			/* We can't bail out entirely, as these unconvertable passwords are frustratingly valid */
1363			io->n.cleartext_utf8 = NULL;
1364			talloc_free(cleartext_utf8_blob);
1365		}
1366		*cleartext_utf8_blob = data_blob_const(cleartext_utf8_str, converted_pw_len);
1367	}
1368	if (io->n.cleartext_utf16) {
1369		struct samr_Password *nt_hash;
1370		nt_hash = talloc(io->ac, struct samr_Password);
1371		if (!nt_hash) {
1372			ldb_oom(ldb);
1373			return LDB_ERR_OPERATIONS_ERROR;
1374		}
1375		io->n.nt_hash = nt_hash;
1376
1377		/* compute the new nt hash */
1378		mdfour(nt_hash->hash, io->n.cleartext_utf16->data, io->n.cleartext_utf16->length);
1379	}
1380
1381	if (io->n.cleartext_utf8) {
1382		struct samr_Password *lm_hash;
1383		char *cleartext_unix;
1384		if (lp_lanman_auth(ldb_get_opaque(ldb, "loadparm")) &&
1385		    convert_string_talloc_convenience(io->ac, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
1386							 CH_UTF8, CH_UNIX, io->n.cleartext_utf8->data, io->n.cleartext_utf8->length,
1387							 (void **)&cleartext_unix, &converted_pw_len, false)) {
1388			lm_hash = talloc(io->ac, struct samr_Password);
1389			if (!lm_hash) {
1390				ldb_oom(ldb);
1391				return LDB_ERR_OPERATIONS_ERROR;
1392			}
1393
1394			/* compute the new lm hash.   */
1395			ok = E_deshash((char *)cleartext_unix, lm_hash->hash);
1396			if (ok) {
1397				io->n.lm_hash = lm_hash;
1398			} else {
1399				talloc_free(lm_hash->hash);
1400			}
1401		}
1402
1403		ret = setup_kerberos_keys(io);
1404		if (ret != LDB_SUCCESS) {
1405			return ret;
1406		}
1407	}
1408
1409	ret = setup_nt_fields(io);
1410	if (ret != LDB_SUCCESS) {
1411		return ret;
1412	}
1413
1414	ret = setup_lm_fields(io);
1415	if (ret != LDB_SUCCESS) {
1416		return ret;
1417	}
1418
1419	ret = setup_supplemental_field(io);
1420	if (ret != LDB_SUCCESS) {
1421		return ret;
1422	}
1423
1424	ret = setup_last_set_field(io);
1425	if (ret != LDB_SUCCESS) {
1426		return ret;
1427	}
1428
1429	ret = setup_kvno_field(io);
1430	if (ret != LDB_SUCCESS) {
1431		return ret;
1432	}
1433
1434	return LDB_SUCCESS;
1435}
1436
1437static int setup_io(struct ph_context *ac,
1438		    const struct ldb_message *new_msg,
1439		    const struct ldb_message *searched_msg,
1440		    struct setup_password_fields_io *io)
1441{
1442	const struct ldb_val *quoted_utf16;
1443	struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
1444
1445	ZERO_STRUCTP(io);
1446
1447	/* Some operations below require kerberos contexts */
1448	if (smb_krb5_init_context(ac,
1449				  ldb_get_event_context(ldb),
1450				  (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
1451				  &io->smb_krb5_context) != 0) {
1452		return LDB_ERR_OPERATIONS_ERROR;
1453	}
1454
1455	io->ac				= ac;
1456	io->domain			= ac->domain;
1457
1458	io->u.user_account_control	= samdb_result_uint(searched_msg, "userAccountControl", 0);
1459	io->u.sAMAccountName		= samdb_result_string(searched_msg, "samAccountName", NULL);
1460	io->u.user_principal_name	= samdb_result_string(searched_msg, "userPrincipalName", NULL);
1461	io->u.is_computer		= ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");
1462
1463	io->n.cleartext_utf8		= ldb_msg_find_ldb_val(new_msg, "userPassword");
1464	io->n.cleartext_utf16		= ldb_msg_find_ldb_val(new_msg, "clearTextPassword");
1465
1466	/* this rather strange looking piece of code is there to
1467	   handle a ldap client setting a password remotely using the
1468	   unicodePwd ldap field. The syntax is that the password is
1469	   in UTF-16LE, with a " at either end. Unfortunately the
1470	   unicodePwd field is also used to store the nt hashes
1471	   internally in Samba, and is used in the nt hash format on
1472	   the wire in DRS replication, so we have a single name for
1473	   two distinct values. The code below leaves us with a small
1474	   chance (less than 1 in 2^32) of a mixup, if someone manages
1475	   to create a MD4 hash which starts and ends in 0x22 0x00, as
1476	   that would then be treated as a UTF16 password rather than
1477	   a nthash */
1478	quoted_utf16			= ldb_msg_find_ldb_val(new_msg, "unicodePwd");
1479	if (quoted_utf16 &&
1480	    quoted_utf16->length >= 4 &&
1481	    quoted_utf16->data[0] == '"' &&
1482	    quoted_utf16->data[1] == 0 &&
1483	    quoted_utf16->data[quoted_utf16->length-2] == '"' &&
1484	    quoted_utf16->data[quoted_utf16->length-1] == 0) {
1485		io->n.quoted_utf16.data = talloc_memdup(io->ac, quoted_utf16->data+2, quoted_utf16->length-4);
1486		io->n.quoted_utf16.length = quoted_utf16->length-4;
1487		io->n.cleartext_utf16 = &io->n.quoted_utf16;
1488		io->n.nt_hash = NULL;
1489	} else {
1490		io->n.nt_hash		= samdb_result_hash(io->ac, new_msg, "unicodePwd");
1491	}
1492
1493	io->n.lm_hash			= samdb_result_hash(io->ac, new_msg, "dBCSPwd");
1494
1495	return LDB_SUCCESS;
1496}
1497
1498static struct ph_context *ph_init_context(struct ldb_module *module,
1499					  struct ldb_request *req)
1500{
1501	struct ldb_context *ldb;
1502	struct ph_context *ac;
1503
1504	ldb = ldb_module_get_ctx(module);
1505
1506	ac = talloc_zero(req, struct ph_context);
1507	if (ac == NULL) {
1508		ldb_set_errstring(ldb, "Out of Memory");
1509		return NULL;
1510	}
1511
1512	ac->module = module;
1513	ac->req = req;
1514
1515	return ac;
1516}
1517
1518static int ph_op_callback(struct ldb_request *req, struct ldb_reply *ares)
1519{
1520	struct ph_context *ac;
1521
1522	ac = talloc_get_type(req->context, struct ph_context);
1523
1524	if (!ares) {
1525		return ldb_module_done(ac->req, NULL, NULL,
1526					LDB_ERR_OPERATIONS_ERROR);
1527	}
1528	if (ares->error != LDB_SUCCESS) {
1529		return ldb_module_done(ac->req, ares->controls,
1530					ares->response, ares->error);
1531	}
1532
1533	if (ares->type != LDB_REPLY_DONE) {
1534		talloc_free(ares);
1535		return ldb_module_done(ac->req, NULL, NULL,
1536					LDB_ERR_OPERATIONS_ERROR);
1537	}
1538
1539	return ldb_module_done(ac->req, ares->controls,
1540				ares->response, ares->error);
1541}
1542
1543static int password_hash_add_do_add(struct ph_context *ac);
1544static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares);
1545static int password_hash_mod_search_self(struct ph_context *ac);
1546static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares);
1547static int password_hash_mod_do_mod(struct ph_context *ac);
1548
1549static int get_domain_data_callback(struct ldb_request *req,
1550				    struct ldb_reply *ares)
1551{
1552	struct ldb_context *ldb;
1553	struct domain_data *data;
1554	struct ph_context *ac;
1555	int ret;
1556	char *tmp;
1557	char *p;
1558
1559	ac = talloc_get_type(req->context, struct ph_context);
1560	ldb = ldb_module_get_ctx(ac->module);
1561
1562	if (!ares) {
1563		return ldb_module_done(ac->req, NULL, NULL,
1564					LDB_ERR_OPERATIONS_ERROR);
1565	}
1566	if (ares->error != LDB_SUCCESS) {
1567		return ldb_module_done(ac->req, ares->controls,
1568					ares->response, ares->error);
1569	}
1570
1571	switch (ares->type) {
1572	case LDB_REPLY_ENTRY:
1573		if (ac->domain != NULL) {
1574			ldb_set_errstring(ldb, "Too many results");
1575			return ldb_module_done(ac->req, NULL, NULL,
1576						LDB_ERR_OPERATIONS_ERROR);
1577		}
1578
1579		data = talloc_zero(ac, struct domain_data);
1580		if (data == NULL) {
1581			return ldb_module_done(ac->req, NULL, NULL,
1582						LDB_ERR_OPERATIONS_ERROR);
1583		}
1584
1585		data->pwdProperties = samdb_result_uint(ares->message, "pwdProperties", 0);
1586		data->store_cleartext = data->pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT;
1587		data->pwdHistoryLength = samdb_result_uint(ares->message, "pwdHistoryLength", 0);
1588
1589		/* For a domain DN, this puts things in dotted notation */
1590		/* For builtin domains, this will give details for the host,
1591		 * but that doesn't really matter, as it's just used for salt
1592		 * and kerberos principals, which don't exist here */
1593
1594		tmp = ldb_dn_canonical_string(data, ares->message->dn);
1595		if (!tmp) {
1596			return ldb_module_done(ac->req, NULL, NULL,
1597						LDB_ERR_OPERATIONS_ERROR);
1598		}
1599
1600		/* But it puts a trailing (or just before 'builtin') / on things, so kill that */
1601		p = strchr(tmp, '/');
1602		if (p) {
1603			p[0] = '\0';
1604		}
1605
1606		data->dns_domain = strlower_talloc(data, tmp);
1607		if (data->dns_domain == NULL) {
1608			ldb_oom(ldb);
1609			return ldb_module_done(ac->req, NULL, NULL,
1610						LDB_ERR_OPERATIONS_ERROR);
1611		}
1612		data->realm = strupper_talloc(data, tmp);
1613		if (data->realm == NULL) {
1614			ldb_oom(ldb);
1615			return ldb_module_done(ac->req, NULL, NULL,
1616						LDB_ERR_OPERATIONS_ERROR);
1617		}
1618		/* FIXME: NetbIOS name is *always* the first domain component ?? -SSS */
1619		p = strchr(tmp, '.');
1620		if (p) {
1621			p[0] = '\0';
1622		}
1623		data->netbios_domain = strupper_talloc(data, tmp);
1624		if (data->netbios_domain == NULL) {
1625			ldb_oom(ldb);
1626			return ldb_module_done(ac->req, NULL, NULL,
1627						LDB_ERR_OPERATIONS_ERROR);
1628		}
1629
1630		talloc_free(tmp);
1631		ac->domain = data;
1632		break;
1633
1634	case LDB_REPLY_DONE:
1635
1636		/* call the next step */
1637		switch (ac->req->operation) {
1638		case LDB_ADD:
1639			ret = password_hash_add_do_add(ac);
1640			break;
1641
1642		case LDB_MODIFY:
1643			ret = password_hash_mod_do_mod(ac);
1644			break;
1645
1646		default:
1647			ret = LDB_ERR_OPERATIONS_ERROR;
1648			break;
1649		}
1650		if (ret != LDB_SUCCESS) {
1651			return ldb_module_done(ac->req, NULL, NULL, ret);
1652		}
1653		break;
1654
1655	case LDB_REPLY_REFERRAL:
1656		/* ignore */
1657		break;
1658	}
1659
1660	talloc_free(ares);
1661	return LDB_SUCCESS;
1662}
1663
1664static int build_domain_data_request(struct ph_context *ac)
1665{
1666	/* attrs[] is returned from this function in
1667	   ac->dom_req->op.search.attrs, so it must be static, as
1668	   otherwise the compiler can put it on the stack */
1669	struct ldb_context *ldb;
1670	static const char * const attrs[] = { "pwdProperties", "pwdHistoryLength", NULL };
1671	char *filter;
1672
1673	ldb = ldb_module_get_ctx(ac->module);
1674
1675	filter = talloc_asprintf(ac,
1676				"(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
1677				 ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
1678	if (filter == NULL) {
1679		ldb_oom(ldb);
1680		return LDB_ERR_OPERATIONS_ERROR;
1681	}
1682
1683	return ldb_build_search_req(&ac->dom_req, ldb, ac,
1684				    ldb_get_default_basedn(ldb),
1685				    LDB_SCOPE_SUBTREE,
1686				    filter, attrs,
1687				    NULL,
1688				    ac, get_domain_data_callback,
1689				    ac->req);
1690}
1691
1692static int password_hash_add(struct ldb_module *module, struct ldb_request *req)
1693{
1694	struct ldb_context *ldb;
1695	struct ph_context *ac;
1696	struct ldb_message_element *sambaAttr;
1697	struct ldb_message_element *clearTextPasswordAttr;
1698	struct ldb_message_element *ntAttr;
1699	struct ldb_message_element *lmAttr;
1700	int ret;
1701
1702	ldb = ldb_module_get_ctx(module);
1703
1704	ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_add\n");
1705
1706	if (ldb_dn_is_special(req->op.add.message->dn)) { /* do not manipulate our control entries */
1707		return ldb_next_request(module, req);
1708	}
1709
1710	/* If the caller is manipulating the local passwords directly, let them pass */
1711	if (ldb_dn_compare_base(ldb_dn_new(req, ldb, LOCAL_BASE),
1712				req->op.add.message->dn) == 0) {
1713		return ldb_next_request(module, req);
1714	}
1715
1716	/* nobody must touch these fields */
1717	if (ldb_msg_find_element(req->op.add.message, "ntPwdHistory")) {
1718		return LDB_ERR_UNWILLING_TO_PERFORM;
1719	}
1720	if (ldb_msg_find_element(req->op.add.message, "lmPwdHistory")) {
1721		return LDB_ERR_UNWILLING_TO_PERFORM;
1722	}
1723	if (ldb_msg_find_element(req->op.add.message, "supplementalCredentials")) {
1724		return LDB_ERR_UNWILLING_TO_PERFORM;
1725	}
1726
1727	/* If no part of this ADD touches the userPassword, or the NT
1728	 * or LM hashes, then we don't need to make any changes.  */
1729
1730	sambaAttr = ldb_msg_find_element(req->op.mod.message, "userPassword");
1731	clearTextPasswordAttr = ldb_msg_find_element(req->op.mod.message, "clearTextPassword");
1732	ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd");
1733	lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd");
1734
1735	if ((!sambaAttr) && (!clearTextPasswordAttr) && (!ntAttr) && (!lmAttr)) {
1736		return ldb_next_request(module, req);
1737	}
1738
1739	/* if it is not an entry of type person its an error */
1740	/* TODO: remove this when userPassword will be in schema */
1741	if (!ldb_msg_check_string_attribute(req->op.add.message, "objectClass", "person")) {
1742		ldb_set_errstring(ldb, "Cannot set a password on entry that does not have objectClass 'person'");
1743		return LDB_ERR_OBJECT_CLASS_VIOLATION;
1744	}
1745
1746	/* check userPassword is single valued here */
1747	/* TODO: remove this when userPassword will be single valued in schema */
1748	if (sambaAttr && sambaAttr->num_values > 1) {
1749		ldb_set_errstring(ldb, "mupltiple values for userPassword not allowed!\n");
1750		return LDB_ERR_CONSTRAINT_VIOLATION;
1751	}
1752	if (clearTextPasswordAttr && clearTextPasswordAttr->num_values > 1) {
1753		ldb_set_errstring(ldb, "mupltiple values for clearTextPassword not allowed!\n");
1754		return LDB_ERR_CONSTRAINT_VIOLATION;
1755	}
1756
1757	if (ntAttr && (ntAttr->num_values > 1)) {
1758		ldb_set_errstring(ldb, "mupltiple values for unicodePwd not allowed!\n");
1759		return LDB_ERR_CONSTRAINT_VIOLATION;
1760	}
1761	if (lmAttr && (lmAttr->num_values > 1)) {
1762		ldb_set_errstring(ldb, "mupltiple values for dBCSPwd not allowed!\n");
1763		return LDB_ERR_CONSTRAINT_VIOLATION;
1764	}
1765
1766	if (sambaAttr && sambaAttr->num_values == 0) {
1767		ldb_set_errstring(ldb, "userPassword must have a value!\n");
1768		return LDB_ERR_CONSTRAINT_VIOLATION;
1769	}
1770
1771	if (clearTextPasswordAttr && clearTextPasswordAttr->num_values == 0) {
1772		ldb_set_errstring(ldb, "clearTextPassword must have a value!\n");
1773		return LDB_ERR_CONSTRAINT_VIOLATION;
1774	}
1775
1776	if (ntAttr && (ntAttr->num_values == 0)) {
1777		ldb_set_errstring(ldb, "unicodePwd must have a value!\n");
1778		return LDB_ERR_CONSTRAINT_VIOLATION;
1779	}
1780	if (lmAttr && (lmAttr->num_values == 0)) {
1781		ldb_set_errstring(ldb, "dBCSPwd must have a value!\n");
1782		return LDB_ERR_CONSTRAINT_VIOLATION;
1783	}
1784
1785	ac = ph_init_context(module, req);
1786	if (ac == NULL) {
1787		return LDB_ERR_OPERATIONS_ERROR;
1788	}
1789
1790	/* get user domain data */
1791	ac->domain_sid = samdb_result_sid_prefix(ac, req->op.add.message, "objectSid");
1792	if (ac->domain_sid == NULL) {
1793		ldb_debug(ldb, LDB_DEBUG_ERROR,
1794			  "can't handle entry with missing objectSid!\n");
1795		return LDB_ERR_OPERATIONS_ERROR;
1796	}
1797
1798	ret = build_domain_data_request(ac);
1799	if (ret != LDB_SUCCESS) {
1800		return ret;
1801	}
1802
1803	return ldb_next_request(module, ac->dom_req);
1804}
1805
1806static int password_hash_add_do_add(struct ph_context *ac)
1807{
1808	struct ldb_context *ldb;
1809	struct ldb_request *down_req;
1810	struct ldb_message *msg;
1811	struct setup_password_fields_io io;
1812	int ret;
1813
1814	/* Prepare the internal data structure containing the passwords */
1815	ret = setup_io(ac, ac->req->op.add.message, ac->req->op.add.message, &io);
1816	if (ret != LDB_SUCCESS) {
1817		return ret;
1818	}
1819
1820	msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
1821	if (msg == NULL) {
1822		return LDB_ERR_OPERATIONS_ERROR;
1823	}
1824
1825	/* remove attributes that we just read into 'io' */
1826	ldb_msg_remove_attr(msg, "userPassword");
1827	ldb_msg_remove_attr(msg, "clearTextPassword");
1828	ldb_msg_remove_attr(msg, "unicodePwd");
1829	ldb_msg_remove_attr(msg, "dBCSPwd");
1830	ldb_msg_remove_attr(msg, "pwdLastSet");
1831	io.o.kvno = samdb_result_uint(msg, "msDs-KeyVersionNumber", 1) - 1;
1832	ldb_msg_remove_attr(msg, "msDs-KeyVersionNumber");
1833
1834	ldb = ldb_module_get_ctx(ac->module);
1835
1836	ret = setup_password_fields(&io);
1837	if (ret != LDB_SUCCESS) {
1838		return ret;
1839	}
1840
1841	if (io.g.nt_hash) {
1842		ret = samdb_msg_add_hash(ldb, ac, msg,
1843					 "unicodePwd", io.g.nt_hash);
1844		if (ret != LDB_SUCCESS) {
1845			return ret;
1846		}
1847	}
1848	if (io.g.lm_hash) {
1849		ret = samdb_msg_add_hash(ldb, ac, msg,
1850					 "dBCSPwd", io.g.lm_hash);
1851		if (ret != LDB_SUCCESS) {
1852			return ret;
1853		}
1854	}
1855	if (io.g.nt_history_len > 0) {
1856		ret = samdb_msg_add_hashes(ac, msg,
1857					   "ntPwdHistory",
1858					   io.g.nt_history,
1859					   io.g.nt_history_len);
1860		if (ret != LDB_SUCCESS) {
1861			return ret;
1862		}
1863	}
1864	if (io.g.lm_history_len > 0) {
1865		ret = samdb_msg_add_hashes(ac, msg,
1866					   "lmPwdHistory",
1867					   io.g.lm_history,
1868					   io.g.lm_history_len);
1869		if (ret != LDB_SUCCESS) {
1870			return ret;
1871		}
1872	}
1873	if (io.g.supplemental.length > 0) {
1874		ret = ldb_msg_add_value(msg, "supplementalCredentials",
1875					&io.g.supplemental, NULL);
1876		if (ret != LDB_SUCCESS) {
1877			return ret;
1878		}
1879	}
1880	ret = samdb_msg_add_uint64(ldb, ac, msg,
1881				   "pwdLastSet",
1882				   io.g.last_set);
1883	if (ret != LDB_SUCCESS) {
1884		return ret;
1885	}
1886	ret = samdb_msg_add_uint(ldb, ac, msg,
1887				 "msDs-KeyVersionNumber",
1888				 io.g.kvno);
1889	if (ret != LDB_SUCCESS) {
1890		return ret;
1891	}
1892
1893	ret = ldb_build_add_req(&down_req, ldb, ac,
1894				msg,
1895				ac->req->controls,
1896				ac, ph_op_callback,
1897				ac->req);
1898	if (ret != LDB_SUCCESS) {
1899		return ret;
1900	}
1901
1902	return ldb_next_request(ac->module, down_req);
1903}
1904
1905static int password_hash_modify(struct ldb_module *module, struct ldb_request *req)
1906{
1907	struct ldb_context *ldb;
1908	struct ph_context *ac;
1909	struct ldb_message_element *sambaAttr;
1910	struct ldb_message_element *clearTextAttr;
1911	struct ldb_message_element *ntAttr;
1912	struct ldb_message_element *lmAttr;
1913	struct ldb_message *msg;
1914	struct ldb_request *down_req;
1915	int ret;
1916
1917	ldb = ldb_module_get_ctx(module);
1918
1919	ldb_debug(ldb, LDB_DEBUG_TRACE, "password_hash_modify\n");
1920
1921	if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */
1922		return ldb_next_request(module, req);
1923	}
1924
1925	/* If the caller is manipulating the local passwords directly, let them pass */
1926	if (ldb_dn_compare_base(ldb_dn_new(req, ldb, LOCAL_BASE),
1927				req->op.mod.message->dn) == 0) {
1928		return ldb_next_request(module, req);
1929	}
1930
1931	/* nobody must touch password Histories */
1932	if (ldb_msg_find_element(req->op.add.message, "ntPwdHistory")) {
1933		return LDB_ERR_UNWILLING_TO_PERFORM;
1934	}
1935	if (ldb_msg_find_element(req->op.add.message, "lmPwdHistory")) {
1936		return LDB_ERR_UNWILLING_TO_PERFORM;
1937	}
1938	if (ldb_msg_find_element(req->op.add.message, "supplementalCredentials")) {
1939		return LDB_ERR_UNWILLING_TO_PERFORM;
1940	}
1941
1942	sambaAttr = ldb_msg_find_element(req->op.mod.message, "userPassword");
1943	clearTextAttr = ldb_msg_find_element(req->op.mod.message, "clearTextPassword");
1944	ntAttr = ldb_msg_find_element(req->op.mod.message, "unicodePwd");
1945	lmAttr = ldb_msg_find_element(req->op.mod.message, "dBCSPwd");
1946
1947	/* If no part of this touches the userPassword OR
1948	 * clearTextPassword OR unicodePwd and/or dBCSPwd, then we
1949	 * don't need to make any changes.  For password changes/set
1950	 * there should be a 'delete' or a 'modify' on this
1951	 * attribute. */
1952	if ((!sambaAttr) && (!clearTextAttr) && (!ntAttr) && (!lmAttr)) {
1953		return ldb_next_request(module, req);
1954	}
1955
1956	/* check passwords are single valued here */
1957	/* TODO: remove this when passwords will be single valued in schema */
1958	if (sambaAttr && (sambaAttr->num_values > 1)) {
1959		DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1960		return LDB_ERR_CONSTRAINT_VIOLATION;
1961	}
1962	if (clearTextAttr && (clearTextAttr->num_values > 1)) {
1963		DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1964		return LDB_ERR_CONSTRAINT_VIOLATION;
1965	}
1966	if (ntAttr && (ntAttr->num_values > 1)) {
1967		DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1968		return LDB_ERR_CONSTRAINT_VIOLATION;
1969	}
1970	if (lmAttr && (lmAttr->num_values > 1)) {
1971		DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1972		return LDB_ERR_CONSTRAINT_VIOLATION;
1973	}
1974
1975	ac = ph_init_context(module, req);
1976	if (!ac) {
1977		DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
1978		return LDB_ERR_OPERATIONS_ERROR;
1979	}
1980
1981	/* use a new message structure so that we can modify it */
1982	msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
1983	if (msg == NULL) {
1984		ldb_oom(ldb);
1985		return LDB_ERR_OPERATIONS_ERROR;
1986	}
1987
1988	/* - remove any modification to the password from the first commit
1989	 *   we will make the real modification later */
1990	if (sambaAttr) ldb_msg_remove_attr(msg, "userPassword");
1991	if (clearTextAttr) ldb_msg_remove_attr(msg, "clearTextPassword");
1992	if (ntAttr) ldb_msg_remove_attr(msg, "unicodePwd");
1993	if (lmAttr) ldb_msg_remove_attr(msg, "dBCSPwd");
1994
1995	/* if there was nothing else to be modified skip to next step */
1996	if (msg->num_elements == 0) {
1997		return password_hash_mod_search_self(ac);
1998	}
1999
2000	ret = ldb_build_mod_req(&down_req, ldb, ac,
2001				msg,
2002				req->controls,
2003				ac, ph_modify_callback,
2004				req);
2005	if (ret != LDB_SUCCESS) {
2006		return ret;
2007	}
2008
2009	return ldb_next_request(module, down_req);
2010}
2011
2012static int ph_modify_callback(struct ldb_request *req, struct ldb_reply *ares)
2013{
2014	struct ph_context *ac;
2015	int ret;
2016
2017	ac = talloc_get_type(req->context, struct ph_context);
2018
2019	if (!ares) {
2020		return ldb_module_done(ac->req, NULL, NULL,
2021					LDB_ERR_OPERATIONS_ERROR);
2022	}
2023	if (ares->error != LDB_SUCCESS) {
2024		return ldb_module_done(ac->req, ares->controls,
2025					ares->response, ares->error);
2026	}
2027
2028	if (ares->type != LDB_REPLY_DONE) {
2029		talloc_free(ares);
2030		return ldb_module_done(ac->req, NULL, NULL,
2031					LDB_ERR_OPERATIONS_ERROR);
2032	}
2033
2034	ret = password_hash_mod_search_self(ac);
2035	if (ret != LDB_SUCCESS) {
2036		return ldb_module_done(ac->req, NULL, NULL, ret);
2037	}
2038
2039	talloc_free(ares);
2040	return LDB_SUCCESS;
2041}
2042
2043static int ph_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
2044{
2045	struct ldb_context *ldb;
2046	struct ph_context *ac;
2047	int ret;
2048
2049	ac = talloc_get_type(req->context, struct ph_context);
2050	ldb = ldb_module_get_ctx(ac->module);
2051
2052	if (!ares) {
2053		return ldb_module_done(ac->req, NULL, NULL,
2054					LDB_ERR_OPERATIONS_ERROR);
2055	}
2056	if (ares->error != LDB_SUCCESS) {
2057		return ldb_module_done(ac->req, ares->controls,
2058					ares->response, ares->error);
2059	}
2060
2061	/* we are interested only in the single reply (base search) */
2062	switch (ares->type) {
2063	case LDB_REPLY_ENTRY:
2064
2065		if (ac->search_res != NULL) {
2066			ldb_set_errstring(ldb, "Too many results");
2067			talloc_free(ares);
2068			return ldb_module_done(ac->req, NULL, NULL,
2069						LDB_ERR_OPERATIONS_ERROR);
2070		}
2071
2072		/* if it is not an entry of type person this is an error */
2073		/* TODO: remove this when sambaPassword will be in schema */
2074		if (!ldb_msg_check_string_attribute(ares->message, "objectClass", "person")) {
2075			ldb_set_errstring(ldb, "Object class violation");
2076			talloc_free(ares);
2077			return ldb_module_done(ac->req, NULL, NULL,
2078					LDB_ERR_OBJECT_CLASS_VIOLATION);
2079		}
2080
2081		ac->search_res = talloc_steal(ac, ares);
2082		return LDB_SUCCESS;
2083
2084	case LDB_REPLY_DONE:
2085
2086		/* get object domain sid */
2087		ac->domain_sid = samdb_result_sid_prefix(ac,
2088							ac->search_res->message,
2089							"objectSid");
2090		if (ac->domain_sid == NULL) {
2091			ldb_debug(ldb, LDB_DEBUG_ERROR,
2092				  "can't handle entry without objectSid!\n");
2093			return ldb_module_done(ac->req, NULL, NULL,
2094						LDB_ERR_OPERATIONS_ERROR);
2095		}
2096
2097		/* get user domain data */
2098		ret = build_domain_data_request(ac);
2099		if (ret != LDB_SUCCESS) {
2100			return ldb_module_done(ac->req, NULL, NULL,ret);
2101		}
2102
2103		return ldb_next_request(ac->module, ac->dom_req);
2104
2105	case LDB_REPLY_REFERRAL:
2106		/*ignore anything else for now */
2107		break;
2108	}
2109
2110	talloc_free(ares);
2111	return LDB_SUCCESS;
2112}
2113
2114static int password_hash_mod_search_self(struct ph_context *ac)
2115{
2116	struct ldb_context *ldb;
2117	static const char * const attrs[] = { "userAccountControl", "lmPwdHistory",
2118					      "ntPwdHistory",
2119					      "objectSid", "msDS-KeyVersionNumber",
2120					      "objectClass", "userPrincipalName",
2121					      "sAMAccountName",
2122					      "dBCSPwd", "unicodePwd",
2123					      "supplementalCredentials",
2124					      NULL };
2125	struct ldb_request *search_req;
2126	int ret;
2127
2128	ldb = ldb_module_get_ctx(ac->module);
2129
2130	ret = ldb_build_search_req(&search_req, ldb, ac,
2131				   ac->req->op.mod.message->dn,
2132				   LDB_SCOPE_BASE,
2133				   "(objectclass=*)",
2134				   attrs,
2135				   NULL,
2136				   ac, ph_mod_search_callback,
2137				   ac->req);
2138
2139	if (ret != LDB_SUCCESS) {
2140		return ret;
2141	}
2142
2143	return ldb_next_request(ac->module, search_req);
2144}
2145
2146static int password_hash_mod_do_mod(struct ph_context *ac)
2147{
2148	struct ldb_context *ldb;
2149	struct ldb_request *mod_req;
2150	struct ldb_message *msg;
2151	const struct ldb_message *searched_msg;
2152	struct setup_password_fields_io io;
2153	int ret;
2154
2155	ldb = ldb_module_get_ctx(ac->module);
2156
2157	/* use a new message structure so that we can modify it */
2158	msg = ldb_msg_new(ac);
2159	if (msg == NULL) {
2160		return LDB_ERR_OPERATIONS_ERROR;
2161	}
2162
2163	/* modify dn */
2164	msg->dn = ac->req->op.mod.message->dn;
2165
2166	/* Prepare the internal data structure containing the passwords */
2167	ret = setup_io(ac,
2168		       ac->req->op.mod.message,
2169		       ac->search_res->message,
2170		       &io);
2171	if (ret != LDB_SUCCESS) {
2172		return ret;
2173	}
2174
2175	searched_msg = ac->search_res->message;
2176
2177	/* Fill in some final details (only relevent once the password has been set) */
2178	io.o.kvno			= samdb_result_uint(searched_msg, "msDs-KeyVersionNumber", 0);
2179	io.o.nt_history_len		= samdb_result_hashes(io.ac, searched_msg, "ntPwdHistory", &io.o.nt_history);
2180	io.o.lm_history_len		= samdb_result_hashes(io.ac, searched_msg, "lmPwdHistory", &io.o.lm_history);
2181	io.o.supplemental		= ldb_msg_find_ldb_val(searched_msg, "supplementalCredentials");
2182
2183	ret = setup_password_fields(&io);
2184	if (ret != LDB_SUCCESS) {
2185		return ret;
2186	}
2187
2188	/* make sure we replace all the old attributes */
2189	ret = ldb_msg_add_empty(msg, "unicodePwd", LDB_FLAG_MOD_REPLACE, NULL);
2190	ret = ldb_msg_add_empty(msg, "dBCSPwd", LDB_FLAG_MOD_REPLACE, NULL);
2191	ret = ldb_msg_add_empty(msg, "ntPwdHistory", LDB_FLAG_MOD_REPLACE, NULL);
2192	ret = ldb_msg_add_empty(msg, "lmPwdHistory", LDB_FLAG_MOD_REPLACE, NULL);
2193	ret = ldb_msg_add_empty(msg, "supplementalCredentials", LDB_FLAG_MOD_REPLACE, NULL);
2194	ret = ldb_msg_add_empty(msg, "pwdLastSet", LDB_FLAG_MOD_REPLACE, NULL);
2195	ret = ldb_msg_add_empty(msg, "msDs-KeyVersionNumber", LDB_FLAG_MOD_REPLACE, NULL);
2196
2197	if (io.g.nt_hash) {
2198		ret = samdb_msg_add_hash(ldb, ac, msg,
2199					 "unicodePwd", io.g.nt_hash);
2200		if (ret != LDB_SUCCESS) {
2201			return ret;
2202		}
2203	}
2204	if (io.g.lm_hash) {
2205		ret = samdb_msg_add_hash(ldb, ac, msg,
2206					 "dBCSPwd", io.g.lm_hash);
2207		if (ret != LDB_SUCCESS) {
2208			return ret;
2209		}
2210	}
2211	if (io.g.nt_history_len > 0) {
2212		ret = samdb_msg_add_hashes(ac, msg,
2213					   "ntPwdHistory",
2214					   io.g.nt_history,
2215					   io.g.nt_history_len);
2216		if (ret != LDB_SUCCESS) {
2217			return ret;
2218		}
2219	}
2220	if (io.g.lm_history_len > 0) {
2221		ret = samdb_msg_add_hashes(ac, msg,
2222					   "lmPwdHistory",
2223					   io.g.lm_history,
2224					   io.g.lm_history_len);
2225		if (ret != LDB_SUCCESS) {
2226			return ret;
2227		}
2228	}
2229	if (io.g.supplemental.length > 0) {
2230		ret = ldb_msg_add_value(msg, "supplementalCredentials",
2231					&io.g.supplemental, NULL);
2232		if (ret != LDB_SUCCESS) {
2233			return ret;
2234		}
2235	}
2236	ret = samdb_msg_add_uint64(ldb, ac, msg,
2237				   "pwdLastSet",
2238				   io.g.last_set);
2239	if (ret != LDB_SUCCESS) {
2240		return ret;
2241	}
2242	ret = samdb_msg_add_uint(ldb, ac, msg,
2243				 "msDs-KeyVersionNumber",
2244				 io.g.kvno);
2245	if (ret != LDB_SUCCESS) {
2246		return ret;
2247	}
2248
2249	ret = ldb_build_mod_req(&mod_req, ldb, ac,
2250				msg,
2251				ac->req->controls,
2252				ac, ph_op_callback,
2253				ac->req);
2254	if (ret != LDB_SUCCESS) {
2255		return ret;
2256	}
2257
2258	return ldb_next_request(ac->module, mod_req);
2259}
2260
2261_PUBLIC_ const struct ldb_module_ops ldb_password_hash_module_ops = {
2262	.name          = "password_hash",
2263	.add           = password_hash_add,
2264	.modify        = password_hash_modify,
2265};
2266