[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Mon May 24 07:08:39 MDT 2010


The branch, master has been updated
       via  1d66cb0... s4:winbind Give more detail on the parameters when reporting idmap failure
       via  dceca3d... s4:winbind Change idmap API to match that used by the source3/ idmap subsystem
       via  9573c35... s4:winbind Change include guard so as not to conflict with idmap.h in source3
       via  e7fe4d3... s4:winbind Fix up includes after seperation of idmap.idl from winbind.idl
       via  2856476... s4:idmap Adjust code to new idmap structure names and layout.
       via  974ed9c... s4:idmap Seperate idmap structures from winbind.idl and match to source3/ idmap
       via  f6aa090... s4:samr Push most of samr_LookupRids into a helper function
       via  c6ffd88... s4:samr Push most of samr_QueryGroupMember into a helper function
       via  20d2847... s4:samr Move most of samr_CreateDomAlias into a helper function
       via  fc04e56... s4:samr Split most of samr_CreateDomainGroup into a helper function
       via  43c931b... s4:samr Split the guts of samr_CreateUser2 into a helper function
       via  e0d141b... s4:dsdb Allow a NULL search expression in dsdb_search()
       via  6c72674... s4:ntvfs rename notify.idl to s4_notify.idl until we can merge this IDL
      from  8e1e6b0... s4:LogonGetDomainInfo - allow to set DNS hostname for the first time

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1d66cb0e204fa5527f35f58d82bda8b7850e7118
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 15:03:17 2010 +1000

    s4:winbind Give more detail on the parameters when reporting idmap failure

commit dceca3d8ae0220bb8d23325a0a771533bf946217
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 14:58:07 2010 +1000

    s4:winbind Change idmap API to match that used by the source3/ idmap subsystem
    
    This makes it much easier to write an idmap module that bridges the gap.
    
    We should finish the change to the new API, but for the moment this
    choke point works for the conversion.
    
    Andrew Bartlett

commit 9573c35636806a0ce013c32e611603c0e8a480fd
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 11:21:29 2010 +1000

    s4:winbind Change include guard so as not to conflict with idmap.h in source3

commit e7fe4d388516e7bf496056ae9828a4219d5ff7db
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 10:52:18 2010 +1000

    s4:winbind Fix up includes after seperation of idmap.idl from winbind.idl

commit 285647664cf60baa9f8f1a52bea0c55aa01b4e85
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 10:16:34 2010 +1000

    s4:idmap Adjust code to new idmap structure names and layout.
    
    Andrew Bartlett

commit 974ed9cf2c10ab3384c1070c22f5cd42908c95f1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 10:15:04 2010 +1000

    s4:idmap Seperate idmap structures from winbind.idl and match to source3/ idmap
    
    These structures now match those in use in the source3 code.  I'm not
    sure if this is the better API or not, but it is far, far safer to
    remove a pointer than to add one.
    
    Andrew Bartlett

commit f6aa0902025dc562748499d60f3257a0f47329c8
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon May 24 00:57:32 2010 +1000

    s4:samr Push most of samr_LookupRids into a helper function
    
    This is a rewrite of the lookup_rids code, using a query based on the
    extended DN for a clearer interface.
    
    By splitting this out, the logic is able to be shared, rather than
    copied, into a passdb wrapper.
    
    Andrew Bartlett

commit c6ffd884d95eadf634b2e596d8fe5cb952f52ee2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri May 21 08:42:21 2010 +1000

    s4:samr Push most of samr_QueryGroupMember into a helper function
    
    This is a rewrite of the group membership lookup code, using the
    stored extended DNs to avoid doing the lookup into each member to find
    the SID
    
    By splitting this out, the logic is able to be shared, rather than
    copied, into a passdb wrapper.
    
    Andrew Bartlett

commit 20d2847492f9ccdb159df91315be9dcc142b5d83
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri May 21 08:21:37 2010 +1000

    s4:samr Move most of samr_CreateDomAlias into a helper function
    
    This allows this logic to be shared, rather than copied, into a passdb
    wrapper.
    
    Andrew Bartlett

commit fc04e565b08012e2e9926b055b6a8c5f5dccc080
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri May 21 08:17:44 2010 +1000

    s4:samr Split most of samr_CreateDomainGroup into a helper function
    
    This allows this logic to be shared, rather than copied, into a passdb
    wrapper.
    
    Andrew Bartlett

commit 43c931b2d453537f0da0ef2abda14c80d8d91dc9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri May 21 08:14:53 2010 +1000

    s4:samr Split the guts of samr_CreateUser2 into a helper function
    
    This allows this logic to be shared, rather than copied, into a passdb
    wrapper.
    
    Andrew Bartlett

commit e0d141bd4661482f374cbd95d866be587307ecd2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri May 21 08:11:13 2010 +1000

    s4:dsdb Allow a NULL search expression in dsdb_search()
    
    The NULL search expression expands to (objectClass=*), but %s expands
    NULL to (NULL) which doesn't parse...
    
    Andrew Bartlett

commit 6c726745a4253f35a5d2e016185ba5624fd40644
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue May 18 20:34:20 2010 +1000

    s4:ntvfs rename notify.idl to s4_notify.idl until we can merge this IDL
    
    This IDL is almost common, but the source3 version has a
    hand-marshalled server_id.  The s3compat build has problems with two
    different idl files of the same name.
    
    Andrew Bartlett

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/idmap.idl                          |   34 ++
 librpc/idl/wscript_build                      |    2 +-
 source4/dsdb/common/util.c                    |    7 +-
 source4/dsdb/common/util_samr.c               |  534 +++++++++++++++++++++++++
 source4/dsdb/wscript_build                    |    2 +-
 source4/librpc/idl/notify.idl                 |   58 ---
 source4/librpc/idl/s4_notify.idl              |   58 +++
 source4/librpc/idl/winbind.idl                |   27 +--
 source4/librpc/idl/wscript_build              |    2 +-
 source4/librpc/wscript_build                  |    9 +-
 source4/ntvfs/common/notify.c                 |    2 +-
 source4/ntvfs/ntvfs.h                         |    2 +-
 source4/ntvfs/posix/pvfs_acl.c                |   40 +--
 source4/ntvfs/posix/pvfs_acl_nfs4.c           |   26 +-
 source4/ntvfs/sysdep/sys_notify.h             |    2 +-
 source4/ntvfs/unixuid/vfs_unixuid.c           |   24 +-
 source4/rpc_server/samr/dcesrv_samr.c         |  524 +++++--------------------
 source4/rpc_server/unixinfo/dcesrv_unixinfo.c |   28 +-
 source4/winbind/idmap.c                       |  101 ++---
 source4/winbind/idmap.h                       |    6 +-
 source4/winbind/wb_gid2sid.c                  |    9 +-
 source4/winbind/wb_pam_auth.c                 |    1 +
 source4/winbind/wb_sam_logon.c                |    1 +
 source4/winbind/wb_sid2gid.c                  |    6 +-
 source4/winbind/wb_sid2uid.c                  |    6 +-
 source4/winbind/wb_sids2xids.c                |   20 +-
 source4/winbind/wb_uid2sid.c                  |    9 +-
 source4/winbind/wb_xids2sids.c                |   20 +-
 28 files changed, 880 insertions(+), 680 deletions(-)
 create mode 100644 librpc/idl/idmap.idl
 create mode 100644 source4/dsdb/common/util_samr.c
 delete mode 100644 source4/librpc/idl/notify.idl
 create mode 100644 source4/librpc/idl/s4_notify.idl


Changeset truncated at 500 lines:

diff --git a/librpc/idl/idmap.idl b/librpc/idl/idmap.idl
new file mode 100644
index 0000000..65e4596
--- /dev/null
+++ b/librpc/idl/idmap.idl
@@ -0,0 +1,34 @@
+#include "idl_types.h"
+
+import "security.idl";
+
+[
+  pointer_default(unique)
+]
+interface idmap
+{
+	typedef [public] enum {
+		ID_TYPE_NOT_SPECIFIED,
+		ID_TYPE_UID,
+		ID_TYPE_GID,
+		ID_TYPE_BOTH
+	} id_type;
+
+	typedef [public] struct {
+		uint32 id;
+		id_type type;
+	} unixid;
+
+	typedef[public]  enum {
+		ID_UNKNOWN,
+		ID_MAPPED,
+		ID_UNMAPPED,
+		ID_EXPIRED
+	} id_mapping;
+
+	typedef [public] struct {
+		dom_sid *sid;
+		unixid xid;
+		id_mapping status;
+	} id_map;
+}
diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build
index b8c6501..c5be1b7 100644
--- a/librpc/idl/wscript_build
+++ b/librpc/idl/wscript_build
@@ -20,6 +20,6 @@ bld.SAMBA_PIDL_LIST('PIDL',
                     output_dir='../gen_ndr')
 
 bld.SAMBA_PIDL_LIST('PIDL',
-                    'rap.idl',
+                    'rap.idl idmap.idl',
                     options='--header --ndr-parser',
                     output_dir='../gen_ndr')
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index da4d0b3..987864f 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -3641,10 +3641,13 @@ int dsdb_search_one(struct ldb_context *ldb,
 			talloc_free(tmp_ctx);
 			return LDB_ERR_OPERATIONS_ERROR;
 		}
+		ret = dsdb_search(ldb, tmp_ctx, &res, basedn, scope, attrs,
+				  dsdb_flags, "%s", expression);
+	} else {
+		ret = dsdb_search(ldb, tmp_ctx, &res, basedn, scope, attrs,
+				  dsdb_flags, NULL);
 	}
 
