Plans for pdb_ads and auth_netlogond?

Volker Lendecke Volker.Lendecke at SerNet.DE
Mon Jun 11 04:08:22 MDT 2012


Hi!

I don't think that I can give input that is deemed worth any
consideration on this matter.

Volker

On Mon, Jun 11, 2012 at 07:09:37PM +1000, Andrew Bartlett wrote:
> I'm wondering what your plans are for auth_netlogond and pdb_ads?
> 
> I'm trying to tidy up the tree as we move along with Samba 4.0 betas,
> and I thought it would be a good time to check what your plans are here.
> 
> These modules were vital building blocks for what we have with the
> merged 4.0, and I thank you for your time and effort in showing that a
> combined Samba 4.0 is indeed possible. 
> 
> Without these first steps, we would not have built the other components
> (in particular the named pipe forwarding) that form our release
> configuration of the Samba 4.0 AD DC.
> 
> However, as you know, we have built on these modules and gone further
> and as they don't operate as part of the official AD configuration they
> are not tested in in make test.  Indeed, there remains some significant
> issues - in particular the need for runtime ldapi:// support and not
> connecting to idmap.ldb for pdb_ads and local group and privileges
> lookup for auth_netlogond. 
> 
> If you don't have any plans for future development, I'm wondering if you
> would be OK with the attached patches to remove these from master?
> 
> Thanks,
> 
> Andrew Bartlett
> -- 
> Andrew Bartlett                                http://samba.org/~abartlet/
> Authentication Developer, Samba Team           http://samba.org

> >From a737c81f5f513bf81e7118372da8cfa26142b5bd Mon Sep 17 00:00:00 2001
> From: Andrew Bartlett <abartlet at samba.org>
> Date: Sun, 3 Jun 2012 10:54:06 +1000
> Subject: [PATCH 1/2] s3-passdb: Remove pdb_ads
> 
> pdb_ads was an important module in the development of the combined Samba 4.0, and
> was the first module to show that standard samba3 tools such as smbpasswd can be
> made to operate on the sam.ldb.
> 
> We now have pdb_samba4, which operates directly on the sam.ldb, rather than via
> ldapi://, which uses transactions and which is supported and tested as part
> of the official Samba 4.0 release configuration.
> 
> This module is not as complete (for example, it does not honour the idmap
> configuration) and requires that the samba binary be running to operate.
> 
> Andrew Bartlett
> ---
>  source3/Makefile.in          |    4 -
>  source3/configure.in         |    2 -
>  source3/passdb/pdb_ads.c     | 2693 ------------------------------------------
>  source3/passdb/wscript_build |    9 -
>  source3/wscript              |    2 +-
>  5 files changed, 1 insertions(+), 2709 deletions(-)
>  delete mode 100644 source3/passdb/pdb_ads.c
> 
> diff --git a/source3/Makefile.in b/source3/Makefile.in
> index 9271baa..fed485a 100644
> --- a/source3/Makefile.in
> +++ b/source3/Makefile.in
> @@ -2682,10 +2682,6 @@ bin/ldapsam. at SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_ldap.o passdb/pdb_nds.o \
>  	@$(SHLD_MODULE) passdb/pdb_ldap.o passdb/pdb_nds.o passdb/pdb_ipa.o \
>  			passdb/pdb_ldap_util.o $(LDAP_LIBS)
>  
> -bin/ads. at SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_ads.o
> -	@echo "Building plugin $@"
> -	@$(SHLD_MODULE) passdb/pdb_ads.o
> -
>  bin/tdbsam. at SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o
>  	@echo "Building plugin $@"
>  	@$(SHLD_MODULE) passdb/pdb_tdb.o
> diff --git a/source3/configure.in b/source3/configure.in
> index f2885d2..8e7af08 100644
> --- a/source3/configure.in
> +++ b/source3/configure.in
> @@ -468,7 +468,6 @@ default_shared_modules="$default_shared_modules vfs_time_audit"
>  default_shared_modules="$default_shared_modules idmap_autorid"
>  
>  if test "x$developer" = xyes; then
> -   default_static_modules="$default_static_modules rpc_rpcecho pdb_ads"
>     default_static_modules="$default_static_modules auth_netlogond"
>     default_shared_modules="$default_shared_modules perfcount_test"
>  fi
> @@ -6341,7 +6340,6 @@ fi
>  SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o passdb/pdb_ipa.o passdb/pdb_ldap_util.o,
>  		   "bin/ldapsam.$SHLIBEXT", PDB,
>  		   [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] )
> -SMB_MODULE(pdb_ads, passdb/pdb_ads.o \$(TLDAP_OBJ), "bin/ads.$SHLIBEXT", PDB)
>  SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB)
>  SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
>  SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB)
> diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c
> deleted file mode 100644
> index df9b7b3..0000000
> --- a/source3/passdb/pdb_ads.c
> +++ /dev/null
> @@ -1,2693 +0,0 @@
> -/*
> -   Unix SMB/CIFS implementation.
> -   pdb_ldap with ads schema
> -   Copyright (C) Volker Lendecke 2009
> -
> -   This program is free software; you can redistribute it and/or modify
> -   it under the terms of the GNU General Public License as published by
> -   the Free Software Foundation; either version 3 of the License, or
> -   (at your option) any later version.
> -
> -   This program is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> -   GNU General Public License for more details.
> -
> -   You should have received a copy of the GNU General Public License
> -   along with this program.  If not, see <http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "includes.h"
> -#include "passdb.h"
> -#include "tldap.h"
> -#include "tldap_util.h"
> -#include "../libds/common/flags.h"
> -#include "secrets.h"
> -#include "../librpc/gen_ndr/samr.h"
> -#include "../librpc/gen_ndr/idmap.h"
> -#include "../libcli/ldap/ldap_ndr.h"
> -#include "../libcli/security/security.h"
> -#include "../libds/common/flag_mapping.h"
> -
> -struct pdb_ads_state {
> -	struct sockaddr_un socket_address;
> -	struct tldap_context *ld;
> -	struct dom_sid domainsid;
> -	struct GUID domainguid;
> -	char *domaindn;
> -	char *configdn;
> -	char *netbiosname;
> -};
> -
> -struct pdb_ads_samu_private {
> -	char *dn;
> -	struct tldap_message *ldapmsg;
> -};
> -
> -static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
> -			       struct dom_sid *sid);
> -static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
> -			       struct dom_sid *psid);
> -static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
> -			       const struct dom_sid *sid,
> -			       TALLOC_CTX *mem_ctx, char **pdn);
> -static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state);
> -static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
> -			      int scope, const char *attrs[], int num_attrs,
> -			      int attrsonly,
> -			      TALLOC_CTX *mem_ctx, struct tldap_message ***res,
> -			      const char *fmt, ...);
> -static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
> -				    const char *filter,
> -				    TALLOC_CTX *mem_ctx,
> -				    struct pdb_ads_samu_private **presult);
> -
> -static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr,
> -			      time_t *ptime)
> -{
> -	uint64_t tmp;
> -
> -	if (!tldap_pull_uint64(msg, attr, &tmp)) {
> -		return false;
> -	}
> -	*ptime = nt_time_to_unix(tmp);
> -	return true;
> -}
> -
> -static gid_t pdb_ads_sid2gid(const struct dom_sid *sid)
> -{
> -	uint32_t rid;
> -	sid_peek_rid(sid, &rid);
> -	return rid;
> -}
> -
> -static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn)
> -{
> -	char *result, *p;
> -
> -	result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false,
> -				    true);
> -	if (result == NULL) {
> -		return NULL;
> -	}
> -
> -	while ((p = strchr_m(result, ',')) != NULL) {
> -		*p = '.';
> -	}
> -
> -	return result;
> -}
> -
> -static struct pdb_domain_info *pdb_ads_get_domain_info(
> -	struct pdb_methods *m, TALLOC_CTX *mem_ctx)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct pdb_domain_info *info;
> -	struct tldap_message *rootdse;
> -	char *tmp;
> -
> -	info = talloc(mem_ctx, struct pdb_domain_info);
> -	if (info == NULL) {
> -		return NULL;
> -	}
> -	info->name = talloc_strdup(info, state->netbiosname);
> -	if (info->name == NULL) {
> -		goto fail;
> -	}
> -	info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn);
> -	if (info->dns_domain == NULL) {
> -		goto fail;
> -	}
> -
> -	rootdse = tldap_rootdse(state->ld);
> -	tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext",
> -					    talloc_tos());
> -	if (tmp == NULL) {
> -		goto fail;
> -	}
> -	info->dns_forest = pdb_ads_domaindn2dns(info, tmp);
> -	TALLOC_FREE(tmp);
> -	if (info->dns_forest == NULL) {
> -		goto fail;
> -	}
> -	info->sid = state->domainsid;
> -	info->guid = state->domainguid;
> -	return info;
> -
> -fail:
> -	TALLOC_FREE(info);
> -	return NULL;
> -}
> -
> -static struct pdb_ads_samu_private *pdb_ads_get_samu_private(
> -	struct pdb_methods *m, struct samu *sam)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct pdb_ads_samu_private *result;
> -	char *sidstr, *filter;
> -	NTSTATUS status;
> -
> -	result = (struct pdb_ads_samu_private *)
> -		pdb_get_backend_private_data(sam, m);
> -
> -	if (result != NULL) {
> -		return talloc_get_type_abort(
> -			result, struct pdb_ads_samu_private);
> -	}
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), pdb_get_user_sid(sam));
> -	if (sidstr == NULL) {
> -		return NULL;
> -	}
> -
> -	filter = talloc_asprintf(
> -		talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
> -	TALLOC_FREE(sidstr);
> -	if (filter == NULL) {
> -		return NULL;
> -	}
> -
> -	status = pdb_ads_getsamupriv(state, filter, sam, &result);
> -	TALLOC_FREE(filter);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		return NULL;
> -	}
> -
> -	return result;
> -}
> -
> -static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
> -					   struct samu *sam,
> -					   struct pdb_ads_samu_private *priv)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	struct tldap_message *entry = priv->ldapmsg;
> -	char *str;
> -	time_t tmp_time;
> -	struct dom_sid sid;
> -	uint64_t n;
> -	uint32_t i;
> -	DATA_BLOB blob;
> -
> -	str = tldap_talloc_single_attribute(entry, "samAccountName", sam);
> -	if (str == NULL) {
> -		DEBUG(10, ("no samAccountName\n"));
> -		goto fail;
> -	}
> -	pdb_set_username(sam, str, PDB_SET);
> -
> -	if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) {
> -		pdb_set_logon_time(sam, tmp_time, PDB_SET);
> -	}
> -	if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) {
> -		pdb_set_logoff_time(sam, tmp_time, PDB_SET);
> -	}
> -	if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) {
> -		pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
> -	}
> -	if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
> -		pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "displayName",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_fullname(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "homeDirectory",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_homedir(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_dir_drive(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_logon_script(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "profilePath",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_profile_path(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "profilePath",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_profile_path(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "comment",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_comment(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "description",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_acct_desc(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "userWorkstations",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_workstations(sam, str, PDB_SET);
> -	}
> -
> -	str = tldap_talloc_single_attribute(entry, "userParameters",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		pdb_set_munged_dial(sam, str, PDB_SET);
> -	}
> -
> -	if (!tldap_pull_binsid(entry, "objectSid", &sid)) {
> -		DEBUG(10, ("Could not pull SID\n"));
> -		goto fail;
> -	}
> -	pdb_set_user_sid(sam, &sid, PDB_SET);
> -
> -	if (!tldap_pull_uint64(entry, "userAccountControl", &n)) {
> -		DEBUG(10, ("Could not pull userAccountControl\n"));
> -		goto fail;
> -	}
> -	pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
> -
> -	if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
> -		if (blob.length != NT_HASH_LEN) {
> -			DEBUG(0, ("Got NT hash of length %d, expected %d\n",
> -				  (int)blob.length, NT_HASH_LEN));
> -			goto fail;
> -		}
> -		pdb_set_nt_passwd(sam, blob.data, PDB_SET);
> -	}
> -
> -	if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) {
> -		if (blob.length != LM_HASH_LEN) {
> -			DEBUG(0, ("Got LM hash of length %d, expected %d\n",
> -				  (int)blob.length, LM_HASH_LEN));
> -			goto fail;
> -		}
> -		pdb_set_lanman_passwd(sam, blob.data, PDB_SET);
> -	}
> -
> -	if (tldap_pull_uint64(entry, "primaryGroupID", &n)) {
> -		sid_compose(&sid, &state->domainsid, n);
> -		pdb_set_group_sid(sam, &sid, PDB_SET);
> -
> -	}
> -
> -	if (tldap_pull_uint32(entry, "countryCode", &i)) {
> -		pdb_set_country_code(sam, i, PDB_SET);
> -	}
> -
> -	if (tldap_pull_uint32(entry, "codePage", &i)) {
> -		pdb_set_code_page(sam, i, PDB_SET);
> -	}
> -
> -	if (tldap_get_single_valueblob(entry, "logonHours", &blob)) {
> -
> -		if (blob.length > MAX_HOURS_LEN) {
> -			status = NT_STATUS_INVALID_PARAMETER;
> -			goto fail;
> -		}
> -		pdb_set_logon_divs(sam, blob.length * 8, PDB_SET);
> -		pdb_set_hours_len(sam, blob.length, PDB_SET);
> -		pdb_set_hours(sam, blob.data, blob.length, PDB_SET);
> -
> -	} else {
> -		uint8_t hours[21];
> -		pdb_set_logon_divs(sam, sizeof(hours)/8, PDB_SET);
> -		pdb_set_hours_len(sam, sizeof(hours), PDB_SET);
> -		memset(hours, 0xff, sizeof(hours));
> -		pdb_set_hours(sam, hours, sizeof(hours), PDB_SET);
> -	}
> -
> -	status = NT_STATUS_OK;
> -fail:
> -	TALLOC_FREE(frame);
> -	return status;
> -}
> -
> -static bool pdb_ads_make_time_mod(struct tldap_message *existing,
> -				  TALLOC_CTX *mem_ctx,
> -				  struct tldap_mod **pmods, int *pnum_mods,
> -				  const char *attrib, time_t t)
> -{
> -	uint64_t nt_time;
> -
> -	unix_to_nt_time(&nt_time, t);
> -
> -	return tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, attrib,
> -		"%llu", nt_time);
> -}
> -
> -static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
> -				      struct tldap_message *existing,
> -				      TALLOC_CTX *mem_ctx,
> -				      struct tldap_mod **pmods, int *pnum_mods,
> -				      struct samu *sam)
> -{
> -	bool ret = true;
> -	DATA_BLOB blob;
> -	const char *pw;
> -
> -	/* TODO: All fields :-) */
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "displayName",
> -		"%s", pdb_get_fullname(sam));
> -
> -	pw = pdb_get_plaintext_passwd(sam);
> -
> -	/*
> -	 * If we have the plain text pw, this is probably about to be
> -	 * set. Is this true always?
> -	 */
> -	if (pw != NULL) {
> -		char *pw_quote;
> -		uint8_t *pw_utf16;
> -		size_t pw_utf16_len;
> -
> -		pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw);
> -		if (pw_quote == NULL) {
> -			ret = false;
> -			goto fail;
> -		}
> -
> -		ret &= convert_string_talloc(talloc_tos(),
> -					     CH_UNIX, CH_UTF16LE,
> -					     pw_quote, strlen(pw_quote),
> -					     &pw_utf16, &pw_utf16_len);
> -		if (!ret) {
> -			goto fail;
> -		}
> -		blob = data_blob_const(pw_utf16, pw_utf16_len);
> -
> -		ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods,
> -					   TLDAP_MOD_REPLACE,
> -					   "unicodePwd", &blob, 1);
> -		TALLOC_FREE(pw_utf16);
> -		TALLOC_FREE(pw_quote);
> -	}
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "userAccountControl",
> -		"%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "homeDirectory",
> -		"%s", pdb_get_homedir(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "homeDrive",
> -		"%s", pdb_get_dir_drive(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "scriptPath",
> -		"%s", pdb_get_logon_script(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "profilePath",
> -		"%s", pdb_get_profile_path(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "comment",
> -		"%s", pdb_get_comment(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "description",
> -		"%s", pdb_get_acct_desc(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "userWorkstations",
> -		"%s", pdb_get_workstations(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "userParameters",
> -		"%s", pdb_get_munged_dial(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "countryCode",
> -		"%i", (int)pdb_get_country_code(sam));
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, mem_ctx, pmods, pnum_mods, "codePage",
> -		"%i", (int)pdb_get_code_page(sam));
> -
> -	ret &= pdb_ads_make_time_mod(
> -		existing, mem_ctx, pmods, pnum_mods, "accountExpires",
> -		(int)pdb_get_kickoff_time(sam));
> -
> -	ret &= tldap_make_mod_blob(
> -		existing, mem_ctx, pmods, pnum_mods, "logonHours",
> -		data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam)));
> -
> -fail:
> -	return ret;
> -}
> -
> -static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state,
> -				    const char *filter,
> -				    TALLOC_CTX *mem_ctx,
> -				    struct pdb_ads_samu_private **presult)
> -{
> -	const char * attrs[] = {
> -		"lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
> -		"sAMAccountName", "displayName", "homeDirectory",
> -		"homeDrive", "scriptPath", "profilePath", "description",
> -		"userWorkstations", "comment", "userParameters", "objectSid",
> -		"primaryGroupID", "userAccountControl", "logonHours",
> -		"badPwdCount", "logonCount", "countryCode", "codePage",
> -		"unicodePwd", "dBCSPwd" };
> -	struct tldap_message **users;
> -	int rc, count;
> -	struct pdb_ads_samu_private *result;
> -
> -	result = talloc(mem_ctx, struct pdb_ads_samu_private);
> -	if (result == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, result,
> -				&users, "%s", filter);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		TALLOC_FREE(result);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	count = talloc_array_length(users);
> -	if (count != 1) {
> -		DEBUG(10, ("Expected 1 user, got %d\n", count));
> -		TALLOC_FREE(result);
> -		return NT_STATUS_NO_SUCH_USER;
> -	}
> -
> -	result->ldapmsg = users[0];
> -	if (!tldap_entry_dn(result->ldapmsg, &result->dn)) {
> -		DEBUG(10, ("Could not extract dn\n"));
> -		TALLOC_FREE(result);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	*presult = result;
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m,
> -				       struct pdb_ads_state *state,
> -				       struct samu *sam_acct,
> -				       const char *filter)
> -{
> -	struct pdb_ads_samu_private *priv;
> -	NTSTATUS status;
> -
> -	status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n",
> -			   nt_errstr(status)));
> -		return status;
> -	}
> -
> -	status = pdb_ads_init_sam_from_priv(m, sam_acct, priv);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n",
> -			   nt_errstr(status)));
> -		TALLOC_FREE(priv);
> -		return status;
> -	}
> -
> -	pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m,
> -				    struct samu *sam_acct,
> -				    const char *username)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	char *filter;
> -
> -	filter = talloc_asprintf(
> -		talloc_tos(), "(&(samaccountname=%s)(objectclass=user))",
> -		username);
> -	NT_STATUS_HAVE_NO_MEMORY(filter);
> -
> -	return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
> -}
> -
> -static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m,
> -				    struct samu *sam_acct,
> -				    const struct dom_sid *sid)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	char *sidstr, *filter;
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
> -	NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -	filter = talloc_asprintf(
> -		talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
> -	TALLOC_FREE(sidstr);
> -	NT_STATUS_HAVE_NO_MEMORY(filter);
> -
> -	return pdb_ads_getsampwfilter(m, state, sam_acct, filter);
> -}
> -
> -static NTSTATUS pdb_ads_create_user(struct pdb_methods *m,
> -				    TALLOC_CTX *tmp_ctx,
> -				    const char *name, uint32 acct_flags,
> -				    uint32 *rid)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	const char *attrs[1] = { "objectSid" };
> -	struct tldap_mod *mods = NULL;
> -	int num_mods = 0;
> -	struct tldap_message **user;
> -	struct dom_sid sid;
> -	char *dn;
> -	int rc;
> -	bool ok;
> -
> -	dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
> -			     state->domaindn);
> -	if (dn == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	/* TODO: Create machines etc */
> -
> -	ok = true;
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "objectClass", "user");
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
> -		name);
> -	if (!ok) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -
> -	rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_add failed %s\n",
> -			   tldap_errstr(talloc_tos(), ld, rc)));
> -		TALLOC_FREE(dn);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&user,
> -				"(&(objectclass=user)(samaccountname=%s))",
> -				name);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not find just created user %s: %s\n",
> -			   name, tldap_errstr(talloc_tos(), state->ld, rc)));
> -		TALLOC_FREE(dn);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	if (talloc_array_length(user) != 1) {
> -		DEBUG(10, ("Got %d users, expected one\n",
> -			   (int)talloc_array_length(user)));
> -		TALLOC_FREE(dn);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	if (!tldap_pull_binsid(user[0], "objectSid", &sid)) {
> -		DEBUG(10, ("Could not fetch objectSid from user %s\n",
> -			   name));
> -		TALLOC_FREE(dn);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	sid_peek_rid(&sid, rid);
> -	TALLOC_FREE(dn);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m,
> -				    TALLOC_CTX *tmp_ctx,
> -				    struct samu *sam)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	NTSTATUS status;
> -	struct tldap_context *ld;
> -	char *dn;
> -	int rc;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(),
> -				&dn);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		return status;
> -	}
> -
> -	rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
> -	TALLOC_FREE(dn);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_delete for %s failed: %s\n", dn,
> -			   tldap_errstr(talloc_tos(), ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m,
> -					struct samu *sampass)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m,
> -					   struct samu *sam)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam);
> -	struct tldap_context *ld;
> -	struct tldap_mod *mods = NULL;
> -	int rc, num_mods = 0;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(),
> -				       &mods, &num_mods, sam)) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	if (num_mods == 0) {
> -		/* Nothing to do, just return success */
> -		return NT_STATUS_OK;
> -	}
> -
> -	rc = tldap_modify(ld, priv->dn, mods, num_mods, NULL, 0,
> -			  NULL, 0);
> -	TALLOC_FREE(mods);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn,
> -			   tldap_errstr(talloc_tos(), ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m,
> -					   struct samu *username)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m,
> -					   struct samu *oldname,
> -					   const char *newname)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m,
> -					      struct samu *sam_acct,
> -					      bool success)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
> -				    const char *filter,
> -				    TALLOC_CTX *mem_ctx,
> -				    struct tldap_message **pmsg)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	const char *attrs[4] = { "objectSid", "description", "samAccountName",
> -				 "groupType" };
> -	char *str;
> -	struct tldap_message **group;
> -	uint32_t grouptype;
> -	int rc;
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&group, "%s", filter);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	if (talloc_array_length(group) != 1) {
> -		DEBUG(10, ("Expected 1 group, got %d\n",
> -			   (int)talloc_array_length(group)));
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) {
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -	map->gid = pdb_ads_sid2gid(&map->sid);
> -
> -	if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) {
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -	switch (grouptype) {
> -	case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
> -	case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
> -		map->sid_name_use = SID_NAME_ALIAS;
> -		break;
> -	case GTYPE_SECURITY_GLOBAL_GROUP:
> -		map->sid_name_use = SID_NAME_DOM_GRP;
> -		break;
> -	default:
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	str = tldap_talloc_single_attribute(group[0], "samAccountName",
> -					    talloc_tos());
> -	if (str == NULL) {
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -	map->nt_name = talloc_move(map, &str);
> -
> -	str = tldap_talloc_single_attribute(group[0], "description",
> -					    talloc_tos());
> -	if (str != NULL) {
> -		map->comment = talloc_move(map, &str);
> -	} else {
> -		map->comment = talloc_strdup(map, "");
> -	}
> -
> -	if (pmsg != NULL) {
> -		*pmsg = talloc_move(mem_ctx, &group[0]);
> -	}
> -	TALLOC_FREE(group);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
> -				 struct dom_sid sid)
> -{
> -	char *filter;
> -	NTSTATUS status;
> -
> -	filter = talloc_asprintf(talloc_tos(),
> -				 "(&(objectsid=%s)(objectclass=group))",
> -				 sid_string_talloc(talloc_tos(), &sid));
> -	if (filter == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
> -	TALLOC_FREE(filter);
> -	return status;
> -}
> -
> -static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
> -				 gid_t gid)
> -{
> -	struct dom_sid sid;
> -	pdb_ads_gid_to_sid(m, gid, &sid);
> -	return pdb_ads_getgrsid(m, map, sid);
> -}
> -
> -static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
> -				 const char *name)
> -{
> -	char *filter;
> -	NTSTATUS status;
> -
> -	filter = talloc_asprintf(talloc_tos(),
> -				 "(&(samaccountname=%s)(objectclass=group))",
> -				 name);
> -	if (filter == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	status = pdb_ads_getgrfilter(m, map, filter, NULL, NULL);
> -	TALLOC_FREE(filter);
> -	return status;
> -}
> -
> -static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m,
> -					 TALLOC_CTX *mem_ctx, const char *name,
> -					 uint32 *rid)
> -{
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	const char *attrs[1] = { "objectSid" };
> -	int num_mods = 0;
> -	struct tldap_mod *mods = NULL;
> -	struct tldap_message **alias;
> -	struct dom_sid sid;
> -	char *dn;
> -	int rc;
> -	bool ok = true;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
> -			     state->domaindn);
> -	if (dn == NULL) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
> -		name);
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "groupType",
> -		"%d", (int)GTYPE_SECURITY_GLOBAL_GROUP);
> -
> -	if (!ok) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_add failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	rc = pdb_ads_search_fmt(
> -		state, state->domaindn, TLDAP_SCOPE_SUB,
> -		attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
> -		"(&(objectclass=group)(samaccountname=%s))", name);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not find just created alias %s: %s\n",
> -			   name, tldap_errstr(talloc_tos(), state->ld, rc)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	if (talloc_array_length(alias) != 1) {
> -		DEBUG(10, ("Got %d alias, expected one\n",
> -			   (int)talloc_array_length(alias)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
> -		DEBUG(10, ("Could not fetch objectSid from alias %s\n",
> -			   name));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	sid_peek_rid(&sid, rid);
> -	TALLOC_FREE(frame);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m,
> -					 TALLOC_CTX *mem_ctx, uint32 rid)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	struct dom_sid sid;
> -	char *sidstr;
> -	struct tldap_message **msg;
> -	char *dn;
> -	int rc;
> -
> -	sid_compose(&sid, &state->domainsid, rid);
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
> -	NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				NULL, 0, 0, talloc_tos(), &msg,
> -				("(&(objectSid=%s)(objectClass=group))"),
> -				sidstr);
> -	TALLOC_FREE(sidstr);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	switch talloc_array_length(msg) {
> -	case 0:
> -		return NT_STATUS_NO_SUCH_GROUP;
> -	case 1:
> -		break;
> -	default:
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	if (!tldap_entry_dn(msg[0], &dn)) {
> -		TALLOC_FREE(msg);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		TALLOC_FREE(msg);
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
> -	TALLOC_FREE(msg);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_delete failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m,
> -						GROUP_MAP *map)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m,
> -						   GROUP_MAP *map)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	struct tldap_mod *mods = NULL;
> -	char *filter;
> -	struct tldap_message *existing;
> -	char *dn;
> -	GROUP_MAP *existing_map;
> -	int rc, num_mods = 0;
> -	bool ret;
> -	NTSTATUS status;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	filter = talloc_asprintf(talloc_tos(),
> -				 "(&(objectsid=%s)(objectclass=group))",
> -				 sid_string_talloc(talloc_tos(), &map->sid));
> -	if (filter == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	existing_map = talloc_zero(talloc_tos(), GROUP_MAP);
> -	if (!existing_map) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	status = pdb_ads_getgrfilter(m, existing_map, filter,
> -				     talloc_tos(), &existing);
> -	TALLOC_FREE(existing_map);
> -	TALLOC_FREE(filter);
> -
> -	if (!tldap_entry_dn(existing, &dn)) {
> -		return NT_STATUS_LDAP(TLDAP_DECODING_ERROR);
> -	}
> -
> -	ret = true;
> -
> -	ret &= tldap_make_mod_fmt(
> -		existing, talloc_tos(), &mods, &num_mods, "description",
> -		"%s", map->comment);
> -	ret &= tldap_make_mod_fmt(
> -		existing, talloc_tos(), &mods, &num_mods, "samaccountname",
> -		"%s", map->nt_name);
> -
> -	if (!ret) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	if (num_mods == 0) {
> -		TALLOC_FREE(existing);
> -		return NT_STATUS_OK;
> -	}
> -
> -	rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_modify for %s failed: %s\n", dn,
> -			   tldap_errstr(talloc_tos(), ld, rc)));
> -		TALLOC_FREE(existing);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	TALLOC_FREE(existing);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m,
> -						   struct dom_sid sid)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m,
> -					   const struct dom_sid *sid,
> -					   enum lsa_SidType sid_name_use,
> -					   GROUP_MAP ***pp_rmap,
> -					   size_t *p_num_entries,
> -					   bool unix_only)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m,
> -					   TALLOC_CTX *mem_ctx,
> -					   const struct dom_sid *group,
> -					   uint32 **pmembers,
> -					   size_t *pnum_members)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	const char *attrs[1] = { "member" };
> -	char *sidstr;
> -	struct tldap_message **msg;
> -	int i, rc, num_members;
> -	DATA_BLOB *blobs;
> -	uint32_t *members;
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), group);
> -	NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&msg, "(objectsid=%s)", sidstr);
> -	TALLOC_FREE(sidstr);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	switch talloc_array_length(msg) {
> -	case 0:
> -		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
> -		break;
> -	case 1:
> -		break;
> -	default:
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		break;
> -	}
> -
> -	if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
> -		*pmembers = NULL;
> -		*pnum_members = 0;
> -		return NT_STATUS_OK;
> -	}
> -
> -	members = talloc_array(mem_ctx, uint32_t, num_members);
> -	if (members == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	for (i=0; i<num_members; i++) {
> -		struct dom_sid sid;
> -		if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid)
> -		    || !sid_peek_rid(&sid, &members[i])) {
> -			TALLOC_FREE(members);
> -			return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		}
> -	}
> -
> -	*pmembers = members;
> -	*pnum_members = num_members;
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m,
> -					       TALLOC_CTX *mem_ctx,
> -					       struct samu *user,
> -					       struct dom_sid **pp_sids,
> -					       gid_t **pp_gids,
> -					       uint32_t *p_num_groups)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct pdb_ads_samu_private *priv;
> -	const char *attrs[1] = { "objectSid" };
> -	struct tldap_message **groups;
> -	int i, rc, count;
> -	size_t num_groups;
> -	struct dom_sid *group_sids;
> -	gid_t *gids;
> -
> -	priv = pdb_ads_get_samu_private(m, user);
> -	if (priv != NULL) {
> -		rc = pdb_ads_search_fmt(
> -			state, state->domaindn, TLDAP_SCOPE_SUB,
> -			attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups,
> -			"(&(member=%s)(grouptype=%d)(objectclass=group))",
> -			priv->dn, GTYPE_SECURITY_GLOBAL_GROUP);
> -		if (rc != TLDAP_SUCCESS) {
> -			DEBUG(10, ("ldap_search failed %s\n",
> -				   tldap_errstr(talloc_tos(), state->ld, rc)));
> -			return NT_STATUS_LDAP(rc);
> -		}
> -		count = talloc_array_length(groups);
> -	} else {
> -		/*
> -		 * This happens for artificial samu users
> -		 */
> -		DEBUG(10, ("Could not get pdb_ads_samu_private\n"));
> -		count = 0;
> -	}
> -
> -	group_sids = talloc_array(mem_ctx, struct dom_sid, count+1);
> -	if (group_sids == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	gids = talloc_array(mem_ctx, gid_t, count+1);
> -	if (gids == NULL) {
> -		TALLOC_FREE(group_sids);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	sid_copy(&group_sids[0], pdb_get_group_sid(user));
> -	if (!sid_to_gid(&group_sids[0], &gids[0])) {
> -		TALLOC_FREE(gids);
> -		TALLOC_FREE(group_sids);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -	num_groups = 1;
> -
> -	for (i=0; i<count; i++) {
> -		if (!tldap_pull_binsid(groups[i], "objectSid",
> -				       &group_sids[num_groups])) {
> -			continue;
> -		}
> -		gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]);
> -
> -		num_groups += 1;
> -		if (num_groups == count) {
> -			break;
> -		}
> -	}
> -
> -	*pp_sids = group_sids;
> -	*pp_gids = gids;
> -	*p_num_groups = num_groups;
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m,
> -					       TALLOC_CTX *mem_ctx,
> -					       struct samu *user)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m,
> -				     TALLOC_CTX *mem_ctx,
> -				     uint32 grouprid, uint32 memberrid,
> -				     int mod_op)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	struct tldap_context *ld;
> -	struct dom_sid groupsid, membersid;
> -	char *groupdn, *memberdn;
> -	struct tldap_mod *mods;
> -	int num_mods;
> -	int rc;
> -	NTSTATUS status;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	sid_compose(&groupsid, &state->domainsid, grouprid);
> -	sid_compose(&membersid, &state->domainsid, memberrid);
> -
> -	status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_SUCH_GROUP;
> -	}
> -	status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_SUCH_USER;
> -	}
> -
> -	mods = NULL;
> -	num_mods = 0;
> -
> -	if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
> -			       "member", memberdn)) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	rc = tldap_modify(ld, groupdn, mods, num_mods, NULL, 0, NULL, 0);
> -	TALLOC_FREE(frame);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_modify failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		if ((mod_op == TLDAP_MOD_ADD) &&
> -		    (rc == TLDAP_ALREADY_EXISTS)) {
> -			return NT_STATUS_MEMBER_IN_GROUP;
> -		}
> -		if ((mod_op == TLDAP_MOD_DELETE) &&
> -		    (rc == TLDAP_UNWILLING_TO_PERFORM)) {
> -			return NT_STATUS_MEMBER_NOT_IN_GROUP;
> -		}
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m,
> -				     TALLOC_CTX *mem_ctx,
> -				     uint32 group_rid, uint32 member_rid)
> -{
> -	return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
> -				    TLDAP_MOD_ADD);
> -}
> -
> -static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m,
> -				     TALLOC_CTX *mem_ctx,
> -				     uint32 group_rid, uint32 member_rid)
> -{
> -	return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid,
> -				    TLDAP_MOD_DELETE);
> -}
> -
> -static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m,
> -				     const char *name, uint32 *rid)
> -{
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	const char *attrs[1] = { "objectSid" };
> -	int num_mods = 0;
> -	struct tldap_mod *mods = NULL;
> -	struct tldap_message **alias;
> -	struct dom_sid sid;
> -	char *dn;
> -	int rc;
> -	bool ok = true;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name,
> -			     state->domaindn);
> -	if (dn == NULL) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s",
> -		name);
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group");
> -	ok &= tldap_make_mod_fmt(
> -		NULL, talloc_tos(), &mods, &num_mods, "groupType",
> -		"%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
> -
> -	if (!ok) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	rc = tldap_add(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_add failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	rc = pdb_ads_search_fmt(
> -		state, state->domaindn, TLDAP_SCOPE_SUB,
> -		attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias,
> -		"(&(objectclass=group)(samaccountname=%s))", name);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not find just created alias %s: %s\n",
> -			   name, tldap_errstr(talloc_tos(), state->ld, rc)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	if (talloc_array_length(alias) != 1) {
> -		DEBUG(10, ("Got %d alias, expected one\n",
> -			   (int)talloc_array_length(alias)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) {
> -		DEBUG(10, ("Could not fetch objectSid from alias %s\n",
> -			   name));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	sid_peek_rid(&sid, rid);
> -	TALLOC_FREE(frame);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m,
> -				     const struct dom_sid *sid)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	struct tldap_message **alias;
> -	char *sidstr, *dn = NULL;
> -	int rc;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
> -	if (sidstr == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				NULL, 0, 0, talloc_tos(), &alias,
> -				"(&(objectSid=%s)(objectclass=group)"
> -				"(|(grouptype=%d)(grouptype=%d)))",
> -				sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
> -				GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
> -	TALLOC_FREE(sidstr);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	if (talloc_array_length(alias) != 1) {
> -		DEBUG(10, ("Expected 1 alias, got %d\n",
> -			   (int)talloc_array_length(alias)));
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -	if (!tldap_entry_dn(alias[0], &dn)) {
> -		DEBUG(10, ("Could not get DN for alias %s\n",
> -			   sid_string_dbg(sid)));
> -		return NT_STATUS_INTERNAL_ERROR;
> -	}
> -
> -	rc = tldap_delete(ld, dn, NULL, 0, NULL, 0);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_delete failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m,
> -				      const struct dom_sid *sid,
> -				      struct acct_info *info)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	const char *attrs[3] = { "objectSid", "description",
> -				 "samAccountName" };
> -	struct tldap_message **msg;
> -	char *sidstr, *dn;
> -	int rc;
> -	struct tldap_mod *mods;
> -	int num_mods;
> -	bool ok;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
> -	NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&msg, "(&(objectSid=%s)(objectclass=group)"
> -				"(|(grouptype=%d)(grouptype=%d)))",
> -				sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
> -				GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
> -	TALLOC_FREE(sidstr);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	switch talloc_array_length(msg) {
> -	case 0:
> -		return NT_STATUS_NO_SUCH_ALIAS;
> -	case 1:
> -		break;
> -	default:
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	if (!tldap_entry_dn(msg[0], &dn)) {
> -		TALLOC_FREE(msg);
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	mods = NULL;
> -	num_mods = 0;
> -	ok = true;
> -
> -	ok &= tldap_make_mod_fmt(
> -		msg[0], msg, &mods, &num_mods, "description",
> -		"%s", info->acct_desc);
> -	ok &= tldap_make_mod_fmt(
> -		msg[0], msg, &mods, &num_mods, "samAccountName",
> -		"%s", info->acct_name);
> -	if (!ok) {
> -		TALLOC_FREE(msg);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	if (num_mods == 0) {
> -		/* no change */
> -		TALLOC_FREE(msg);
> -		return NT_STATUS_OK;
> -	}
> -
> -	rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0);
> -	TALLOC_FREE(msg);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_modify failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state,
> -			       const struct dom_sid *sid,
> -			       TALLOC_CTX *mem_ctx, char **pdn)
> -{
> -	struct tldap_message **msg;
> -	char *sidstr, *dn;
> -	int rc;
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid);
> -	NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				NULL, 0, 0, talloc_tos(), &msg,
> -				"(objectsid=%s)", sidstr);
> -	TALLOC_FREE(sidstr);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	switch talloc_array_length(msg) {
> -	case 0:
> -		return NT_STATUS_NOT_FOUND;
> -	case 1:
> -		break;
> -	default:
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	if (!tldap_entry_dn(msg[0], &dn)) {
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -	}
> -
> -	dn = talloc_strdup(mem_ctx, dn);
> -	if (dn == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	TALLOC_FREE(msg);
> -
> -	*pdn = dn;
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m,
> -				     const struct dom_sid *alias,
> -				     const struct dom_sid *member,
> -				     int mod_op)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct tldap_context *ld;
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	struct tldap_mod *mods;
> -	int num_mods;
> -	int rc;
> -	char *aliasdn, *memberdn;
> -	NTSTATUS status;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
> -	}
> -
> -	status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
> -			   sid_string_dbg(alias), nt_errstr(status)));
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_SUCH_ALIAS;
> -	}
> -	status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n",
> -			   sid_string_dbg(member), nt_errstr(status)));
> -		TALLOC_FREE(frame);
> -		return status;
> -	}
> -
> -	mods = NULL;
> -	num_mods = 0;
> -
> -	if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op,
> -			       "member", memberdn)) {
> -		TALLOC_FREE(frame);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	rc = tldap_modify(ld, aliasdn, mods, num_mods, NULL, 0, NULL, 0);
> -	TALLOC_FREE(frame);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_modify failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) {
> -			return NT_STATUS_MEMBER_IN_ALIAS;
> -		}
> -		if (rc == TLDAP_NO_SUCH_ATTRIBUTE) {
> -			return NT_STATUS_MEMBER_NOT_IN_ALIAS;
> -		}
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m,
> -				     const struct dom_sid *alias,
> -				     const struct dom_sid *member)
> -{
> -	return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD);
> -}
> -
> -static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m,
> -				     const struct dom_sid *alias,
> -				     const struct dom_sid *member)
> -{
> -	return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE);
> -}
> -
> -static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob,
> -			       struct dom_sid *psid)
> -{
> -	const char *attrs[1] = { "objectSid" };
> -	struct tldap_message **msg;
> -	char *dn;
> -	size_t len;
> -	int rc;
> -	bool ret;
> -
> -	if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX,
> -				   dnblob->data, dnblob->length, &dn, &len)) {
> -		return false;
> -	}
> -	rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&msg, "(objectclass=*)");
> -	TALLOC_FREE(dn);
> -	if (talloc_array_length(msg) != 1) {
> -		DEBUG(10, ("Got %d objects, expected one\n",
> -			   (int)talloc_array_length(msg)));
> -		TALLOC_FREE(msg);
> -		return false;
> -	}
> -
> -	ret = tldap_pull_binsid(msg[0], "objectSid", psid);
> -	TALLOC_FREE(msg);
> -	return ret;
> -}
> -
> -static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m,
> -				      const struct dom_sid *alias,
> -				      TALLOC_CTX *mem_ctx,
> -				      struct dom_sid **pmembers,
> -				      size_t *pnum_members)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	const char *attrs[1] = { "member" };
> -	char *sidstr;
> -	struct tldap_message **msg;
> -	int i, rc, num_members;
> -	DATA_BLOB *blobs;
> -	struct dom_sid *members;
> -
> -	sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), alias);
> -	NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&msg, "(objectsid=%s)", sidstr);
> -	TALLOC_FREE(sidstr);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -	switch talloc_array_length(msg) {
> -	case 0:
> -		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
> -		break;
> -	case 1:
> -		break;
> -	default:
> -		return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		break;
> -	}
> -
> -	if (!tldap_entry_values(msg[0], "member", &blobs, &num_members)) {
> -		*pmembers = NULL;
> -		*pnum_members = 0;
> -		return NT_STATUS_OK;
> -	}
> -
> -	members = talloc_array(mem_ctx, struct dom_sid, num_members);
> -	if (members == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	for (i=0; i<num_members; i++) {
> -		if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) {
> -			TALLOC_FREE(members);
> -			return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		}
> -	}
> -
> -	*pmembers = members;
> -	*pnum_members = num_members;
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m,
> -					       TALLOC_CTX *mem_ctx,
> -					       const struct dom_sid *domain_sid,
> -					       const struct dom_sid *members,
> -					       size_t num_members,
> -					       uint32_t **palias_rids,
> -					       size_t *pnum_alias_rids)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	const char *attrs[1] = { "objectSid" };
> -	struct tldap_message **msg = NULL;
> -	uint32_t *alias_rids = NULL;
> -	size_t num_alias_rids = 0;
> -	int i, rc, count;
> -	bool got_members = false;
> -	char *filter;
> -	NTSTATUS status;
> -
> -	/*
> -	 * TODO: Get the filter right so that we only get the aliases from
> -	 * either the SAM or BUILTIN
> -	 */
> -
> -	filter = talloc_asprintf(talloc_tos(),
> -				 "(&(|(grouptype=%d)(grouptype=%d))"
> -				 "(objectclass=group)(|",
> -				 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
> -				 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
> -	if (filter == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	for (i=0; i<num_members; i++) {
> -		char *dn;
> -
> -		status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn);
> -		if (!NT_STATUS_IS_OK(status)) {
> -			DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n",
> -				   sid_string_dbg(&members[i]),
> -				   nt_errstr(status)));
> -			continue;
> -		}
> -		filter = talloc_asprintf_append_buffer(
> -			filter, "(member=%s)", dn);
> -		TALLOC_FREE(dn);
> -		if (filter == NULL) {
> -			return NT_STATUS_NO_MEMORY;
> -		}
> -		got_members = true;
> -	}
> -
> -	if (!got_members) {
> -		goto done;
> -	}
> -
> -	rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
> -				attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
> -				&msg, "%s))", filter);
> -	TALLOC_FREE(filter);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("tldap_search failed %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return NT_STATUS_LDAP(rc);
> -	}
> -
> -	count = talloc_array_length(msg);
> -	if (count == 0) {
> -		goto done;
> -	}
> -
> -	alias_rids = talloc_array(mem_ctx, uint32_t, count);
> -	if (alias_rids == NULL) {
> -		TALLOC_FREE(msg);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	for (i=0; i<count; i++) {
> -		struct dom_sid sid;
> -
> -		if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) {
> -			DEBUG(10, ("Could not pull SID for member %d\n", i));
> -			continue;
> -		}
> -		if (sid_peek_check_rid(domain_sid, &sid,
> -				       &alias_rids[num_alias_rids])) {
> -			num_alias_rids += 1;
> -		}
> -	}
> -done:
> -	TALLOC_FREE(msg);
> -	*palias_rids = alias_rids;
> -	*pnum_alias_rids = 0;
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
> -				    const struct dom_sid *domain_sid,
> -				    int num_rids,
> -				    uint32 *rids,
> -				    const char **names,
> -				    enum lsa_SidType *lsa_attrs)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	const char *attrs[2] = { "sAMAccountType", "sAMAccountName" };
> -	int i, num_mapped;
> -
> -	if (num_rids == 0) {
> -		return NT_STATUS_NONE_MAPPED;
> -	}
> -
> -	num_mapped = 0;
> -
> -	for (i=0; i<num_rids; i++) {
> -		struct dom_sid sid;
> -		struct tldap_message **msg;
> -		char *sidstr;
> -		uint32_t attr;
> -		int rc;
> -
> -		lsa_attrs[i] = SID_NAME_UNKNOWN;
> -
> -		sid_compose(&sid, domain_sid, rids[i]);
> -
> -		sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), &sid);
> -		NT_STATUS_HAVE_NO_MEMORY(sidstr);
> -
> -		rc = pdb_ads_search_fmt(state, state->domaindn,
> -					TLDAP_SCOPE_SUB, attrs,
> -					ARRAY_SIZE(attrs), 0, talloc_tos(),
> -					&msg, "(objectsid=%s)", sidstr);
> -		TALLOC_FREE(sidstr);
> -		if (rc != TLDAP_SUCCESS) {
> -			DEBUG(10, ("ldap_search failed %s\n",
> -				   tldap_errstr(talloc_tos(), state->ld, rc)));
> -			continue;
> -		}
> -
> -		switch talloc_array_length(msg) {
> -		case 0:
> -			DEBUG(10, ("rid %d not found\n", (int)rids[i]));
> -			continue;
> -		case 1:
> -			break;
> -		default:
> -			return NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		}
> -
> -		names[i] = tldap_talloc_single_attribute(
> -			msg[0], "samAccountName", talloc_tos());
> -		if (names[i] == NULL) {
> -			DEBUG(10, ("no samAccountName\n"));
> -			continue;
> -		}
> -		if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) {
> -			DEBUG(10, ("no samAccountType"));
> -			continue;
> -		}
> -		lsa_attrs[i] = ds_atype_map(attr);
> -		num_mapped += 1;
> -	}
> -
> -	if (num_mapped == 0) {
> -		return NT_STATUS_NONE_MAPPED;
> -	}
> -	if (num_mapped < num_rids) {
> -		return STATUS_SOME_UNMAPPED;
> -	}
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
> -				     const struct dom_sid *domain_sid,
> -				     int num_names,
> -				     const char **pp_names,
> -				     uint32 *rids,
> -				     enum lsa_SidType *attrs)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
> -					   enum pdb_policy_type type,
> -					   uint32_t *value)
> -{
> -	return account_policy_get(type, value)
> -		? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
> -}
> -
> -static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
> -					   enum pdb_policy_type type,
> -					   uint32_t value)
> -{
> -	return account_policy_set(type, value)
> -		? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
> -}
> -
> -static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m,
> -				    time_t *seq_num)
> -{
> -	return NT_STATUS_NOT_IMPLEMENTED;
> -}
> -
> -struct pdb_ads_search_state {
> -	uint32_t acct_flags;
> -	struct samr_displayentry *entries;
> -	uint32_t num_entries;
> -	ssize_t array_size;
> -	uint32_t current;
> -};
> -
> -static bool pdb_ads_next_entry(struct pdb_search *search,
> -			       struct samr_displayentry *entry)
> -{
> -	struct pdb_ads_search_state *state = talloc_get_type_abort(
> -		search->private_data, struct pdb_ads_search_state);
> -
> -	if (state->current == state->num_entries) {
> -		return false;
> -	}
> -
> -	entry->idx = state->entries[state->current].idx;
> -	entry->rid = state->entries[state->current].rid;
> -	entry->acct_flags = state->entries[state->current].acct_flags;
> -
> -	entry->account_name = talloc_strdup(
> -		search, state->entries[state->current].account_name);
> -	entry->fullname = talloc_strdup(
> -		search, state->entries[state->current].fullname);
> -	entry->description = talloc_strdup(
> -		search, state->entries[state->current].description);
> -
> -	if ((entry->account_name == NULL) || (entry->fullname == NULL)
> -	    || (entry->description == NULL)) {
> -		DEBUG(0, ("talloc_strdup failed\n"));
> -		return false;
> -	}
> -
> -	state->current += 1;
> -	return true;
> -}
> -
> -static void pdb_ads_search_end(struct pdb_search *search)
> -{
> -	struct pdb_ads_search_state *state = talloc_get_type_abort(
> -		search->private_data, struct pdb_ads_search_state);
> -	TALLOC_FREE(state);
> -}
> -
> -static bool pdb_ads_search_filter(struct pdb_methods *m,
> -				  struct pdb_search *search,
> -				  const char *filter,
> -				  uint32_t acct_flags,
> -				  struct pdb_ads_search_state **pstate)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	struct pdb_ads_search_state *sstate;
> -	const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
> -				 "userAccountControl", "description" };
> -	struct tldap_message **users;
> -	int i, rc, num_users;
> -
> -	sstate = talloc_zero(search, struct pdb_ads_search_state);
> -	if (sstate == NULL) {
> -		return false;
> -	}
> -	sstate->acct_flags = acct_flags;
> -
> -	rc = pdb_ads_search_fmt(
> -		state, state->domaindn, TLDAP_SCOPE_SUB,
> -		attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users,
> -		"%s", filter);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("ldap_search_ext_s failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return false;
> -	}
> -
> -	num_users = talloc_array_length(users);
> -
> -	sstate->entries = talloc_array(sstate, struct samr_displayentry,
> -				       num_users);
> -	if (sstate->entries == NULL) {
> -		DEBUG(10, ("talloc failed\n"));
> -		return false;
> -	}
> -
> -	sstate->num_entries = 0;
> -
> -	for (i=0; i<num_users; i++) {
> -		struct samr_displayentry *e;
> -		struct dom_sid sid;
> -		uint32_t ctrl;
> -
> -		e = &sstate->entries[sstate->num_entries];
> -
> -		e->idx = sstate->num_entries;
> -		if (!tldap_pull_binsid(users[i], "objectSid", &sid)) {
> -			DEBUG(10, ("Could not pull sid\n"));
> -			continue;
> -		}
> -		sid_peek_rid(&sid, &e->rid);
> -
> -		if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) {
> -
> -			e->acct_flags = ds_uf2acb(ctrl);
> -
> -			DEBUG(10, ("pdb_ads_search_filter: Found %x, "
> -				   "filter %x\n", (int)e->acct_flags,
> -				   (int)sstate->acct_flags));
> -
> -
> -			if ((sstate->acct_flags != 0) &&
> -			    ((sstate->acct_flags & e->acct_flags) == 0)) {
> -				continue;
> -			}
> -
> -			if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) {
> -				e->acct_flags |= ACB_NORMAL;
> -			}
> -		} else {
> -			e->acct_flags = ACB_NORMAL;
> -		}
> -
> -		if (e->rid == DOMAIN_RID_GUEST) {
> -			/*
> -			 * Guest is specially crafted in s3. Make
> -			 * QueryDisplayInfo match QueryUserInfo
> -			 */
> -			e->account_name = lp_guestaccount();
> -			e->fullname = lp_guestaccount();
> -			e->description = "";
> -			e->acct_flags = ACB_NORMAL;
> -		} else {
> -			e->account_name = tldap_talloc_single_attribute(
> -				users[i], "samAccountName", sstate->entries);
> -			e->fullname = tldap_talloc_single_attribute(
> -				users[i], "displayName", sstate->entries);
> -			e->description = tldap_talloc_single_attribute(
> -				users[i], "description", sstate->entries);
> -		}
> -		if (e->account_name == NULL) {
> -			return false;
> -		}
> -		if (e->fullname == NULL) {
> -			e->fullname = "";
> -		}
> -		if (e->description == NULL) {
> -			e->description = "";
> -		}
> -
> -		sstate->num_entries += 1;
> -		if (sstate->num_entries >= num_users) {
> -			break;
> -		}
> -	}
> -
> -	search->private_data = sstate;
> -	search->next_entry = pdb_ads_next_entry;
> -	search->search_end = pdb_ads_search_end;
> -	*pstate = sstate;
> -	return true;
> -}
> -
> -static bool pdb_ads_search_users(struct pdb_methods *m,
> -				 struct pdb_search *search,
> -				 uint32 acct_flags)
> -{
> -	struct pdb_ads_search_state *sstate;
> -	char *filter;
> -	bool ret;
> -
> -	DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags));
> -
> -	if (acct_flags & ACB_NORMAL) {
> -		filter = talloc_asprintf(
> -			talloc_tos(),
> -			"(&(objectclass=user)(sAMAccountType=%d))",
> -			ATYPE_NORMAL_ACCOUNT);
> -	} else if (acct_flags & ACB_WSTRUST) {
> -		filter = talloc_asprintf(
> -			talloc_tos(),
> -			"(&(objectclass=user)(sAMAccountType=%d))",
> -			ATYPE_WORKSTATION_TRUST);
> -	} else {
> -		filter = talloc_strdup(talloc_tos(), "(objectclass=user)");
> -	}
> -	if (filter == NULL) {
> -		return false;
> -	}
> -
> -	ret = pdb_ads_search_filter(m, search, filter, acct_flags, &sstate);
> -	TALLOC_FREE(filter);
> -	if (!ret) {
> -		return false;
> -	}
> -	return true;
> -}
> -
> -static bool pdb_ads_search_groups(struct pdb_methods *m,
> -				  struct pdb_search *search)
> -{
> -	struct pdb_ads_search_state *sstate;
> -	char *filter;
> -	bool ret;
> -
> -	filter = talloc_asprintf(talloc_tos(),
> -				 "(&(grouptype=%d)(objectclass=group))",
> -				 GTYPE_SECURITY_GLOBAL_GROUP);
> -	if (filter == NULL) {
> -		return false;
> -	}
> -	ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
> -	TALLOC_FREE(filter);
> -	if (!ret) {
> -		return false;
> -	}
> -	return true;
> -}
> -
> -static bool pdb_ads_search_aliases(struct pdb_methods *m,
> -				   struct pdb_search *search,
> -				   const struct dom_sid *sid)
> -{
> -	struct pdb_ads_search_state *sstate;
> -	char *filter;
> -	bool ret;
> -
> -	filter = talloc_asprintf(
> -		talloc_tos(), "(&(grouptype=%d)(objectclass=group))",
> -		sid_check_is_builtin(sid)
> -		? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
> -		: GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
> -
> -	if (filter == NULL) {
> -		return false;
> -	}
> -	ret = pdb_ads_search_filter(m, search, filter, 0, &sstate);
> -	TALLOC_FREE(filter);
> -	if (!ret) {
> -		return false;
> -	}
> -	return true;
> -}
> -
> -static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid,
> -			       struct dom_sid *sid)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	sid_compose(sid, &state->domainsid, uid);
> -	return true;
> -}
> -
> -static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid,
> -			       struct dom_sid *sid)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	sid_compose(sid, &state->domainsid, gid);
> -	return true;
> -}
> -
> -static bool pdb_ads_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
> -			      struct unixid *id)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		m->private_data, struct pdb_ads_state);
> -	const char *attrs[4] = { "objectClass", "samAccountType",
> -				 "uidNumber", "gidNumber" };
> -	struct tldap_message **msg;
> -	char *sidstr, *base;
> -	uint32_t atype;
> -	int rc;
> -	bool ret = false;
> -
> -	id->id = -1;
> -	id->type = ID_TYPE_NOT_SPECIFIED;
> -
> -	sidstr = sid_binstring_hex(sid);
> -	if (sidstr == NULL) {
> -		return false;
> -	}
> -	base = talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr);
> -	SAFE_FREE(sidstr);
> -
> -	rc = pdb_ads_search_fmt(
> -		state, base, TLDAP_SCOPE_BASE,
> -		attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg,
> -		"(objectclass=*)");
> -	TALLOC_FREE(base);
> -
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("pdb_ads_search_fmt failed: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		return false;
> -	}
> -	if (talloc_array_length(msg) != 1) {
> -		DEBUG(10, ("Got %d objects, expected 1\n",
> -			   (int)talloc_array_length(msg)));
> -		goto fail;
> -	}
> -	if (!tldap_pull_uint32(msg[0], "samAccountType", &atype)) {
> -		DEBUG(10, ("samAccountType not found\n"));
> -		goto fail;
> -	}
> -	if (atype == ATYPE_ACCOUNT) {
> -		uid_t uid;
> -		id->type = ID_TYPE_UID;
> -		if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) {
> -			DEBUG(10, ("Did not find uidNumber\n"));
> -			goto fail;
> -		}
> -		id->id = uid;
> -	} else {
> -		gid_t gid;
> -		id->type = ID_TYPE_GID;
> -		if (!tldap_pull_uint32(msg[0], "gidNumber", &gid)) {
> -			DEBUG(10, ("Did not find gidNumber\n"));
> -			goto fail;
> -		}
> -		id->id = gid;
> -	}
> -	ret = true;
> -fail:
> -	TALLOC_FREE(msg);
> -	return ret;
> -}
> -
> -static uint32_t pdb_ads_capabilities(struct pdb_methods *m)
> -{
> -	return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
> -}
> -
> -static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid)
> -{
> -	return false;
> -}
> -
> -static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m,
> -				      const char *domain, char** pwd,
> -				      struct dom_sid *sid,
> -				      time_t *pass_last_set_time)
> -{
> -	return false;
> -}
> -
> -static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m,
> -				      const char* domain, const char* pwd,
> -				      const struct dom_sid *sid)
> -{
> -	return false;
> -}
> -
> -static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m,
> -				      const char *domain)
> -{
> -	return false;
> -}
> -
> -static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
> -					 TALLOC_CTX *mem_ctx,
> -					 uint32 *num_domains,
> -					 struct trustdom_info ***domains)
> -{
> -	*num_domains = 0;
> -	*domains = NULL;
> -	return NT_STATUS_OK;
> -}
> -
> -static void pdb_ads_init_methods(struct pdb_methods *m)
> -{
> -	m->name = "ads";
> -	m->get_domain_info = pdb_ads_get_domain_info;
> -	m->getsampwnam = pdb_ads_getsampwnam;
> -	m->getsampwsid = pdb_ads_getsampwsid;
> -	m->create_user = pdb_ads_create_user;
> -	m->delete_user = pdb_ads_delete_user;
> -	m->add_sam_account = pdb_ads_add_sam_account;
> -	m->update_sam_account = pdb_ads_update_sam_account;
> -	m->delete_sam_account = pdb_ads_delete_sam_account;
> -	m->rename_sam_account = pdb_ads_rename_sam_account;
> -	m->update_login_attempts = pdb_ads_update_login_attempts;
> -	m->getgrsid = pdb_ads_getgrsid;
> -	m->getgrgid = pdb_ads_getgrgid;
> -	m->getgrnam = pdb_ads_getgrnam;
> -	m->create_dom_group = pdb_ads_create_dom_group;
> -	m->delete_dom_group = pdb_ads_delete_dom_group;
> -	m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry;
> -	m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry;
> -	m->delete_group_mapping_entry =	pdb_ads_delete_group_mapping_entry;
> -	m->enum_group_mapping = pdb_ads_enum_group_mapping;
> -	m->enum_group_members = pdb_ads_enum_group_members;
> -	m->enum_group_memberships = pdb_ads_enum_group_memberships;
> -	m->set_unix_primary_group = pdb_ads_set_unix_primary_group;
> -	m->add_groupmem = pdb_ads_add_groupmem;
> -	m->del_groupmem = pdb_ads_del_groupmem;
> -	m->create_alias = pdb_ads_create_alias;
> -	m->delete_alias = pdb_ads_delete_alias;
> -	m->get_aliasinfo = pdb_default_get_aliasinfo;
> -	m->set_aliasinfo = pdb_ads_set_aliasinfo;
> -	m->add_aliasmem = pdb_ads_add_aliasmem;
> -	m->del_aliasmem = pdb_ads_del_aliasmem;
> -	m->enum_aliasmem = pdb_ads_enum_aliasmem;
> -	m->enum_alias_memberships = pdb_ads_enum_alias_memberships;
> -	m->lookup_rids = pdb_ads_lookup_rids;
> -	m->lookup_names = pdb_ads_lookup_names;
> -	m->get_account_policy = pdb_ads_get_account_policy;
> -	m->set_account_policy = pdb_ads_set_account_policy;
> -	m->get_seq_num = pdb_ads_get_seq_num;
> -	m->search_users = pdb_ads_search_users;
> -	m->search_groups = pdb_ads_search_groups;
> -	m->search_aliases = pdb_ads_search_aliases;
> -	m->uid_to_sid = pdb_ads_uid_to_sid;
> -	m->gid_to_sid = pdb_ads_gid_to_sid;
> -	m->sid_to_id = pdb_ads_sid_to_id;
> -	m->capabilities = pdb_ads_capabilities;
> -	m->new_rid = pdb_ads_new_rid;
> -	m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw;
> -	m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw;
> -	m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw;
> -	m->enum_trusteddoms = pdb_ads_enum_trusteddoms;
> -}
> -
> -static void free_private_data(void **vp)
> -{
> -	struct pdb_ads_state *state = talloc_get_type_abort(
> -		*vp, struct pdb_ads_state);
> -
> -	TALLOC_FREE(state->ld);
> -	return;
> -}
> -
> -/*
> -  this is used to catch debug messages from events
> -*/
> -static void s3_tldap_debug(void *context, enum tldap_debug_level level,
> -			   const char *fmt, va_list ap)  PRINTF_ATTRIBUTE(3,0);
> -
> -static void s3_tldap_debug(void *context, enum tldap_debug_level level,
> -			   const char *fmt, va_list ap)
> -{
> -	int samba_level = -1;
> -	char *s = NULL;
> -	switch (level) {
> -	case TLDAP_DEBUG_FATAL:
> -		samba_level = 0;
> -		break;
> -	case TLDAP_DEBUG_ERROR:
> -		samba_level = 1;
> -		break;
> -	case TLDAP_DEBUG_WARNING:
> -		samba_level = 2;
> -		break;
> -	case TLDAP_DEBUG_TRACE:
> -		samba_level = 11;
> -		break;
> -
> -	};
> -	if (vasprintf(&s, fmt, ap) == -1) {
> -		return;
> -	}
> -	DEBUG(samba_level, ("tldap: %s", s));
> -	free(s);
> -}
> -
> -static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state)
> -{
> -	NTSTATUS status;
> -	int fd;
> -
> -	if (tldap_connection_ok(state->ld)) {
> -		return state->ld;
> -	}
> -	TALLOC_FREE(state->ld);
> -
> -	status = open_socket_out(
> -		(struct sockaddr_storage *)(void *)&state->socket_address,
> -		0, 0, &fd);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("Could not connect to %s: %s\n",
> -			   state->socket_address.sun_path, nt_errstr(status)));
> -		return NULL;
> -	}
> -
> -	set_blocking(fd, false);
> -
> -	state->ld = tldap_context_create(state, fd);
> -	if (state->ld == NULL) {
> -		close(fd);
> -		return NULL;
> -	}
> -	tldap_set_debug(state->ld, s3_tldap_debug, NULL);
> -
> -	return state->ld;
> -}
> -
> -int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
> -		       int scope, const char *attrs[], int num_attrs,
> -		       int attrsonly,
> -		       TALLOC_CTX *mem_ctx, struct tldap_message ***res,
> -		       const char *fmt, ...)
> -{
> -	struct tldap_context *ld;
> -	va_list ap;
> -	int ret;
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return TLDAP_SERVER_DOWN;
> -	}
> -
> -	va_start(ap, fmt);
> -	ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
> -			      mem_ctx, res, fmt, ap);
> -	va_end(ap);
> -
> -	if (ret != TLDAP_SERVER_DOWN) {
> -		return ret;
> -	}
> -
> -	/* retry once */
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		return TLDAP_SERVER_DOWN;
> -	}
> -
> -	va_start(ap, fmt);
> -	ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
> -			      mem_ctx, res, fmt, ap);
> -	va_end(ap);
> -	return ret;
> -}
> -
> -static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
> -				const char *location)
> -{
> -	const char *domain_attrs[2] = { "objectSid", "objectGUID" };
> -	const char *ncname_attrs[1] = { "netbiosname" };
> -	struct tldap_context *ld;
> -	struct tldap_message *rootdse, **domain, **ncname;
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	NTSTATUS status;
> -	int num_domains;
> -	int rc;
> -
> -	ZERO_STRUCT(state->socket_address);
> -	state->socket_address.sun_family = AF_UNIX;
> -	strlcpy(state->socket_address.sun_path, location,
> -		sizeof(state->socket_address.sun_path));
> -
> -	ld = pdb_ads_ld(state);
> -	if (ld == NULL) {
> -		status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
> -		goto done;
> -	}
> -
> -	rc = tldap_fetch_rootdse(ld);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not retrieve rootdse: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		status = NT_STATUS_LDAP(rc);
> -		goto done;
> -	}
> -	rootdse = tldap_rootdse(state->ld);
> -
> -	state->domaindn = tldap_talloc_single_attribute(
> -		rootdse, "defaultNamingContext", state);
> -	if (state->domaindn == NULL) {
> -		DEBUG(10, ("Could not get defaultNamingContext\n"));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -	DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn));
> -
> -	state->configdn = tldap_talloc_single_attribute(
> -		rootdse, "configurationNamingContext", state);
> -	if (state->configdn == NULL) {
> -		DEBUG(10, ("Could not get configurationNamingContext\n"));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -	DEBUG(10, ("configurationNamingContext = %s\n", state->configdn));
> -
> -	/*
> -	 * Figure out our domain's SID
> -	 */
> -	rc = pdb_ads_search_fmt(
> -		state, state->domaindn, TLDAP_SCOPE_BASE,
> -		domain_attrs, ARRAY_SIZE(domain_attrs), 0,
> -		talloc_tos(), &domain, "(objectclass=*)");
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not retrieve domain: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		status = NT_STATUS_LDAP(rc);
> -		goto done;
> -	}
> -
> -	num_domains = talloc_array_length(domain);
> -	if (num_domains != 1) {
> -		DEBUG(10, ("Got %d domains, expected one\n", num_domains));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -	if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) {
> -		DEBUG(10, ("Could not retrieve domain SID\n"));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -	if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) {
> -		DEBUG(10, ("Could not retrieve domain GUID\n"));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -	DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid)));
> -
> -	/*
> -	 * Figure out our domain's short name
> -	 */
> -	rc = pdb_ads_search_fmt(
> -		state, state->configdn, TLDAP_SCOPE_SUB,
> -		ncname_attrs, ARRAY_SIZE(ncname_attrs), 0,
> -		talloc_tos(), &ncname, "(ncname=%s)", state->domaindn);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not retrieve ncname: %s\n",
> -			   tldap_errstr(talloc_tos(), state->ld, rc)));
> -		status = NT_STATUS_LDAP(rc);
> -		goto done;
> -	}
> -	if (talloc_array_length(ncname) != 1) {
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -
> -	state->netbiosname = tldap_talloc_single_attribute(
> -		ncname[0], "netbiosname", state);
> -	if (state->netbiosname == NULL) {
> -		DEBUG(10, ("Could not get netbiosname\n"));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto done;
> -	}
> -	DEBUG(10, ("netbiosname: %s\n", state->netbiosname));
> -
> -	if (!strequal(lp_workgroup(), state->netbiosname)) {
> -		DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n",
> -			  state->netbiosname, lp_workgroup()));
> -		status = NT_STATUS_NO_SUCH_DOMAIN;
> -		goto done;
> -	}
> -
> -	secrets_store_domain_sid(state->netbiosname, &state->domainsid);
> -
> -	status = NT_STATUS_OK;
> -done:
> -	TALLOC_FREE(frame);
> -	return status;
> -}
> -
> -static NTSTATUS pdb_ads_init_secrets(struct pdb_methods *m)
> -{
> -#if _SAMBA_BUILD_ == 4
> -	struct pdb_domain_info *dom_info;
> -	bool ret;
> -
> -	dom_info = pdb_ads_get_domain_info(m, m);
> -	if (!dom_info) {
> -		return NT_STATUS_UNSUCCESSFUL;
> -	}
> -
> -	secrets_clear_domain_protection(dom_info->name);
> -	ret = secrets_store_domain_sid(dom_info->name,
> -				       &dom_info->sid);
> -	if (!ret) {
> -		goto done;
> -	}
> -	ret = secrets_store_domain_guid(dom_info->name,
> -				        &dom_info->guid);
> -	if (!ret) {
> -		goto done;
> -	}
> -	ret = secrets_mark_domain_protected(dom_info->name);
> -	if (!ret) {
> -		goto done;
> -	}
> -
> -done:
> -	TALLOC_FREE(dom_info);
> -	if (!ret) {
> -		return NT_STATUS_UNSUCCESSFUL;
> -	}
> -#endif
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method,
> -			     const char *location)
> -{
> -	struct pdb_methods *m;
> -	struct pdb_ads_state *state;
> -	char *tmp = NULL;
> -	NTSTATUS status;
> -
> -	m = talloc(NULL, struct pdb_methods);
> -	if (m == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	state = talloc_zero(m, struct pdb_ads_state);
> -	if (state == NULL) {
> -		goto nomem;
> -	}
> -	m->private_data = state;
> -	m->free_private_data = free_private_data;
> -	pdb_ads_init_methods(m);
> -
> -	if (location == NULL) {
> -		tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
> -				      lp_private_dir());
> -		location = tmp;
> -	}
> -	if (location == NULL) {
> -		goto nomem;
> -	}
> -
> -	status = pdb_ads_connect(state, location);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status)));
> -		goto fail;
> -	}
> -
> -	status = pdb_ads_init_secrets(m);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("pdb_ads_init_secrets failed!\n"));
> -		goto fail;
> -	}
> -
> -	*pdb_method = m;
> -	return NT_STATUS_OK;
> -nomem:
> -	status = NT_STATUS_NO_MEMORY;
> -fail:
> -	TALLOC_FREE(m);
> -	return status;
> -}
> -
> -NTSTATUS pdb_ads_init(void);
> -NTSTATUS pdb_ads_init(void)
> -{
> -	return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads",
> -				   pdb_init_ads);
> -}
> diff --git a/source3/passdb/wscript_build b/source3/passdb/wscript_build
> index 59a7f80..2a39b10 100644
> --- a/source3/passdb/wscript_build
> +++ b/source3/passdb/wscript_build
> @@ -2,7 +2,6 @@
>  
>  PDB_TDBSAM_SRC =    'pdb_tdb.c'
>  PDB_LDAP_SRC =      'pdb_ldap.c pdb_nds.c pdb_ipa.c pdb_ldap_util.c'
> -PDB_ADS_SRC =       'pdb_ads.c'
>  PDB_SMBPASSWD_SRC = 'pdb_smbpasswd.c'
>  PDB_WBC_SAM_SRC =   'pdb_wbc_sam.c'
>  
> @@ -22,14 +21,6 @@ bld.SAMBA3_MODULE('pdb_ldap',
>                   internal_module=bld.SAMBA3_IS_STATIC_MODULE('pdb_ldap'),
>                   enabled=bld.SAMBA3_IS_ENABLED_MODULE('pdb_ldap') and bld.env.HAVE_LDAP)
>  
> -bld.SAMBA3_MODULE('pdb_ads',
> -                 subsystem='pdb',
> -                 source=PDB_ADS_SRC,
> -                 deps='cli-ldap-common TLDAP',
> -                 init_function='',
> -                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('pdb_ads'),
> -                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('pdb_ads'))
> -
>  bld.SAMBA3_MODULE('pdb_smbpasswd',
>                   subsystem='pdb',
>                   source=PDB_SMBPASSWD_SRC,
> diff --git a/source3/wscript b/source3/wscript
> index 02773c0..04c0feb 100755
> --- a/source3/wscript
> +++ b/source3/wscript
> @@ -1385,7 +1385,7 @@ main() {
>                                        vfs_time_audit idmap_autorid''')
>  
>      if Options.options.developer:
> -        default_static_modules.extend(TO_LIST('pdb_ads auth_netlogond charset_weird'))
> +        default_static_modules.extend(TO_LIST('auth_netlogond charset_weird'))
>          default_shared_modules.extend(TO_LIST('perfcount_test'))
>          default_shared_modules.extend(TO_LIST('vfs_skel_opaque vfs_skel_transparent vfs_shadow_copy_test'))
>          default_shared_modules.extend(TO_LIST('auth_skel pdb_test'))
> -- 
> 1.7.7.6
> 

> >From 4e9f090c7ee5e0726284198d638e64bb935cf310 Mon Sep 17 00:00:00 2001
> From: Andrew Bartlett <abartlet at samba.org>
> Date: Sun, 3 Jun 2012 10:56:46 +1000
> Subject: [PATCH 2/2] s3-auth: Remove auth_netlogond
> 
> auth_netlogond was an important module in the development of the
> combined Samba 4.0, and was the first module to link smbd with the AD
> authentication store, showing that it was possible for NTLM
> authentication to be offloaded to the AD server components.
> 
> We now have auth_samba4, which provides the full GENSEC stack to smbd,
> which also matches exactly the group membership and privileges
> assignment and which is supported and tested as part of the official
> Samba 4.0 release configuration.
> 
> Andrew Bartlett
> ---
>  source3/Makefile.in           |    5 -
>  source3/auth/auth_netlogond.c |  448 -----------------------------------------
>  source3/auth/proto.h          |    2 -
>  source3/auth/wscript_build    |    9 -
>  source3/configure.in          |    2 -
>  source3/wscript               |    2 +-
>  6 files changed, 1 insertions(+), 467 deletions(-)
>  delete mode 100644 source3/auth/auth_netlogond.c
> 
> diff --git a/source3/Makefile.in b/source3/Makefile.in
> index fed485a..5d8b656 100644
> --- a/source3/Makefile.in
> +++ b/source3/Makefile.in
> @@ -906,7 +906,6 @@ AUTH_UNIX_OBJ = auth/auth_unix.o
>  AUTH_WINBIND_OBJ = auth/auth_winbind.o
>  AUTH_WBC_OBJ = auth/auth_wbc.o
>  AUTH_SCRIPT_OBJ = auth/auth_script.o
> -AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o
>  
>  AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/token_util.o \
>  	   auth/server_info.o \
> @@ -2656,10 +2655,6 @@ bin/script. at SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_SCRIPT_OBJ)
>  	@echo "Building plugin $@"
>  	@$(SHLD_MODULE) $(AUTH_SCRIPT_OBJ)
>  
> -bin/netlogond. at SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_NETLOGOND_OBJ)
> -	@echo "Building plugin $@"
> -	@$(SHLD_MODULE) $(AUTH_NETLOGOND_OBJ)
> -
>  bin/winbind. at SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ)
>  	@echo "Building plugin $@"
>  	@$(SHLD_MODULE) $(AUTH_WINBIND_OBJ)
> diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c
> deleted file mode 100644
> index 7fb0374..0000000
> --- a/source3/auth/auth_netlogond.c
> +++ /dev/null
> @@ -1,448 +0,0 @@
> -/*
> -   Unix SMB/CIFS implementation.
> -   Authenticate against a netlogon pipe listening on a unix domain socket
> -   Copyright (C) Volker Lendecke 2008
> -
> -   This program is free software; you can redistribute it and/or modify
> -   it under the terms of the GNU General Public License as published by
> -   the Free Software Foundation; either version 3 of the License, or
> -   (at your option) any later version.
> -
> -   This program is distributed in the hope that it will be useful,
> -   but WITHOUT ANY WARRANTY; without even the implied warranty of
> -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> -   GNU General Public License for more details.
> -
> -   You should have received a copy of the GNU General Public License
> -   along with this program.  If not, see <http://www.gnu.org/licenses/>.
> -*/
> -
> -#include "includes.h"
> -#include "auth.h"
> -#include "../libcli/auth/libcli_auth.h"
> -#include "../librpc/gen_ndr/ndr_netlogon.h"
> -#include "librpc/gen_ndr/ndr_schannel.h"
> -#include "rpc_client/cli_pipe.h"
> -#include "rpc_client/cli_netlogon.h"
> -#include "secrets.h"
> -#include "tldap.h"
> -#include "tldap_util.h"
> -
> -#undef DBGC_CLASS
> -#define DBGC_CLASS DBGC_AUTH
> -
> -static bool secrets_store_local_schannel_creds(
> -	const struct netlogon_creds_CredentialState *creds)
> -{
> -	DATA_BLOB blob;
> -	enum ndr_err_code ndr_err;
> -	bool ret;
> -
> -	ndr_err = ndr_push_struct_blob(
> -		&blob, talloc_tos(), creds,
> -		(ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
> -	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
> -		DEBUG(10, ("ndr_push_netlogon_creds_CredentialState failed: "
> -			   "%s\n", ndr_errstr(ndr_err)));
> -		return false;
> -	}
> -	ret = secrets_store(SECRETS_LOCAL_SCHANNEL_KEY,
> -			    blob.data, blob.length);
> -	data_blob_free(&blob);
> -	return ret;
> -}
> -
> -static struct netlogon_creds_CredentialState *
> -secrets_fetch_local_schannel_creds(TALLOC_CTX *mem_ctx)
> -{
> -	struct netlogon_creds_CredentialState *creds;
> -	enum ndr_err_code ndr_err;
> -	DATA_BLOB blob;
> -
> -	blob.data = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY,
> -					     &blob.length);
> -	if (blob.data == NULL) {
> -		DEBUG(10, ("secrets_fetch failed\n"));
> -		return NULL;
> -	}
> -
> -	creds = talloc(mem_ctx, struct netlogon_creds_CredentialState);
> -	if (creds == NULL) {
> -		DEBUG(10, ("talloc failed\n"));
> -		SAFE_FREE(blob.data);
> -		return NULL;
> -	}
> -	ndr_err = ndr_pull_struct_blob(
> -		&blob, creds, creds,
> -		(ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
> -	SAFE_FREE(blob.data);
> -	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
> -		DEBUG(10, ("ndr_pull_netlogon_creds_CredentialState failed: "
> -			   "%s\n", ndr_errstr(ndr_err)));
> -		TALLOC_FREE(creds);
> -		return NULL;
> -	}
> -
> -	return creds;
> -}
> -
> -static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
> -				   const struct auth_context *auth_context,
> -				   const char *ncalrpc_sockname,
> -				   struct netlogon_creds_CredentialState *creds,
> -				   const struct auth_usersupplied_info *user_info,
> -				   struct netr_SamInfo3 **pinfo3,
> -				   NTSTATUS *schannel_bind_result)
> -{
> -	struct rpc_pipe_client *p = NULL;
> -	struct pipe_auth_data *auth = NULL;
> -	struct netr_SamInfo3 *info3 = NULL;
> -	NTSTATUS status;
> -
> -	*schannel_bind_result = NT_STATUS_OK;
> -
> -	status = rpc_pipe_open_ncalrpc(talloc_tos(), ncalrpc_sockname,
> -				       &ndr_table_netlogon.syntax_id, &p);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpc_pipe_open_ncalrpc failed: %s\n",
> -			   nt_errstr(status)));
> -		return status;
> -	}
> -
> -	p->dc = creds;
> -
> -	status = rpccli_schannel_bind_data(p, lp_workgroup(),
> -					   DCERPC_AUTH_LEVEL_PRIVACY,
> -					   p->dc, &auth);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpccli_schannel_bind_data failed: %s\n",
> -			   nt_errstr(status)));
> -		TALLOC_FREE(p);
> -		return status;
> -	}
> -
> -	status = rpc_pipe_bind(p, auth);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
> -		TALLOC_FREE(p);
> -		*schannel_bind_result = status;
> -		return status;
> -	}
> -
> -	status = rpccli_netlogon_sam_network_logon_ex(
> -		p, p,
> -		user_info->logon_parameters,           /* flags such as 'allow
> -					                * workstation logon' */
> -		lp_netbios_name(),                       /* server name */
> -		user_info->client.account_name,        /* user name logging on. */
> -		user_info->client.domain_name,         /* domain name */
> -		user_info->workstation_name,           /* workstation name */
> -		(uchar *)auth_context->challenge.data, /* 8 byte challenge. */
> -		3,				       /* validation level */
> -		user_info->password.response.lanman,   /* lanman 24 byte response */
> -		user_info->password.response.nt,       /* nt 24 byte response */
> -		&info3);                               /* info3 out */
> -
> -	DEBUG(10, ("rpccli_netlogon_sam_network_logon_ex returned %s\n",
> -		   nt_errstr(status)));
> -
> -	if (!NT_STATUS_IS_OK(status)) {
> -		TALLOC_FREE(p);
> -		return status;
> -	}
> -
> -	*pinfo3 = talloc_move(mem_ctx, &info3);
> -
> -	TALLOC_FREE(p);
> -	return NT_STATUS_OK;
> -}
> -
> -static NTSTATUS get_ldapi_ctx(TALLOC_CTX *mem_ctx, struct tldap_context **pld)
> -{
> -	struct tldap_context *ld;
> -	struct sockaddr_un addr;
> -	char *sockaddr;
> -	int fd;
> -	NTSTATUS status;
> -	int res;
> -
> -	sockaddr = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi",
> -				   lp_private_dir());
> -	if (sockaddr == NULL) {
> -		DEBUG(10, ("talloc failed\n"));
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
> -	ZERO_STRUCT(addr);
> -	addr.sun_family = AF_UNIX;
> -	strncpy(addr.sun_path, sockaddr, sizeof(addr.sun_path));
> -	TALLOC_FREE(sockaddr);
> -
> -	status = open_socket_out((struct sockaddr_storage *)(void *)&addr,
> -				 0, 0, &fd);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("Could not connect to %s: %s\n", addr.sun_path,
> -			   nt_errstr(status)));
> -		return status;
> -	}
> -	set_blocking(fd, false);
> -
> -	ld = tldap_context_create(mem_ctx, fd);
> -	if (ld == NULL) {
> -		close(fd);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	res = tldap_fetch_rootdse(ld);
> -	if (res != TLDAP_SUCCESS) {
> -		DEBUG(10, ("tldap_fetch_rootdse failed: %s\n",
> -			   tldap_errstr(talloc_tos(), ld, res)));
> -		TALLOC_FREE(ld);
> -		return NT_STATUS_LDAP(res);
> -	}
> -	*pld = ld;
> -	return NT_STATUS_OK;;
> -}
> -
> -static NTSTATUS mymachinepw(uint8_t pwd[16])
> -{
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	struct tldap_context *ld = NULL;
> -	struct tldap_message *rootdse, **msg;
> -	const char *attrs[1] = { "unicodePwd" };
> -	char *default_nc, *myname;
> -	int rc, num_msg;
> -	DATA_BLOB pwdblob;
> -	NTSTATUS status;
> -
> -	status = get_ldapi_ctx(talloc_tos(), &ld);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		goto fail;
> -	}
> -	rootdse = tldap_rootdse(ld);
> -	if (rootdse == NULL) {
> -		DEBUG(10, ("Could not get rootdse\n"));
> -		status = NT_STATUS_INTERNAL_ERROR;
> -		goto fail;
> -	}
> -	default_nc = tldap_talloc_single_attribute(
> -		rootdse, "defaultNamingContext", talloc_tos());
> -	if (default_nc == NULL) {
> -		DEBUG(10, ("Could not get defaultNamingContext\n"));
> -		status = NT_STATUS_NO_MEMORY;
> -		goto fail;
> -	}
> -	DEBUG(10, ("default_nc = %s\n", default_nc));
> -
> -	myname = talloc_asprintf_strupper_m(talloc_tos(), "%s$",
> -					    lp_netbios_name());
> -	if (myname == NULL) {
> -		DEBUG(10, ("talloc failed\n"));
> -		status = NT_STATUS_NO_MEMORY;
> -		goto fail;
> -	}
> -
> -	rc = tldap_search_fmt(
> -		ld, default_nc, TLDAP_SCOPE_SUB, attrs, ARRAY_SIZE(attrs), 0,
> -		talloc_tos(), &msg,
> -		"(&(sAMAccountName=%s)(objectClass=computer))", myname);
> -	if (rc != TLDAP_SUCCESS) {
> -		DEBUG(10, ("Could not retrieve our account: %s\n",
> -			   tldap_errstr(talloc_tos(), ld, rc)));
> -		status = NT_STATUS_LDAP(rc);
> -		goto fail;
> -	}
> -	num_msg = talloc_array_length(msg);
> -	if (num_msg != 1) {
> -		DEBUG(10, ("Got %d accounts, expected one\n", num_msg));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto fail;
> -	}
> -	if (!tldap_get_single_valueblob(msg[0], "unicodePwd", &pwdblob)) {
> -		char *dn = NULL;
> -		tldap_entry_dn(msg[0], &dn);
> -		DEBUG(10, ("No unicodePwd attribute in %s\n",
> -			   dn ? dn : "<unknown DN>"));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto fail;
> -	}
> -	if (pwdblob.length != 16) {
> -		DEBUG(10, ("Password hash hash has length %d, expected 16\n",
> -			   (int)pwdblob.length));
> -		status = NT_STATUS_INTERNAL_DB_CORRUPTION;
> -		goto fail;
> -	}
> -	memcpy(pwd, pwdblob.data, 16);
> -
> -fail:
> -	TALLOC_FREE(frame);
> -	return status;
> -}
> -
> -static NTSTATUS check_netlogond_security(const struct auth_context *auth_context,
> -					 void *my_private_data,
> -					 TALLOC_CTX *mem_ctx,
> -					 const struct auth_usersupplied_info *user_info,
> -					 struct auth_serversupplied_info **server_info)
> -{
> -	TALLOC_CTX *frame = talloc_stackframe();
> -	struct netr_SamInfo3 *info3 = NULL;
> -	struct rpc_pipe_client *p = NULL;
> -	struct pipe_auth_data *auth = NULL;
> -	uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
> -	uint8_t machine_password[16];
> -	struct netlogon_creds_CredentialState *creds;
> -	NTSTATUS schannel_bind_result, status;
> -	struct named_mutex *mutex = NULL;
> -	const char *ncalrpcsock;
> -
> -	DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));
> -
> -	ncalrpcsock = lp_parm_const_string(
> -		GLOBAL_SECTION_SNUM, "auth_netlogond", "socket", NULL);
> -
> -	if (ncalrpcsock == NULL) {
> -		ncalrpcsock = talloc_asprintf(talloc_tos(), "%s/%s",
> -					      get_dyn_NCALRPCDIR(), "DEFAULT");
> -	}
> -
> -	if (ncalrpcsock == NULL) {
> -		status = NT_STATUS_NO_MEMORY;
> -		goto done;
> -	}
> -
> -	creds = secrets_fetch_local_schannel_creds(talloc_tos());
> -	if (creds == NULL) {
> -		goto new_key;
> -	}
> -
> -	status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
> -				    creds, user_info, &info3,
> -				    &schannel_bind_result);
> -
> -	DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
> -
> -	if (NT_STATUS_IS_OK(status)) {
> -		goto okay;
> -	}
> -
> -	if (NT_STATUS_IS_OK(schannel_bind_result)) {
> -		/*
> -		 * This is a real failure from the DC
> -		 */
> -		goto done;
> -	}
> -
> - new_key:
> -
> -	mutex = grab_named_mutex(talloc_tos(), "LOCAL_SCHANNEL_KEY", 60);
> -	if (mutex == NULL) {
> -		DEBUG(10, ("Could not get mutex LOCAL_SCHANNEL_KEY\n"));
> -		status = NT_STATUS_ACCESS_DENIED;
> -		goto done;
> -	}
> -
> -	DEBUG(10, ("schannel bind failed, setting up new key\n"));
> -
> -	status = rpc_pipe_open_ncalrpc(talloc_tos(), ncalrpcsock,
> -				       &ndr_table_netlogon.syntax_id, &p);
> -
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpc_pipe_open_ncalrpc failed: %s\n",
> -			   nt_errstr(status)));
> -		goto done;
> -	}
> -
> -	status = rpccli_anon_bind_data(p, &auth);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpccli_anon_bind_data failed: %s\n",
> -			   nt_errstr(status)));
> -		goto done;
> -	}
> -
> -	status = rpc_pipe_bind(p, auth);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
> -		goto done;
> -	}
> -
> -	status = mymachinepw(machine_password);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("mymachinepw failed: %s\n", nt_errstr(status)));
> -		goto done;
> -	}
> -
> -	DEBUG(10, ("machinepw "));
> -	dump_data(10, machine_password, 16);
> -
> -	status = rpccli_netlogon_setup_creds(
> -		p, lp_netbios_name(), lp_workgroup(), lp_netbios_name(),
> -		lp_netbios_name(), machine_password, SEC_CHAN_BDC, &neg_flags);
> -
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("rpccli_netlogon_setup_creds failed: %s\n",
> -			   nt_errstr(status)));
> -		goto done;
> -	}
> -
> -	secrets_store_local_schannel_creds(p->dc);
> -
> -	/*
> -	 * Retry the authentication with the mutex held. This way nobody else
> -	 * can step on our toes.
> -	 */
> -
> -	status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock,
> -				    p->dc, user_info, &info3,
> -				    &schannel_bind_result);
> -
> -	TALLOC_FREE(p);
> -
> -	DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status)));
> -
> -	if (!NT_STATUS_IS_OK(status)) {
> -		goto done;
> -	}
> -
> - okay:
> -
> -	status = make_server_info_info3(mem_ctx, user_info->client.account_name,
> -					user_info->mapped.domain_name, server_info,
> -					info3);
> -	if (!NT_STATUS_IS_OK(status)) {
> -		DEBUG(10, ("make_server_info_info3 failed: %s\n",
> -			   nt_errstr(status)));
> -		TALLOC_FREE(frame);
> -		return status;
> -	}
> -
> -	status = NT_STATUS_OK;
> -
> - done:
> -	TALLOC_FREE(frame);
> -	return status;
> -}
> -
> -/* module initialisation */
> -static NTSTATUS auth_init_netlogond(struct auth_context *auth_context,
> -				    const char *param,
> -				    auth_methods **auth_method)
> -{
> -	struct auth_methods *result;
> -
> -	result = talloc_zero(auth_context, struct auth_methods);
> -	if (result == NULL) {
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -	result->name = "netlogond";
> -	result->auth = check_netlogond_security;
> -
> -        *auth_method = result;
> -	return NT_STATUS_OK;
> -}
> -
> -NTSTATUS auth_netlogond_init(void)
> -{
> -	smb_register_auth(AUTH_INTERFACE_VERSION, "netlogond",
> -			  auth_init_netlogond);
> -	return NT_STATUS_OK;
> -}
> diff --git a/source3/auth/proto.h b/source3/auth/proto.h
> index a35a804..e2f5a57 100644
> --- a/source3/auth/proto.h
> +++ b/source3/auth/proto.h
> @@ -93,8 +93,6 @@ NTSTATUS auth_builtin_init(void);
>  void attempt_machine_password_change(void);
>  NTSTATUS auth_domain_init(void);
>  
> -NTSTATUS auth_netlogond_init(void);
> -
>  /* The following definitions come from auth/auth_generic.c  */
>  
>  NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out);
> diff --git a/source3/auth/wscript_build b/source3/auth/wscript_build
> index 47dbea0..8a535cb 100644
> --- a/source3/auth/wscript_build
> +++ b/source3/auth/wscript_build
> @@ -7,7 +7,6 @@ AUTH_UNIX_SRC = 'auth_unix.c'
>  AUTH_WINBIND_SRC = 'auth_winbind.c'
>  AUTH_WBC_SRC = 'auth_wbc.c'
>  AUTH_SCRIPT_SRC = 'auth_script.c'
> -AUTH_NETLOGOND_SRC = 'auth_netlogond.c'
>  
>  AUTH_SRC = '''auth.c
>             user_krb5.c
> @@ -84,14 +83,6 @@ bld.SAMBA3_MODULE('auth_builtin',
>                   internal_module=bld.SAMBA3_IS_STATIC_MODULE('auth_builtin'),
>                   enabled=bld.SAMBA3_IS_ENABLED_MODULE('auth_builtin'))
>  
> -bld.SAMBA3_MODULE('auth_netlogond',
> -                 subsystem='auth',
> -                 source=AUTH_NETLOGOND_SRC,
> -                 deps='TLDAP',
> -                 init_function='',
> -                 internal_module=bld.SAMBA3_IS_STATIC_MODULE('auth_netlogond'),
> -                 enabled=bld.SAMBA3_IS_ENABLED_MODULE('auth_netlogond'))
> -
>  bld.SAMBA3_MODULE('auth_script',
>                   subsystem='auth',
>                   source=AUTH_SCRIPT_SRC,
> diff --git a/source3/configure.in b/source3/configure.in
> index 8e7af08..43c101b 100644
> --- a/source3/configure.in
> +++ b/source3/configure.in
> @@ -468,7 +468,6 @@ default_shared_modules="$default_shared_modules vfs_time_audit"
>  default_shared_modules="$default_shared_modules idmap_autorid"
>  
>  if test "x$developer" = xyes; then
> -   default_static_modules="$default_static_modules auth_netlogond"
>     default_shared_modules="$default_shared_modules perfcount_test"
>  fi
>  
> @@ -6367,7 +6366,6 @@ SMB_MODULE(auth_wbc, \$(AUTH_WBC_OBJ), "bin/wbc.$SHLIBEXT", AUTH)
>  SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH)
>  SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH)
>  SMB_MODULE(auth_script, \$(AUTH_SCRIPT_OBJ), "bin/script.$SHLIBEXT", AUTH)
> -SMB_MODULE(auth_netlogond, \$(AUTH_NETLOGOND_OBJ), "bin/netlogond.$SHLIBEXT", AUTH)
>  SMB_SUBSYSTEM(AUTH,auth/auth.o)
>  
>  SMB_MODULE(vfs_default, \$(VFS_DEFAULT_OBJ), "bin/default.$SHLIBEXT", VFS)
> diff --git a/source3/wscript b/source3/wscript
> index 04c0feb..f31613c 100755
> --- a/source3/wscript
> +++ b/source3/wscript
> @@ -1385,7 +1385,7 @@ main() {
>                                        vfs_time_audit idmap_autorid''')
>  
>      if Options.options.developer:
> -        default_static_modules.extend(TO_LIST('auth_netlogond charset_weird'))
> +        default_static_modules.extend(TO_LIST('charset_weird'))
>          default_shared_modules.extend(TO_LIST('perfcount_test'))
>          default_shared_modules.extend(TO_LIST('vfs_skel_opaque vfs_skel_transparent vfs_shadow_copy_test'))
>          default_shared_modules.extend(TO_LIST('auth_skel pdb_test'))
> -- 
> 1.7.7.6
> 


-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de


More information about the samba-technical mailing list