-	ret = dsdb_search(ldb, tmp_ctx, &res, basedn, scope, attrs,
-			  dsdb_flags, "%s", expression);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_ctx);
 		return ret;
diff --git a/source4/dsdb/common/util_samr.c b/source4/dsdb/common/util_samr.c
new file mode 100644
index 0000000..42f30e9
--- /dev/null
+++ b/source4/dsdb/common/util_samr.c
@@ -0,0 +1,534 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Helpers to add users and groups to the DB
+
+   Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Volker Lendecke 2004
+   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2004-2010
+   Copyright (C) Matthias Dieter Wallnöfer 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 "dsdb/samdb/samdb.h"
+#include "dsdb/common/util.h"
+#include "../libds/common/flags.h"
+#include "libcli/security/dom_sid.h"
+
+/* Add a user, SAMR style, including the correct transaction
+ * semantics.  Used by the SAMR server and by pdb_samba4 */
+NTSTATUS dsdb_add_user(struct ldb_context *ldb,
+		       TALLOC_CTX *mem_ctx,
+		       const char *account_name,
+		       uint32_t acct_flags,
+		       struct dom_sid **sid,
+		       struct ldb_dn **dn)
+{
+	const char *name;
+	struct ldb_message *msg;
+	int ret;
+	const char *container, *obj_class=NULL;
+	char *cn_name;
+	int cn_name_len;
+
+	const char *attrs[] = {
+		"objectSid",
+		"userAccountControl",
+		NULL
+	};
+
+	uint32_t user_account_control;
+	struct ldb_dn *account_dn;
+	struct dom_sid *account_sid;
+
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+
+	/*
+	 * Start a transaction, so we can query and do a subsequent atomic
+	 * modify
+	 */
+
+	ret = ldb_transaction_start(ldb);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,("Failed to start a transaction for user creation: %s\n",
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	/* check if the user already exists */
+	name = samdb_search_string(ldb, tmp_ctx, NULL,
+				   "sAMAccountName",
+				   "(&(sAMAccountName=%s)(objectclass=user))",
+				   ldb_binary_encode_string(tmp_ctx, account_name));
+	if (name != NULL) {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_USER_EXISTS;
+	}
+
+	msg = ldb_msg_new(tmp_ctx);
+	if (msg == NULL) {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	cn_name   = talloc_strdup(tmp_ctx, account_name);
+	if (!cn_name) {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	cn_name_len = strlen(cn_name);
+
+	/* This must be one of these values *only* */
+	if (acct_flags == ACB_NORMAL) {
+		container = "CN=Users";
+		obj_class = "user";
+
+	} else if (acct_flags == ACB_WSTRUST) {
+		if (cn_name[cn_name_len - 1] != '$') {
+			ldb_transaction_cancel(ldb);
+			return NT_STATUS_FOOBAR;
+		}
+		cn_name[cn_name_len - 1] = '\0';
+		container = "CN=Computers";
+		obj_class = "computer";
+		samdb_msg_add_int(ldb, tmp_ctx, msg,
+			"primaryGroupID", DOMAIN_RID_DOMAIN_MEMBERS);
+
+	} else if (acct_flags == ACB_SVRTRUST) {
+		if (cn_name[cn_name_len - 1] != '$') {
+			ldb_transaction_cancel(ldb);
+			return NT_STATUS_FOOBAR;
+		}
+		cn_name[cn_name_len - 1] = '\0';
+		container = "OU=Domain Controllers";
+		obj_class = "computer";
+		samdb_msg_add_int(ldb, tmp_ctx, msg,
+			"primaryGroupID", DOMAIN_RID_DCS);
+	} else {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* add core elements to the ldb_message for the user */
+	msg->dn = ldb_dn_copy(msg, ldb_get_default_basedn(ldb));
+	if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_FOOBAR;
+	}
+
+	samdb_msg_add_string(ldb, tmp_ctx, msg, "sAMAccountName",
+		account_name);
+	samdb_msg_add_string(ldb, tmp_ctx, msg, "objectClass",
+		obj_class);
+
+	/* create the user */
+	ret = ldb_add(ldb, msg);
+	switch (ret) {
+	case LDB_SUCCESS:
+		break;
+	case LDB_ERR_ENTRY_ALREADY_EXISTS:
+		ldb_transaction_cancel(ldb);
+		DEBUG(0,("Failed to create user record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_USER_EXISTS;
+	case LDB_ERR_UNWILLING_TO_PERFORM:
+	case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+		ldb_transaction_cancel(ldb);
+		DEBUG(0,("Failed to create user record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_ACCESS_DENIED;
+	default:
+		ldb_transaction_cancel(ldb);
+		DEBUG(0,("Failed to create user record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	account_dn = msg->dn;
+
+	/* retrieve the sid and account control bits for the user just created */
+	ret = dsdb_search_one(ldb, tmp_ctx, &msg,
+			      account_dn, LDB_SCOPE_BASE, attrs, 0, NULL);
+
+	if (ret != LDB_SUCCESS) {
+		ldb_transaction_cancel(ldb);
+		DEBUG(0,("Can't locate the account we just created %s: %s\n",
+			 ldb_dn_get_linearized(account_dn), ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+	account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
+	if (account_sid == NULL) {
+		ldb_transaction_cancel(ldb);
+		DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n",
+			 ldb_dn_get_linearized(msg->dn)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	/* Change the account control to be the correct account type.
+	 * The default is for a workstation account */
+	user_account_control = samdb_result_uint(msg, "userAccountControl", 0);
+	user_account_control = (user_account_control &
+				~(UF_NORMAL_ACCOUNT |
+				  UF_INTERDOMAIN_TRUST_ACCOUNT |
+				  UF_WORKSTATION_TRUST_ACCOUNT |
+				  UF_SERVER_TRUST_ACCOUNT));
+	user_account_control |= ds_acb2uf(acct_flags);
+
+	talloc_free(msg);
+	msg = ldb_msg_new(tmp_ctx);
+	if (msg == NULL) {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	msg->dn = account_dn;
+
+	if (samdb_msg_add_uint(ldb, tmp_ctx, msg,
+			       "userAccountControl",
+			       user_account_control) != 0) {
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* modify the samdb record */
+	ret = dsdb_replace(ldb, msg, 0);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		ldb_transaction_cancel(ldb);
+		talloc_free(tmp_ctx);
+
+		/* we really need samdb.c to return NTSTATUS */
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	ret = ldb_transaction_commit(ldb);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+	*dn = talloc_steal(mem_ctx, account_dn);
+	*sid = talloc_steal(mem_ctx, account_sid);
+	talloc_free(tmp_ctx);
+	return NT_STATUS_OK;
+}
+
+/*
+  called by samr_CreateDomainGroup and pdb_samba4
+*/
+NTSTATUS dsdb_add_domain_group(struct ldb_context *ldb,
+			       TALLOC_CTX *mem_ctx,
+			       const char *groupname,
+			       struct dom_sid **sid,
+			       struct ldb_dn **dn)
+{
+	const char *name;
+	struct ldb_message *msg;
+	struct dom_sid *group_sid;
+	int ret;
+
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+
+	/* check if the group already exists */
+	name = samdb_search_string(ldb, tmp_ctx, NULL,
+				   "sAMAccountName",
+				   "(&(sAMAccountName=%s)(objectclass=group))",
+				   ldb_binary_encode_string(tmp_ctx, groupname));
+	if (name != NULL) {
+		return NT_STATUS_GROUP_EXISTS;
+	}
+
+	msg = ldb_msg_new(tmp_ctx);
+	if (msg == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* add core elements to the ldb_message for the user */
+	msg->dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(ldb));
+	ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname);
+	if (!msg->dn) {
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+	samdb_msg_add_string(ldb, tmp_ctx, msg, "sAMAccountName", groupname);
+	samdb_msg_add_string(ldb, tmp_ctx, msg, "objectClass", "group");
+
+	/* create the group */
+	ret = ldb_add(ldb, msg);
+	switch (ret) {
+	case  LDB_SUCCESS:
+		break;
+	case  LDB_ERR_ENTRY_ALREADY_EXISTS:
+		DEBUG(0,("Failed to create group record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_GROUP_EXISTS;
+	case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+		DEBUG(0,("Failed to create group record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_ACCESS_DENIED;
+	default:
+		DEBUG(0,("Failed to create group record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	/* retrieve the sid for the group just created */
+	group_sid = samdb_search_dom_sid(ldb, tmp_ctx,
+					 msg->dn, "objectSid", NULL);
+	if (group_sid == NULL) {
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	*dn = talloc_steal(mem_ctx, msg->dn);
+	*sid = talloc_steal(mem_ctx, group_sid);
+	talloc_free(tmp_ctx);
+	return NT_STATUS_OK;
+}
+
+NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
+			       TALLOC_CTX *mem_ctx,
+			       const char *alias_name,
+			       struct dom_sid **sid,
+			       struct ldb_dn **dn)
+{
+	const char *name;
+	struct ldb_message *msg;
+	struct dom_sid *alias_sid;
+	int ret;
+
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+
+	/* Check if alias already exists */
+	name = samdb_search_string(ldb, tmp_ctx, NULL,
+				   "sAMAccountName",
+				   "(sAMAccountName=%s)(objectclass=group))",
+				   ldb_binary_encode_string(mem_ctx, alias_name));
+
+	if (name != NULL) {
+		talloc_free(tmp_ctx);
+		return NT_STATUS_ALIAS_EXISTS;
+	}
+
+	msg = ldb_msg_new(tmp_ctx);
+	if (msg == NULL) {
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* add core elements to the ldb_message for the alias */
+	msg->dn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb));
+	ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
+	if (!msg->dn) {
+		talloc_free(tmp_ctx);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	samdb_msg_add_string(ldb, mem_ctx, msg, "sAMAccountName", alias_name);
+	samdb_msg_add_string(ldb, mem_ctx, msg, "objectClass", "group");
+	samdb_msg_add_int(ldb, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
+
+	/* create the alias */
+	ret = ldb_add(ldb, msg);
+	switch (ret) {
+	case LDB_SUCCESS:
+		break;
+	case LDB_ERR_ENTRY_ALREADY_EXISTS:
+		talloc_free(tmp_ctx);
+		return NT_STATUS_ALIAS_EXISTS;
+	case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+		talloc_free(tmp_ctx);
+		return NT_STATUS_ACCESS_DENIED;
+	default:
+		DEBUG(0,("Failed to create alias record %s: %s\n",
+			 ldb_dn_get_linearized(msg->dn),
+			 ldb_errstring(ldb)));
+		talloc_free(tmp_ctx);
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	/* retrieve the sid for the alias just created */
+	alias_sid = samdb_search_dom_sid(ldb, tmp_ctx,
+					 msg->dn, "objectSid", NULL);
+
+	*dn = talloc_steal(mem_ctx, msg->dn);
+	*sid = talloc_steal(mem_ctx, alias_sid);
+	talloc_free(tmp_ctx);
+
+	return NT_STATUS_OK;
+}
+
+/* Return the members of this group (which may be a domain group or an alias) */
+NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb,
+			     TALLOC_CTX *mem_ctx,
+			     struct ldb_dn *dn,
+			     struct dom_sid **members_out,
+			     size_t *pnum_members)
+{
+	struct ldb_message *msg;
+	int i, ret;
+	struct dom_sid *members;
+	struct ldb_message_element *member_el;
+	const char *attrs[] = { "member", NULL };
+	NTSTATUS status;
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+
+	ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs,
+			      DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
+	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+		talloc_free(tmp_ctx);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list