summaryrefslogtreecommitdiff
path: root/source/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source/passdb')
-rw-r--r--source/passdb/login_cache.c8
-rw-r--r--source/passdb/lookup_sid.c1130
-rw-r--r--source/passdb/machine_sid.c27
-rw-r--r--source/passdb/passdb.c1614
-rw-r--r--source/passdb/pdb_compat.c10
-rw-r--r--source/passdb/pdb_get_set.c610
-rw-r--r--source/passdb/pdb_guest.c164
-rw-r--r--source/passdb/pdb_interface.c2078
-rw-r--r--source/passdb/pdb_ldap.c2851
-rw-r--r--source/passdb/pdb_mysql.c509
-rw-r--r--source/passdb/pdb_nds.c30
-rw-r--r--source/passdb/pdb_pgsql.c605
-rw-r--r--source/passdb/pdb_plugin.c4
-rw-r--r--source/passdb/pdb_smbpasswd.c116
-rw-r--r--source/passdb/pdb_sql.c571
-rw-r--r--source/passdb/pdb_tdb.c1414
-rw-r--r--source/passdb/pdb_xml.c580
-rw-r--r--source/passdb/secrets.c267
-rw-r--r--source/passdb/util_builtin.c79
-rw-r--r--source/passdb/util_sam_sid.c238
-rw-r--r--source/passdb/util_unixsids.c94
-rw-r--r--source/passdb/util_wellknown.c175
22 files changed, 6320 insertions, 6854 deletions
diff --git a/source/passdb/login_cache.c b/source/passdb/login_cache.c
index d82cfcc5601..fba5990d811 100644
--- a/source/passdb/login_cache.c
+++ b/source/passdb/login_cache.c
@@ -1,6 +1,6 @@
/*
Unix SMB/CIFS implementation.
- SAM_ACCOUNT local cache for
+ struct samu local cache for
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2004.
This program is free software; you can redistribute it and/or modify
@@ -64,7 +64,7 @@ BOOL login_cache_shutdown(void)
}
/* if we can't read the cache, oh well, no need to return anything */
-LOGIN_CACHE * login_cache_read(SAM_ACCOUNT *sampass)
+LOGIN_CACHE * login_cache_read(struct samu *sampass)
{
TDB_DATA keybuf, databuf;
LOGIN_CACHE *entry;
@@ -108,7 +108,7 @@ LOGIN_CACHE * login_cache_read(SAM_ACCOUNT *sampass)
return entry;
}
-BOOL login_cache_write(const SAM_ACCOUNT *sampass, LOGIN_CACHE entry)
+BOOL login_cache_write(const struct samu *sampass, LOGIN_CACHE entry)
{
TDB_DATA keybuf, databuf;
@@ -155,7 +155,7 @@ BOOL login_cache_write(const SAM_ACCOUNT *sampass, LOGIN_CACHE entry)
return ret == 0;
}
-BOOL login_cache_delentry(const SAM_ACCOUNT *sampass)
+BOOL login_cache_delentry(const struct samu *sampass)
{
int ret;
TDB_DATA keybuf;
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index b397e084c33..942d2771782 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -3,6 +3,7 @@
uid/user handling
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Gerald (Jerry) Carter 2003
+ Copyright (C) Volker Lendecke 2005
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
@@ -22,129 +23,804 @@
#include "includes.h"
/*****************************************************************
- *THE CANONICAL* convert name to SID function.
- Tries local lookup first - for local domains - then uses winbind.
+ Dissect a user-provided name into domain, name, sid and type.
+
+ If an explicit domain name was given in the form domain\user, it
+ has to try that. If no explicit domain name was given, we have
+ to do guesswork.
*****************************************************************/
-BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL lookup_name(TALLOC_CTX *mem_ctx,
+ const char *full_name, int flags,
+ const char **ret_domain, const char **ret_name,
+ DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
{
- fstring sid;
- BOOL local_lookup = False;
-
- *name_type = SID_NAME_UNKNOWN;
+ char *p;
+ const char *tmp;
+ const char *domain = NULL;
+ const char *name = NULL;
+ uint32 rid;
+ DOM_SID sid;
+ enum SID_NAME_USE type;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+
+ if (tmp_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return False;
+ }
+
+ p = strchr_m(full_name, '\\');
+
+ if (p != NULL) {
+ domain = talloc_strndup(tmp_ctx, full_name,
+ PTR_DIFF(p, full_name));
+ name = talloc_strdup(tmp_ctx, p+1);
+ } else {
+ domain = talloc_strdup(tmp_ctx, "");
+ name = talloc_strdup(tmp_ctx, full_name);
+ }
+
+ if ((domain == NULL) || (name == NULL)) {
+ DEBUG(0, ("talloc failed\n"));
+ return False;
+ }
- /* If we are looking up a domain user, make sure it is
- for the local machine only */
-
if (strequal(domain, get_global_sam_name())) {
- if (local_lookup_name(name, psid, name_type)) {
- DEBUG(10,
- ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
- domain, name, sid_to_string(sid,psid),
- sid_type_lookup(*name_type), (unsigned int)*name_type));
- return True;
+
+ /* It's our own domain, lookup the name in passdb */
+ if (lookup_global_sam_name(name, flags, &rid, &type)) {
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
+ goto ok;
}
- } else {
- /* Remote */
- if (winbind_lookup_name(domain, name, psid, name_type)) {
-
- DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
- domain, name, sid_to_string(sid, psid),
- (unsigned int)*name_type));
- return True;
+ goto failed;
+ }
+
+ if (strequal(domain, builtin_domain_name())) {
+
+ /* Explicit request for a name in BUILTIN */
+ if (lookup_builtin_name(name, &rid)) {
+ sid_copy(&sid, &global_sid_Builtin);
+ sid_append_rid(&sid, rid);
+ type = SID_NAME_ALIAS;
+ goto ok;
}
+ goto failed;
}
-
- DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
- local_lookup ? "local" : "winbind", domain, name));
+ /* Try the explicit winbind lookup first, don't let it guess the
+ * domain yet at this point yet. This comes later. */
+
+ if ((domain[0] != '\0') &&
+ (winbind_lookup_name(domain, name, &sid, &type))) {
+ goto ok;
+ }
+
+ if (strequal(domain, unix_users_domain_name())) {
+ if (lookup_unix_user_name(name, &sid)) {
+ type = SID_NAME_USER;
+ goto ok;
+ }
+ goto failed;
+ }
+
+ if (strequal(domain, unix_groups_domain_name())) {
+ if (lookup_unix_group_name(name, &sid)) {
+ type = SID_NAME_DOM_GRP;
+ goto ok;
+ }
+ goto failed;
+ }
+
+ if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
+ goto failed;
+ }
+
+ /*
+ * Nasty hack necessary for too common scenarios:
+ *
+ * For 'valid users = +users' we know "users" is most probably not
+ * BUILTIN\users but the unix group users. This hack requires the
+ * admin to explicitly qualify BUILTIN if BUILTIN\users is meant.
+ *
+ * Please note that LOOKUP_NAME_GROUP can not be requested via for
+ * example lsa_lookupnames, it only comes into this routine via
+ * the expansion of group names coming in from smb.conf
+ */
+
+ if ((flags & LOOKUP_NAME_GROUP) &&
+ (lookup_unix_group_name(name, &sid))) {
+ domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
+ type = SID_NAME_DOM_GRP;
+ goto ok;
+ }
+
+ /* Now the guesswork begins, we haven't been given an explicit
+ * domain. Try the sequence as documented on
+ * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
+ * November 27, 2005 */
+
+ /* 1. well-known names */
+
+ if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
+ type = SID_NAME_WKN_GRP;
+ goto ok;
+ }
+
+ /* 2. Builtin domain as such */
+
+ if (strequal(name, builtin_domain_name())) {
+ /* Swap domain and name */
+ tmp = name; name = domain; domain = tmp;
+ sid_copy(&sid, &global_sid_Builtin);
+ type = SID_NAME_DOMAIN;
+ goto ok;
+ }
+
+ /* 3. Account domain */
+
+ if (strequal(name, get_global_sam_name())) {
+ if (!secrets_fetch_domain_sid(name, &sid)) {
+ DEBUG(3, ("Could not fetch my SID\n"));
+ goto failed;
+ }
+ /* Swap domain and name */
+ tmp = name; name = domain; domain = tmp;
+ type = SID_NAME_DOMAIN;
+ goto ok;
+ }
+
+ /* 4. Primary domain */
+
+ if (!IS_DC && strequal(name, lp_workgroup())) {
+ if (!secrets_fetch_domain_sid(name, &sid)) {
+ DEBUG(3, ("Could not fetch the domain SID\n"));
+ goto failed;
+ }
+ /* Swap domain and name */
+ tmp = name; name = domain; domain = tmp;
+ type = SID_NAME_DOMAIN;
+ goto ok;
+ }
+
+ /* 5. Trusted domains as such, to me it looks as if members don't do
+ this, tested an XP workstation in a NT domain -- vl */
+
+ if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
+ &sid, NULL))) {
+ /* Swap domain and name */
+ tmp = name; name = domain; domain = tmp;
+ type = SID_NAME_DOMAIN;
+ goto ok;
+ }
+
+ /* 6. Builtin aliases */
+
+ if (lookup_builtin_name(name, &rid)) {
+ domain = talloc_strdup(tmp_ctx, builtin_domain_name());
+ sid_copy(&sid, &global_sid_Builtin);
+ sid_append_rid(&sid, rid);
+ type = SID_NAME_ALIAS;
+ goto ok;
+ }
+
+ /* 7. Local systems' SAM (DCs don't have a local SAM) */
+ /* 8. Primary SAM (On members, this is the domain) */
+
+ /* Both cases are done by looking at our passdb */
+
+ if (lookup_global_sam_name(name, flags, &rid, &type)) {
+ domain = talloc_strdup(tmp_ctx, get_global_sam_name());
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
+ goto ok;
+ }
+
+ /* Now our local possibilities are exhausted. */
+
+ if (!(flags & LOOKUP_NAME_REMOTE)) {
+ goto failed;
+ }
+
+ /* If we are not a DC, we have to ask in our primary domain. Let
+ * winbind do that. */
+
+ if (!IS_DC &&
+ (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
+ domain = talloc_strdup(tmp_ctx, lp_workgroup());
+ goto ok;
+ }
+
+ /* 9. Trusted domains */
+
+ /* If we're a DC we have to ask all trusted DC's. Winbind does not do
+ * that (yet), but give it a chance. */
+
+ if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
+ DOM_SID dom_sid;
+ uint32 tmp_rid;
+ enum SID_NAME_USE domain_type;
+
+ if (type == SID_NAME_DOMAIN) {
+ /* Swap name and type */
+ tmp = name; name = domain; domain = tmp;
+ goto ok;
+ }
+
+ /* Here we have to cope with a little deficiency in the
+ * winbind API: We have to ask it again for the name of the
+ * domain it figured out itself. Maybe fix that later... */
+
+ sid_copy(&dom_sid, &sid);
+ sid_split_rid(&dom_sid, &tmp_rid);
+
+ if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
+ &domain_type) ||
+ (domain_type != SID_NAME_DOMAIN)) {
+ DEBUG(2, ("winbind could not find the domain's name "
+ "it just looked up for us\n"));
+ goto failed;
+ }
+ goto ok;
+ }
+
+ /* 10. Don't translate */
+
+ /* 11. Ok, windows would end here. Samba has two more options:
+ Unmapped users and unmapped groups */
+
+ if (lookup_unix_user_name(name, &sid)) {
+ domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
+ type = SID_NAME_USER;
+ goto ok;
+ }
+
+ if (lookup_unix_group_name(name, &sid)) {
+ domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
+ type = SID_NAME_DOM_GRP;
+ goto ok;
+ }
+
+ failed:
+ TALLOC_FREE(tmp_ctx);
return False;
+
+ ok:
+ if ((domain == NULL) || (name == NULL)) {
+ DEBUG(0, ("talloc failed\n"));
+ TALLOC_FREE(tmp_ctx);
+ return False;
+ }
+
+ if (ret_name != NULL) {
+ *ret_name = talloc_steal(mem_ctx, name);
+ }
+
+ if (ret_domain != NULL) {
+ char *tmp_dom = talloc_strdup(tmp_ctx, domain);
+ strupper_m(tmp_dom);
+ *ret_domain = talloc_steal(mem_ctx, tmp_dom);
+ }
+
+ if (ret_sid != NULL) {
+ sid_copy(ret_sid, &sid);
+ }
+
+ if (ret_type != NULL) {
+ *ret_type = type;
+ }
+
+ TALLOC_FREE(tmp_ctx);
+ return True;
}
-/*****************************************************************
- *THE CANONICAL* convert SID to name function.
- Tries local lookup first - for local sids, then tries winbind.
-*****************************************************************/
+static BOOL winbind_lookup_rids(TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids, uint32 *rids,
+ const char **domain_name,
+ const char **names, uint32 *types)
+{
+ /* Unless the winbind interface is upgraded, fall back to ask for
+ * individual sids. I imagine introducing a lookuprids operation that
+ * directly proxies to lsa_lookupsids to the correct DC. -- vl */
+
+ int i;
+ for (i=0; i<num_rids; i++) {
+ DOM_SID sid;
+
+ sid_copy(&sid, domain_sid);
+ sid_append_rid(&sid, rids[i]);
+
+ if (winbind_lookup_sid(mem_ctx, &sid,
+ *domain_name == NULL ?
+ domain_name : NULL,
+ &names[i], &types[i])) {
+ if ((names[i] == NULL) || ((*domain_name) == NULL)) {
+ return False;
+ }
+ } else {
+ types[i] = SID_NAME_UNKNOWN;
+ }
+ }
+ return True;
+}
-BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
- enum SID_NAME_USE *name_type)
+static BOOL lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
+ int num_rids, uint32_t *rids,
+ const char **domain_name,
+ const char ***names, enum SID_NAME_USE **types)
{
- if (!name_type)
+ int i;
+
+ *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
+ *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids);
+
+ if ((*names == NULL) || (*types == NULL)) {
return False;
+ }
- *name_type = SID_NAME_UNKNOWN;
+ if (sid_check_is_domain(domain_sid)) {
+ NTSTATUS result;
- /* Check if this is our own sid. This should perhaps be done by
- winbind? For the moment handle it here. */
+ if (*domain_name == NULL) {
+ *domain_name = talloc_strdup(
+ mem_ctx, get_global_sam_name());
+ }
- if (sid_check_is_domain(sid)) {
- fstrcpy(dom_name, get_global_sam_name());
- fstrcpy(name, "");
- *name_type = SID_NAME_DOMAIN;
+ if (*domain_name == NULL) {
+ return False;
+ }
+
+ become_root();
+ result = pdb_lookup_rids(domain_sid, num_rids, rids,
+ *names, *types);
+ unbecome_root();
+
+ return (NT_STATUS_IS_OK(result) ||
+ NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
+ NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
+ }
+
+ if (sid_check_is_builtin(domain_sid)) {
+
+ if (*domain_name == NULL) {
+ *domain_name = talloc_strdup(
+ mem_ctx, builtin_domain_name());
+ }
+
+ if (*domain_name == NULL) {
+ return False;
+ }
+
+ for (i=0; i<num_rids; i++) {
+ if (lookup_builtin_rid(*names, rids[i],
+ &(*names)[i])) {
+ if ((*names)[i] == NULL) {
+ return False;
+ }
+ (*types)[i] = SID_NAME_ALIAS;
+ } else {
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
return True;
}
- if (sid_check_is_in_our_domain(sid)) {
- uint32 rid;
- SMB_ASSERT(sid_peek_rid(sid, &rid));
+ if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
+ for (i=0; i<num_rids; i++) {
+ DOM_SID sid;
+ sid_copy(&sid, domain_sid);
+ sid_append_rid(&sid, rids[i]);
+ if (lookup_wellknown_sid(mem_ctx, &sid,
+ domain_name, &(*names)[i])) {
+ if ((*names)[i] == NULL) {
+ return False;
+ }
+ (*types)[i] = SID_NAME_WKN_GRP;
+ } else {
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
+ return True;
+ }
+
+ if (sid_check_is_unix_users(domain_sid)) {
+ if (*domain_name == NULL) {
+ *domain_name = talloc_strdup(
+ mem_ctx, unix_users_domain_name());
+ }
+ for (i=0; i<num_rids; i++) {
+ (*names)[i] = talloc_strdup(
+ (*names), uidtoname(rids[i]));
+ (*types)[i] = SID_NAME_USER;
+ }
+ return True;
+ }
- /* For our own domain passdb is responsible */
- fstrcpy(dom_name, get_global_sam_name());
- return lookup_global_sam_rid(rid, name, name_type);
+ if (sid_check_is_unix_groups(domain_sid)) {
+ if (*domain_name == NULL) {
+ *domain_name = talloc_strdup(
+ mem_ctx, unix_groups_domain_name());
+ }
+ for (i=0; i<num_rids; i++) {
+ (*names)[i] = talloc_strdup(
+ (*names), gidtoname(rids[i]));
+ (*types)[i] = SID_NAME_DOM_GRP;
+ }
+ return True;
}
- if (sid_check_is_builtin(sid)) {
+ return winbind_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
+ domain_name, *names, *types);
+}
- /* Got through map_domain_sid_to_name here so that the mapping
- * of S-1-5-32 to the name "BUILTIN" in as few places as
- * possible. We might add i18n... */
- SMB_ASSERT(map_domain_sid_to_name(sid, dom_name));
+/*
+ * Is the SID a domain as such? If yes, lookup its name.
+ */
- /* Yes, W2k3 returns "BUILTIN" both as domain and name here */
- fstrcpy(name, dom_name);
+static BOOL lookup_as_domain(const DOM_SID *sid, TALLOC_CTX *mem_ctx,
+ const char **name)
+{
+ const char *tmp;
+ enum SID_NAME_USE type;
- *name_type = SID_NAME_DOMAIN;
+ if (sid_check_is_domain(sid)) {
+ *name = talloc_strdup(mem_ctx, get_global_sam_name());
return True;
}
- if (sid_check_is_in_builtin(sid)) {
- uint32 rid;
+ if (sid_check_is_builtin(sid)) {
+ *name = talloc_strdup(mem_ctx, builtin_domain_name());
+ return True;
+ }
- SMB_ASSERT(sid_peek_rid(sid, &rid));
+ if (sid_check_is_wellknown_domain(sid, &tmp)) {
+ *name = talloc_strdup(mem_ctx, tmp);
+ return True;
+ }
- /* Got through map_domain_sid_to_name here so that the mapping
- * of S-1-5-32 to the name "BUILTIN" in as few places as
- * possible. We might add i18n... */
- SMB_ASSERT(map_domain_sid_to_name(&global_sid_Builtin,
- dom_name));
+ if (sid->num_auths != 4) {
+ /* This can't be a domain */
+ return False;
+ }
- /* There's only aliases in S-1-5-32 */
- *name_type = SID_NAME_ALIAS;
+ if (IS_DC) {
+ uint32 i, num_domains;
+ struct trustdom_info **domains;
- return lookup_builtin_rid(rid, name);
+ /* This is relatively expensive, but it happens only on DCs
+ * and for SIDs that have 4 sub-authorities and thus look like
+ * domains */
+
+ if (!NT_STATUS_IS_OK(secrets_trusted_domains(mem_ctx,
+ &num_domains,
+ &domains))) {
+ return False;
+ }
+
+ for (i=0; i<num_domains; i++) {
+ if (sid_equal(sid, &domains[i]->sid)) {
+ *name = talloc_strdup(mem_ctx,
+ domains[i]->name);
+ return True;
+ }
+ }
+ return False;
}
- if (winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
+ (type == SID_NAME_DOMAIN)) {
+ *name = tmp;
return True;
}
- DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying "
- "special SIDs.\n", sid_string_static(sid)));
+ return False;
+}
- {
- const char *dom, *obj_name;
-
- if (lookup_special_sid(sid, &dom, &obj_name, name_type)) {
- DEBUG(10, ("found %s\\%s\n", dom, obj_name));
- fstrcpy(dom_name, dom);
- fstrcpy(name, obj_name);
- return True;
+/*
+ * This tries to implement the rather weird rules for the lsa_lookup level
+ * parameter.
+ *
+ * This is as close as we can get to what W2k3 does. With this we survive the
+ * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
+ * different, but I assume that's just being too liberal. For example, W2k3
+ * replies to everything else but the levels 1-6 with INVALID_PARAMETER
+ * whereas NT4 does the same as level 1 (I think). I did not fully test that
+ * with NT4, this is what w2k3 does.
+ *
+ * Level 1: Ask everywhere
+ * Level 2: Ask domain and trusted domains, no builtin and wkn
+ * Level 3: Only ask domain
+ * Level 4: W2k3ad: Only ask AD trusts
+ * Level 5: Don't lookup anything
+ * Level 6: Like 4
+ */
+
+static BOOL check_dom_sid_to_level(const DOM_SID *sid, int level)
+{
+ int ret = False;
+
+ switch(level) {
+ case 1:
+ ret = True;
+ break;
+ case 2:
+ ret = (!sid_check_is_builtin(sid) &&
+ !sid_check_is_wellknown_domain(sid, NULL));
+ break;
+ case 3:
+ case 4:
+ case 6:
+ ret = sid_check_is_domain(sid);
+ break;
+ case 5:
+ ret = False;
+ break;
+ }
+
+ DEBUG(10, ("%s SID %s in level %d\n",
+ ret ? "Accepting" : "Rejecting",
+ sid_string_static(sid), level));
+ return ret;
+}
+
+/*
+ * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
+ * references to domains, it is explicitly made for this.
+ *
+ * This attempts to be as efficient as possible: It collects all SIDs
+ * belonging to a domain and hands them in bulk to the appropriate lookup
+ * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
+ * *hugely* from this. Winbind is going to be extended with a lookup_rids
+ * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
+ * appropriate DC.
+ */
+
+NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
+ const DOM_SID **sids, int level,
+ struct lsa_dom_info **ret_domains,
+ struct lsa_name_info **ret_names)
+{
+ TALLOC_CTX *tmp_ctx;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ struct lsa_name_info *name_infos;
+ struct lsa_dom_info *dom_infos;
+
+ int i, j;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ name_infos = TALLOC_ARRAY(tmp_ctx, struct lsa_name_info, num_sids);
+ dom_infos = TALLOC_ZERO_ARRAY(tmp_ctx, struct lsa_dom_info,
+ MAX_REF_DOMAINS);
+ if ((name_infos == NULL) || (dom_infos == NULL)) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* First build up the data structures:
+ *
+ * dom_infos is a list of domains referenced in the list of
+ * SIDs. Later we will walk the list of domains and look up the RIDs
+ * in bulk.
+ *
+ * name_infos is a shadow-copy of the SIDs array to collect the real
+ * data.
+ *
+ * dom_info->idxs is an index into the name_infos array. The
+ * difficulty we have here is that we need to keep the SIDs the client
+ * asked for in the same order for the reply
+ */
+
+ for (i=0; i<num_sids; i++) {
+ DOM_SID sid;
+ uint32 rid;
+ const char *domain_name = NULL;
+
+ sid_copy(&sid, sids[i]);
+ name_infos[i].type = SID_NAME_USE_NONE;
+
+ if (lookup_as_domain(&sid, name_infos, &domain_name)) {
+ /* We can't push that through the normal lookup
+ * process, as this would reference illegal
+ * domains.
+ *
+ * For example S-1-5-32 would end up referencing
+ * domain S-1-5- with RID 32 which is clearly wrong.
+ */
+ if (domain_name == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ name_infos[i].rid = 0;
+ name_infos[i].type = SID_NAME_DOMAIN;
+ name_infos[i].name = NULL;
+
+ if (sid_check_is_builtin(&sid)) {
+ /* Yes, W2k3 returns "BUILTIN" both as domain
+ * and name here */
+ name_infos[i].name = talloc_strdup(
+ name_infos, builtin_domain_name());
+ if (name_infos[i].name == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ }
+ } else {
+ /* This is a normal SID with rid component */
+ if (!sid_split_rid(&sid, &rid)) {
+ result = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ }
+
+ if (!check_dom_sid_to_level(&sid, level)) {
+ name_infos[i].rid = 0;
+ name_infos[i].type = SID_NAME_UNKNOWN;
+ name_infos[i].name = NULL;
+ continue;
+ }
+
+ for (j=0; j<MAX_REF_DOMAINS; j++) {
+ if (!dom_infos[j].valid) {
+ break;
+ }
+ if (sid_equal(&sid, &dom_infos[j].sid)) {
+ break;
+ }
+ }
+
+ if (j == MAX_REF_DOMAINS) {
+ /* TODO: What's the right error message here? */
+ result = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ if (!dom_infos[j].valid) {
+ /* We found a domain not yet referenced, create a new
+ * ref. */
+ dom_infos[j].valid = True;
+ sid_copy(&dom_infos[j].sid, &sid);
+
+ if (domain_name != NULL) {
+ /* This name was being found above in the case
+ * when we found a domain SID */
+ dom_infos[j].name =
+ talloc_steal(dom_infos, domain_name);
+ } else {
+ /* lookup_rids will take care of this */
+ dom_infos[j].name = NULL;
+ }
+ }
+
+ name_infos[i].dom_idx = j;
+
+ if (name_infos[i].type == SID_NAME_USE_NONE) {
+ name_infos[i].rid = rid;
+
+ ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
+ &dom_infos[j].num_idxs);
+
+ if (dom_infos[j].idxs == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
}
}
- DEBUG(10, ("lookup_sid failed\n"));
+ /* Iterate over the domains found */
- return False;
+ for (i=0; i<MAX_REF_DOMAINS; i++) {
+ uint32_t *rids;
+ const char **names;
+ enum SID_NAME_USE *types;
+ struct lsa_dom_info *dom = &dom_infos[i];
+
+ if (!dom->valid) {
+ /* No domains left, we're done */
+ break;
+ }
+
+ rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs);
+
+ if (rids == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ for (j=0; j<dom->num_idxs; j++) {
+ rids[j] = name_infos[dom->idxs[j]].rid;
+ }
+
+ if (!lookup_rids(tmp_ctx, &dom->sid,
+ dom->num_idxs, rids, &dom->name,
+ &names, &types)) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ talloc_steal(dom_infos, dom->name);
+
+ for (j=0; j<dom->num_idxs; j++) {
+ int idx = dom->idxs[j];
+ name_infos[idx].type = types[j];
+ if (types[j] != SID_NAME_UNKNOWN) {
+ name_infos[idx].name =
+ talloc_steal(name_infos, names[j]);
+ } else {
+ name_infos[idx].name = NULL;
+ }
+ }
+ }
+
+ *ret_domains = talloc_steal(mem_ctx, dom_infos);
+ *ret_names = talloc_steal(mem_ctx, name_infos);
+ result = NT_STATUS_OK;
+
+ done:
+ TALLOC_FREE(tmp_ctx);
+ return result;
+}
+
+/*****************************************************************
+ *THE CANONICAL* convert SID to name function.
+*****************************************************************/
+
+BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ const char **ret_domain, const char **ret_name,
+ enum SID_NAME_USE *ret_type)
+{
+ struct lsa_dom_info *domain;
+ struct lsa_name_info *name;
+ TALLOC_CTX *tmp_ctx;
+ BOOL ret = False;
+
+ tmp_ctx = talloc_new(mem_ctx);
+
+ if (tmp_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return False;
+ }
+
+ if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
+ &domain, &name))) {
+ goto done;
+ }
+
+ if (name->type == SID_NAME_UNKNOWN) {
+ goto done;
+ }
+
+ if (ret_domain != NULL) {
+ *ret_domain = talloc_steal(mem_ctx, domain->name);
+ }
+
+ if (ret_name != NULL) {
+ *ret_name = talloc_steal(mem_ctx, name->name);
+ }
+
+ if (ret_type != NULL) {
+ *ret_type = name->type;
+ }
+
+ ret = True;
+
+ done:
+ if (ret) {
+ DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
+ sid_string_static(sid), domain->name,
+ name->name, name->type));
+ } else {
+ DEBUG(10, ("failed to lookup sid %s\n",
+ sid_string_static(sid)));
+ }
+ TALLOC_FREE(tmp_ctx);
+ return ret;
}
/*****************************************************************
@@ -187,10 +863,9 @@ static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
if (pc->uid == uid) {
- fstring sid;
*psid = pc->sid;
DEBUG(3,("fetch sid from uid cache %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid)));
+ (unsigned int)uid, sid_string_static(psid)));
DLIST_PROMOTE(uid_sid_cache_head, pc);
return True;
}
@@ -208,10 +883,9 @@ static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
if (sid_compare(&pc->sid, psid) == 0) {
- fstring sid;
*puid = pc->uid;
DEBUG(3,("fetch uid from cache %u -> %s\n",
- (unsigned int)*puid, sid_to_string(sid, psid)));
+ (unsigned int)*puid, sid_string_static(psid)));
DLIST_PROMOTE(uid_sid_cache_head, pc);
return True;
}
@@ -223,7 +897,7 @@ static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
Store uid to SID mapping in cache.
*****************************************************************/
-static void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
+void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
{
struct uid_sid_cache *pc;
@@ -261,10 +935,9 @@ static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
if (pc->gid == gid) {
- fstring sid;
*psid = pc->sid;
DEBUG(3,("fetch sid from gid cache %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid, psid)));
+ (unsigned int)gid, sid_string_static(psid)));
DLIST_PROMOTE(gid_sid_cache_head, pc);
return True;
}
@@ -282,10 +955,9 @@ static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
if (sid_compare(&pc->sid, psid) == 0) {
- fstring sid;
*pgid = pc->gid;
DEBUG(3,("fetch gid from cache %u -> %s\n",
- (unsigned int)*pgid, sid_to_string(sid, psid)));
+ (unsigned int)*pgid, sid_string_static(psid)));
DLIST_PROMOTE(gid_sid_cache_head, pc);
return True;
}
@@ -297,7 +969,7 @@ static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
Store gid to SID mapping in cache.
*****************************************************************/
-static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
+void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
{
struct gid_sid_cache *pc;
@@ -329,201 +1001,259 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
*THE CANONICAL* convert uid_t to SID function.
*****************************************************************/
-NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
+void uid_to_sid(DOM_SID *psid, uid_t uid)
{
- fstring sid;
uid_t low, high;
+ uint32 rid;
ZERO_STRUCTP(psid);
if (fetch_sid_from_uid_cache(psid, uid))
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
-
- /* DC's never use winbindd to resolve users outside the
- defined idmap range */
+ return;
- if ( lp_server_role()==ROLE_DOMAIN_MEMBER
- || (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) )
- {
- if (winbind_uid_to_sid(psid, uid)) {
+ if (lp_idmap_uid(&low, &high) && (uid >= low) && (uid <= high) &&
+ winbind_uid_to_sid(psid, uid)) {
- DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid)));
+ DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)uid, sid_string_static(psid)));
+ goto done;
+ }
- if (psid)
- store_uid_sid_cache(psid, uid);
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- }
+ if (pdb_uid_to_rid(uid, &rid)) {
+ /* This is a mapped user */
+ sid_copy(psid, get_global_sam_sid());
+ sid_append_rid(psid, rid);
+ goto done;
}
- if (!local_uid_to_sid(psid, uid)) {
- DEBUG(10,("uid_to_sid: local %u failed to map to sid\n", (unsigned int)uid ));
- return NT_STATUS_UNSUCCESSFUL;
+ if (pdb_rid_algorithm() && (uid < max_algorithmic_uid())) {
+ sid_copy(psid, get_global_sam_sid());
+ sid_append_rid(psid, algorithmic_pdb_uid_to_user_rid(uid));
+ goto done;
+ } else {
+ sid_copy(psid, &global_sid_Unix_Users);
+ sid_append_rid(psid, uid);
+ goto done;
}
-
- DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
+
+ done:
+ DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
+ sid_string_static(psid)));
store_uid_sid_cache(psid, uid);
- return NT_STATUS_OK;
+ return;
}
/*****************************************************************
*THE CANONICAL* convert gid_t to SID function.
*****************************************************************/
-NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
+void gid_to_sid(DOM_SID *psid, gid_t gid)
{
- fstring sid;
gid_t low, high;
ZERO_STRUCTP(psid);
if (fetch_sid_from_gid_cache(psid, gid))
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
+ return;
- /* DC's never use winbindd to resolve groups outside the
- defined idmap range */
+ if (lp_idmap_gid(&low, &high) && (gid >= low) && (gid <= high) &&
+ winbind_gid_to_sid(psid, gid)) {
- if ( lp_server_role()==ROLE_DOMAIN_MEMBER
- || (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) )
- {
- if (winbind_gid_to_sid(psid, gid)) {
+ DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)gid, sid_string_static(psid)));
+ goto done;
+ }
- DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid, psid)));
-
- if (psid)
- store_gid_sid_cache(psid, gid);
- return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
- }
+ if (pdb_gid_to_sid(gid, psid)) {
+ /* This is a mapped group */
+ goto done;
}
- if (!local_gid_to_sid(psid, gid)) {
- DEBUG(10,("gid_to_sid: local %u failed to map to sid\n", (unsigned int)gid ));
- return NT_STATUS_UNSUCCESSFUL;
+ if (pdb_rid_algorithm() && (gid < max_algorithmic_gid())) {
+ sid_copy(psid, get_global_sam_sid());
+ sid_append_rid(psid, pdb_gid_to_group_rid(gid));
+ goto done;
+ } else {
+ sid_copy(psid, &global_sid_Unix_Groups);
+ sid_append_rid(psid, gid);
+ goto done;
}
-
- DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
+
+ done:
+ DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
+ sid_string_static(psid)));
store_gid_sid_cache(psid, gid);
- return NT_STATUS_OK;
+ return;
}
/*****************************************************************
*THE CANONICAL* convert SID to uid function.
*****************************************************************/
-NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
+BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
{
- fstring dom_name, name, sid_str;
- enum SID_NAME_USE name_type;
+ enum SID_NAME_USE type;
+ uint32 rid;
+ gid_t gid;
if (fetch_uid_from_cache(puid, psid))
- return NT_STATUS_OK;
+ return True;
- /* if this is our SID then go straight to a local lookup */
-
- if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) {
- DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n",
- sid_string_static(psid) ));
-
- if ( local_sid_to_uid(puid, psid, &name_type) )
- goto success;
-
- DEBUG(10,("sid_to_uid: local lookup failed\n"));
-
- return NT_STATUS_UNSUCCESSFUL;
+ if (fetch_gid_from_cache(&gid, psid)) {
+ return False;
}
-
- /* If it is not our local domain, only hope is winbindd */
- if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) {
- DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n",
- sid_string_static(psid) ));
-
- return NT_STATUS_UNSUCCESSFUL;
+ if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
+ uid_t uid = rid;
+ *puid = uid;
+ goto done;
}
- /* If winbindd does know the SID, ensure this is a user */
+ if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
+ union unid_t id;
+
+ if (pdb_sid_to_id(psid, &id, &type)) {
+ if (type != SID_NAME_USER) {
+ DEBUG(5, ("sid %s is a %s, expected a user\n",
+ sid_string_static(psid),
+ sid_type_lookup(type)));
+ return False;
+ }
+ *puid = id.uid;
+ goto done;
+ }
+ if (pdb_rid_algorithm() &&
+ algorithmic_pdb_rid_is_user(rid)) {
+ *puid = algorithmic_pdb_user_rid_to_uid(rid);
+ goto done;
+ }
- if (name_type != SID_NAME_USER) {
- DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a user (%u)\n",
- (unsigned int)name_type ));
- return NT_STATUS_INVALID_PARAMETER;
+ /* This was ours, but it was neither mapped nor
+ * algorithmic. Fail */
+ return False;
}
- /* get the uid. Has to work or else we are dead in the water */
+ if (winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
+
+ if (type != SID_NAME_USER) {
+ DEBUG(10, ("sid_to_uid: sid %s is a %s\n",
+ sid_string_static(psid),
+ sid_type_lookup(type)));
+ return False;
+ }
- if ( !winbind_sid_to_uid(puid, psid) ) {
- DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
- sid_to_string(sid_str, psid) ));
- return NT_STATUS_UNSUCCESSFUL;
+ if (!winbind_sid_to_uid(puid, psid)) {
+ DEBUG(5, ("sid_to_uid: winbind failed to allocate a "
+ "new uid for sid %s\n",
+ sid_string_static(psid)));
+ return False;
+ }
+ goto done;
}
-success:
- DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
+ /* TODO: Here would be the place to allocate both a gid and a uid for
+ * the SID in question */
+
+ return False;
+
+ done:
+ DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
(unsigned int)*puid ));
store_uid_sid_cache(psid, *puid);
-
- return NT_STATUS_OK;
+ return True;
}
+
/*****************************************************************
*THE CANONICAL* convert SID to gid function.
Group mapping is used for gids that maps to Wellknown SIDs
*****************************************************************/
-NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
+BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
{
- fstring dom_name, name, sid_str;
- enum SID_NAME_USE name_type;
+ uint32 rid;
+ GROUP_MAP map;
+ union unid_t id;
+ enum SID_NAME_USE type;
+ uid_t uid;
if (fetch_gid_from_cache(pgid, psid))
- return NT_STATUS_OK;
+ return True;
- /*
- * First we must look up the name and decide if this is a group sid.
- * Group mapping can deal with foreign SIDs
- */
+ if (fetch_uid_from_cache(&uid, psid))
+ return False;
+
+ if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
+ gid_t gid = rid;
+ *pgid = gid;
+ goto done;
+ }
+
+ if ((sid_check_is_in_builtin(psid) ||
+ sid_check_is_in_wellknown_domain(psid))) {
+ if (pdb_getgrsid(&map, *psid)) {
+ *pgid = map.gid;
+ goto done;
+ }
+ return False;
+ }
- if ( local_sid_to_gid(pgid, psid, &name_type) )
- goto success;
+ if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
+ if (pdb_sid_to_id(psid, &id, &type)) {
+ if ((type != SID_NAME_DOM_GRP) &&
+ (type != SID_NAME_ALIAS)) {
+ DEBUG(5, ("sid %s is a %s, expected a group\n",
+ sid_string_static(psid),
+ sid_type_lookup(type)));
+ return False;
+ }
+ *pgid = id.gid;
+ goto done;
+ }
+ if (pdb_rid_algorithm() &&
+ !algorithmic_pdb_rid_is_user(rid)) {
+ /* This must be a group, presented as alias */
+ *pgid = pdb_group_rid_to_gid(rid);
+ goto done;
+ }
+ /* This was ours, but it was neither mapped nor
+ * algorithmic. Fail. */
+ return False;
+ }
- if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
- DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then winbind)\n", sid_to_string(sid_str, psid)));
+ if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
+ DEBUG(11,("sid_to_gid: no one knows the SID %s (tried local, "
+ "then winbind)\n", sid_string_static(psid)));
- return NT_STATUS_UNSUCCESSFUL;
+ return False;
}
/* winbindd knows it; Ensure this is a group sid */
- if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS)
- && (name_type != SID_NAME_WKN_GRP))
- {
- DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
- (unsigned int)name_type ));
-
- /* winbindd is running and knows about this SID. Just the wrong type.
- Don't fallback to a local lookup here */
-
- return NT_STATUS_INVALID_PARAMETER;
+ if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
+ (type != SID_NAME_WKN_GRP)) {
+ DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is "
+ "a %s\n", sid_type_lookup(type)));
+ return False;
}
/* winbindd knows it and it is a type of group; sid_to_gid must succeed
or we are dead in the water */
if ( !winbind_sid_to_gid(pgid, psid) ) {
- DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid for sid %s\n",
- sid_to_string(sid_str, psid) ));
- return NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid "
+ "for sid %s\n", sid_string_static(psid)));
+ return False;
}
-success:
- DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
- (unsigned int)*pgid ));
+ done:
+ DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
+ (unsigned int)*pgid ));
store_gid_sid_cache(psid, *pgid);
- return NT_STATUS_OK;
+ return True;
}
diff --git a/source/passdb/machine_sid.c b/source/passdb/machine_sid.c
index 87ec27d34ea..d7cae06749c 100644
--- a/source/passdb/machine_sid.c
+++ b/source/passdb/machine_sid.c
@@ -35,13 +35,14 @@ static DOM_SID *global_sam_sid=NULL;
Read a SID from a file. This is for compatibility with the old MACHINE.SID
style of SID storage
****************************************************************************/
+
static BOOL read_sid_from_file(const char *fname, DOM_SID *sid)
{
char **lines;
int numlines;
BOOL ret;
- lines = file_lines_load(fname, &numlines);
+ lines = file_lines_load(fname, &numlines,0);
if (!lines || numlines < 1) {
if (lines) file_lines_free(lines);
@@ -198,3 +199,27 @@ void reset_global_sam_sid(void)
{
SAFE_FREE(global_sam_sid);
}
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+
+BOOL sid_check_is_domain(const DOM_SID *sid)
+{
+ return sid_equal(sid, get_global_sam_sid());
+}
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+
+BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_equal(&dom_sid, get_global_sam_sid());
+}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 2c8ab514f55..876f04bdfe7 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -3,9 +3,10 @@
Password and authentication handling
Copyright (C) Jeremy Allison 1996-2001
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Gerald (Jerry) Carter 2000-2001
+ Copyright (C) Gerald (Jerry) Carter 2000-2006
Copyright (C) Andrew Bartlett 2001-2002
Copyright (C) Simo Sorce 2003
+ Copyright (C) Volker Lendecke 2006
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
@@ -35,7 +36,7 @@
standalone box will map to WKS\user.
******************************************************************/
-const char *get_default_sam_name(void)
+const char *my_sam_name(void)
{
/* standalone servers can only use the local netbios name */
if ( lp_server_role() == ROLE_STANDALONE )
@@ -46,410 +47,204 @@ const char *get_default_sam_name(void)
return lp_workgroup();
}
-/************************************************************
- Fill the SAM_ACCOUNT with default values.
- ***********************************************************/
+/**********************************************************************
+***********************************************************************/
-void pdb_fill_default_sam(SAM_ACCOUNT *user)
+static int samu_destroy(void *p)
{
- ZERO_STRUCT(user->private_u); /* Don't touch the talloc context */
-
- /* no initial methods */
- user->methods = NULL;
-
- /* Don't change these timestamp settings without a good reason.
- They are important for NT member server compatibility. */
-
- user->private_u.logon_time = (time_t)0;
- user->private_u.pass_last_set_time = (time_t)0;
- user->private_u.pass_can_change_time = (time_t)0;
- user->private_u.logoff_time =
- user->private_u.kickoff_time =
- user->private_u.pass_must_change_time = get_time_t_max();
- user->private_u.fields_present = 0x00ffffff;
- user->private_u.logon_divs = 168; /* hours per week */
- user->private_u.hours_len = 21; /* 21 times 8 bits = 168 */
- memset(user->private_u.hours, 0xff, user->private_u.hours_len); /* available at all hours */
- user->private_u.bad_password_count = 0;
- user->private_u.logon_count = 0;
- user->private_u.unknown_6 = 0x000004ec; /* don't know */
-
- /* Some parts of samba strlen their pdb_get...() returns,
- so this keeps the interface unchanged for now. */
-
- user->private_u.username = "";
- user->private_u.domain = "";
- user->private_u.nt_username = "";
- user->private_u.full_name = "";
- user->private_u.home_dir = "";
- user->private_u.logon_script = "";
- user->private_u.profile_path = "";
- user->private_u.acct_desc = "";
- user->private_u.workstations = "";
- user->private_u.unknown_str = "";
- user->private_u.munged_dial = "";
-
- user->private_u.plaintext_pw = NULL;
-
- /*
- Unless we know otherwise have a Account Control Bit
- value of 'normal user'. This helps User Manager, which
- asks for a filtered list of users.
- */
+ struct samu *user = p;
- user->private_u.acct_ctrl = ACB_NORMAL;
-}
+ data_blob_clear_free( &user->lm_pw );
+ data_blob_clear_free( &user->nt_pw );
-static void destroy_pdb_talloc(SAM_ACCOUNT **user)
-{
- if (*user) {
- data_blob_clear_free(&((*user)->private_u.lm_pw));
- data_blob_clear_free(&((*user)->private_u.nt_pw));
+ if ( user->plaintext_pw )
+ memset( user->plaintext_pw, 0x0, strlen(user->plaintext_pw) );
- if((*user)->private_u.plaintext_pw!=NULL)
- memset((*user)->private_u.plaintext_pw,'\0',strlen((*user)->private_u.plaintext_pw));
- talloc_destroy((*user)->mem_ctx);
- *user = NULL;
- }
+ return 0;
}
-
/**********************************************************************
- Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.
+ generate a new struct samuser
***********************************************************************/
-NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
+struct samu* samu_new( TALLOC_CTX *ctx )
{
- if (*user != NULL) {
- DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
-#if 0
- smb_panic("non-NULL pointer passed to pdb_init_sam\n");
-#endif
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!mem_ctx) {
- DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ struct samu *user;
+
+ if ( !(user = TALLOC_ZERO_P( ctx, struct samu )) ) {
+ DEBUG(0,("samuser_new: Talloc failed!\n"));
+ return NULL;
}
+
+ talloc_set_destructor( user, samu_destroy );
+
+ /* no initial methods */
+
+ user->methods = NULL;
- *user=TALLOC_P(mem_ctx, SAM_ACCOUNT);
-
- if (*user==NULL) {
- DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ /* Don't change these timestamp settings without a good reason.
+ They are important for NT member server compatibility. */
- (*user)->mem_ctx = mem_ctx;
+ user->logon_time = (time_t)0;
+ user->pass_last_set_time = (time_t)0;
+ user->pass_can_change_time = (time_t)0;
+ user->logoff_time = get_time_t_max();
+ user->kickoff_time = get_time_t_max();
+ user->pass_must_change_time = get_time_t_max();
+ user->fields_present = 0x00ffffff;
+ user->logon_divs = 168; /* hours per week */
+ user->hours_len = 21; /* 21 times 8 bits = 168 */
+ memset(user->hours, 0xff, user->hours_len); /* available at all hours */
+ user->bad_password_count = 0;
+ user->logon_count = 0;
+ user->unknown_6 = 0x000004ec; /* don't know */
- (*user)->free_fn = NULL;
+ /* Some parts of samba strlen their pdb_get...() returns,
+ so this keeps the interface unchanged for now. */
+
+ user->username = "";
+ user->domain = "";
+ user->nt_username = "";
+ user->full_name = "";
+ user->home_dir = "";
+ user->logon_script = "";
+ user->profile_path = "";
+ user->acct_desc = "";
+ user->workstations = "";
+ user->unknown_str = "";
+ user->munged_dial = "";
+
+ user->plaintext_pw = NULL;
+
+ /* Unless we know otherwise have a Account Control Bit
+ value of 'normal user'. This helps User Manager, which
+ asks for a filtered list of users. */
- pdb_fill_default_sam(*user);
+ user->acct_ctrl = ACB_NORMAL;
- return NT_STATUS_OK;
+
+ return user;
}
+/*********************************************************************
+ Initialize a struct samu from a struct passwd including the user
+ and group SIDs. The *user structure is filled out with the Unix
+ attributes and a user SID.
+*********************************************************************/
-/*************************************************************
- Allocates memory and initialises a struct sam_passwd.
- ************************************************************/
-
-NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
+static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *pwd, BOOL create)
{
- TALLOC_CTX *mem_ctx;
- NTSTATUS nt_status;
-
- mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");
+ const char *guest_account = lp_guestaccount();
+ const char *domain = global_myname();
+ uint32 urid;
- if (!mem_ctx) {
- DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));
- return NT_STATUS_NO_MEMORY;
+ if ( !pwd ) {
+ return NT_STATUS_NO_SUCH_USER;
}
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {
- talloc_destroy(mem_ctx);
- return nt_status;
- }
+ /* Basic properties based upon the Unix account information */
- (*user)->free_fn = destroy_pdb_talloc;
-
- return NT_STATUS_OK;
-}
-
-/**************************************************************************
- * This function will take care of all the steps needed to correctly
- * allocate and set the user SID, please do use this function to create new
- * users, messing with SIDs is not good.
- *
- * account_data must be provided initialized, pwd may be null.
- * SSS
- ***************************************************************************/
-
-static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
-{
- const char *guest_account = lp_guestaccount();
- GROUP_MAP map;
- BOOL ret;
+ pdb_set_username(user, pwd->pw_name, PDB_SET);
+ pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
+ pdb_set_domain (user, get_global_sam_name(), PDB_DEFAULT);
- if (!account_data || !pwd) {
- return NT_STATUS_INVALID_PARAMETER;
- }
+ /* save the password structure for later use */
+
+ user->unix_pw = tcopy_passwd( user, pwd );
- /* this is a hack this thing should not be set
- this way --SSS */
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- } else {
- /* Ensure this *must* be set right */
- if (strcmp(pwd->pw_name, guest_account) == 0) {
- if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
- return NT_STATUS_OK;
+ /* Special case for the guest account which must have a RID of 501 */
+
+ if ( strequal( pwd->pw_name, guest_account ) ) {
+ if ( !pdb_set_user_sid_from_rid(user, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {
+ return NT_STATUS_NO_SUCH_USER;
}
+ return NT_STATUS_OK;
}
-
- if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {
- DEBUG(0,("Can't set User SID from RID!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* call the mapping code here */
- become_root();
- ret = pdb_getgrgid(&map, pwd->pw_gid);
- unbecome_root();
- if( ret ) {
- if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
- DEBUG(0,("Can't set Group SID!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
+ /* Non-guest accounts...Check for a workstation or user account */
+
+ if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
+ /* workstation */
+
+ if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
+ DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
+ pwd->pw_name));
+ return NT_STATUS_INVALID_COMPUTER_NAME;
+ }
}
else {
- if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {
- DEBUG(0,("Can't set Group SID\n"));
- return NT_STATUS_INVALID_PARAMETER;
+ /* user */
+
+ if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
+ DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
+ pwd->pw_name));
+ return NT_STATUS_INVALID_ACCOUNT_NAME;
}
+
+ /* set some basic attributes */
+
+ pdb_set_profile_path(user, talloc_sub_specified(user,
+ lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
+ PDB_DEFAULT);
+ pdb_set_homedir(user, talloc_sub_specified(user,
+ lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
+ PDB_DEFAULT);
+ pdb_set_dir_drive(user, talloc_sub_specified(user,
+ lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
+ PDB_DEFAULT);
+ pdb_set_logon_script(user, talloc_sub_specified(user,
+ lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid),
+ PDB_DEFAULT);
}
-
- return NT_STATUS_OK;
-}
-
-/*************************************************************
- Initialises a struct sam_passwd with sane values.
- ************************************************************/
-
-NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
-{
- NTSTATUS ret;
-
- if (!pwd) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pdb_fill_default_sam(sam_account);
-
- pdb_set_username(sam_account, pwd->pw_name, PDB_SET);
- pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);
-
- pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);
-
- pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);
- /* When we get a proper uid -> SID and SID -> uid allocation
- mechinism, we should call it here.
-
- We can't just set this to 0 or allow it only to be filled
- in when added to the backend, because the user's SID
- may already be in security descriptors etc.
-
- -- abartlet 11-May-02
- */
-
- ret = pdb_set_sam_sids(sam_account, pwd);
- if (!NT_STATUS_IS_OK(ret)) return ret;
-
- /* check if this is a user account or a machine account */
- if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
- {
- pdb_set_profile_path(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_path(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
-
- pdb_set_homedir(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_home(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
-
- pdb_set_dir_drive(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_drive(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
+ /* Now deal with the user SID. If we have a backend that can generate
+ RIDs, then do so. But sometimes the caller just wanted a structure
+ initialized and will fill in these fields later (such as from a
+ NET_USER_INFO_3 structure) */
+
+ if ( create && !pdb_rid_algorithm() ) {
+ uint32 user_rid;
+ DOM_SID user_sid;
- pdb_set_logon_script(sam_account,
- talloc_sub_specified((sam_account)->mem_ctx,
- lp_logon_script(),
- pwd->pw_name, global_myname(),
- pwd->pw_uid, pwd->pw_gid),
- PDB_DEFAULT);
- if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {
- DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else {
- if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {
- DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));
- return NT_STATUS_UNSUCCESSFUL;
+ if ( !pdb_new_rid( &user_rid ) ) {
+ DEBUG(3, ("Could not allocate a new RID\n"));
+ return NT_STATUS_ACCESS_DENIED;
}
- }
- return NT_STATUS_OK;
-}
-
-
-/*************************************************************
- Initialises a struct sam_passwd with sane values.
- ************************************************************/
-
-NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
-{
- NTSTATUS nt_status;
- if (!pwd) {
- new_sam_acct = NULL;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
- new_sam_acct = NULL;
- return nt_status;
- }
+ sid_copy( &user_sid, get_global_sam_sid() );
+ sid_append_rid( &user_sid, user_rid );
- if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
- pdb_free_sam(new_sam_acct);
- new_sam_acct = NULL;
- return nt_status;
+ if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
+ DEBUG(3, ("pdb_set_user_sid failed\n"));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ return NT_STATUS_OK;
}
- return NT_STATUS_OK;
-}
-
-
-/*************************************************************
- Initialises a SAM_ACCOUNT ready to add a new account, based
- on the UNIX user. Pass in a RID if you have one
- ************************************************************/
-
-NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,
- uint32 rid)
-{
- NTSTATUS nt_status = NT_STATUS_NO_MEMORY;
- struct passwd *pwd;
- BOOL ret;
-
- pwd = Get_Pwnam(username);
-
- if (!pwd)
- return NT_STATUS_NO_SUCH_USER;
+ /* generate a SID for the user with the RID algorithm */
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {
- *new_sam_acct = NULL;
- return nt_status;
- }
-
- /* see if we need to generate a new rid using the 2.2 algorithm */
- if ( rid == 0 && lp_enable_rid_algorithm() ) {
- DEBUG(10,("pdb_init_sam_new: no RID specified. Generating one via old algorithm\n"));
- rid = algorithmic_pdb_uid_to_user_rid(pwd->pw_uid);
+ urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
+
+ if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
+ return NT_STATUS_INTERNAL_ERROR;
}
- /* set the new SID */
-
- ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );
-
- return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);
+ return NT_STATUS_OK;
}
+/********************************************************************
+ Set the Unix user attributes
+********************************************************************/
-/**
- * Free the contets of the SAM_ACCOUNT, but not the structure.
- *
- * Also wipes the LM and NT hashes and plaintext password from
- * memory.
- *
- * @param user SAM_ACCOUNT to free members of.
- **/
-
-static void pdb_free_sam_contents(SAM_ACCOUNT *user)
+NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
{
-
- /* Kill off sensitive data. Free()ed by the
- talloc mechinism */
-
- data_blob_clear_free(&(user->private_u.lm_pw));
- data_blob_clear_free(&(user->private_u.nt_pw));
- if (user->private_u.plaintext_pw!=NULL)
- memset(user->private_u.plaintext_pw,'\0',strlen(user->private_u.plaintext_pw));
-
- if (user->private_u.backend_private_data && user->private_u.backend_private_data_free_fn) {
- user->private_u.backend_private_data_free_fn(&user->private_u.backend_private_data);
- }
+ return samu_set_unix_internal( user, pwd, False );
}
-
-/************************************************************
- Reset the SAM_ACCOUNT and free the NT/LM hashes.
- ***********************************************************/
-
-NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user)
+NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd)
{
- if (user == NULL) {
- DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to pdb_free_sam\n");
-#endif
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pdb_free_sam_contents(user);
-
- pdb_fill_default_sam(user);
-
- return NT_STATUS_OK;
-}
-
-
-/************************************************************
- Free the SAM_ACCOUNT and the member pointers.
- ***********************************************************/
-
-NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
-{
- if (*user == NULL) {
- DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to pdb_free_sam\n");
-#endif
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- pdb_free_sam_contents(*user);
-
- if ((*user)->free_fn) {
- (*user)->free_fn(user);
- }
-
- return NT_STATUS_OK;
+ return samu_set_unix_internal( user, pwd, True );
}
/**********************************************************
@@ -458,7 +253,7 @@ NTSTATUS pdb_free_sam(SAM_ACCOUNT **user)
null). length *MUST BE MORE THAN 2* !
**********************************************************/
-char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
+char *pdb_encode_acct_ctrl(uint32 acct_ctrl, size_t length)
{
static fstring acct_str;
@@ -494,9 +289,9 @@ char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
Decode the account control bits from a string.
**********************************************************/
-uint16 pdb_decode_acct_ctrl(const char *p)
+uint32 pdb_decode_acct_ctrl(const char *p)
{
- uint16 acct_ctrl = 0;
+ uint32 acct_ctrl = 0;
BOOL finished = False;
/*
@@ -536,7 +331,7 @@ uint16 pdb_decode_acct_ctrl(const char *p)
Routine to set 32 hex password characters from a 16 byte array.
**************************************************************/
-void pdb_sethexpwd(char *p, const unsigned char *pwd, uint16 acct_ctrl)
+void pdb_sethexpwd(char *p, const unsigned char *pwd, uint32 acct_ctrl)
{
if (pwd != NULL) {
int i;
@@ -634,6 +429,9 @@ BOOL pdb_gethexhours(const char *p, unsigned char *hours)
return (True);
}
+/********************************************************************
+********************************************************************/
+
int algorithmic_rid_base(void)
{
static int rid_offset = 0;
@@ -666,6 +464,11 @@ uid_t algorithmic_pdb_user_rid_to_uid(uint32 user_rid)
return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
}
+uid_t max_algorithmic_uid(void)
+{
+ return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
+}
+
/*******************************************************************
converts UNIX uid to an NT User RID.
********************************************************************/
@@ -686,6 +489,11 @@ gid_t pdb_group_rid_to_gid(uint32 group_rid)
return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
}
+gid_t max_algorithmic_gid(void)
+{
+ return pdb_group_rid_to_gid(0xffffffff);
+}
+
/*******************************************************************
converts NT Group RID to a UNIX uid.
@@ -704,7 +512,7 @@ uint32 pdb_gid_to_group_rid(gid_t gid)
Decides if a RID is a well known RID.
********************************************************************/
-static BOOL pdb_rid_is_well_known(uint32 rid)
+static BOOL rid_is_well_known(uint32 rid)
{
/* Not using rid_offset here, because this is the actual
NT fixed value (1000) */
@@ -718,7 +526,7 @@ static BOOL pdb_rid_is_well_known(uint32 rid)
BOOL algorithmic_pdb_rid_is_user(uint32 rid)
{
- if(pdb_rid_is_well_known(rid)) {
+ if ( rid_is_well_known(rid) ) {
/*
* The only well known user RIDs are DOMAIN_USER_RID_ADMIN
* and DOMAIN_USER_RID_GUEST.
@@ -732,215 +540,85 @@ BOOL algorithmic_pdb_rid_is_user(uint32 rid)
}
/*******************************************************************
- Look up a rid in the SAM we're responsible for (i.e. passdb)
+ Convert a name into a SID. Used in the lookup name rpc.
********************************************************************/
-BOOL lookup_global_sam_rid(uint32 rid, fstring name,
- enum SID_NAME_USE *psid_name_use)
+BOOL lookup_global_sam_name(const char *user, int flags, uint32_t *rid,
+ enum SID_NAME_USE *type)
{
- SAM_ACCOUNT *sam_account = NULL;
GROUP_MAP map;
BOOL ret;
- DOM_SID sid;
-
- *psid_name_use = SID_NAME_UNKNOWN;
- DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
- (unsigned int)rid));
-
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
-
- /* see if the passdb can help us with the name of the user */
- if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
- return False;
- }
-
- /* BEING ROOT BLLOCK */
- become_root();
- if (pdb_getsampwsid(sam_account, &sid)) {
- unbecome_root(); /* -----> EXIT BECOME_ROOT() */
- fstrcpy(name, pdb_get_username(sam_account));
- *psid_name_use = SID_NAME_USER;
-
- pdb_free_sam(&sam_account);
-
+ /* Windows treats "MACHINE\None" as a special name for
+ rid 513 on non-DCs. You cannot create a user or group
+ name "None" on Windows. You will get an error that
+ the group already exists. */
+
+ if ( strequal( user, "None" ) ) {
+ *rid = DOMAIN_GROUP_RID_USERS;
+ *type = SID_NAME_DOM_GRP;
+
return True;
}
- pdb_free_sam(&sam_account);
-
- ret = pdb_getgrsid(&map, sid);
- unbecome_root();
- /* END BECOME_ROOT BLOCK */
-
- if ( ret ) {
- if (map.gid!=(gid_t)-1) {
- DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
- "gid %u\n", map.nt_name,
- (unsigned int)map.gid));
- } else {
- DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
- "no unix gid. Returning name.\n",
- map.nt_name));
- }
- fstrcpy(name, map.nt_name);
- *psid_name_use = map.sid_name_use;
- return True;
- }
+ /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
+ * correctly in the case where foo also exists as a user. If the flag
+ * is set, don't look for users at all. */
- if (rid == DOMAIN_USER_RID_ADMIN) {
- *psid_name_use = SID_NAME_USER;
- fstrcpy(name, "Administrator");
- return True;
- }
+ if ((flags & LOOKUP_NAME_GROUP) == 0) {
+ struct samu *sam_account = NULL;
+ DOM_SID user_sid;
- if (algorithmic_pdb_rid_is_user(rid)) {
- uid_t uid;
- struct passwd *pw = NULL;
-
- DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
+ if ( !(sam_account = samu_new( NULL )) ) {
+ return False;
+ }
+
+ become_root();
+ ret = pdb_getsampwnam(sam_account, user);
+ unbecome_root();
- uid = algorithmic_pdb_user_rid_to_uid(rid);
- pw = sys_getpwuid( uid );
-
- DEBUG(5,("lookup_global_sam_rid: looking up uid %u %s\n",
- (unsigned int)uid, pw ? "succeeded" : "failed" ));
-
- if ( !pw )
- fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
- else
- fstrcpy( name, pw->pw_name );
-
- DEBUG(5,("lookup_global_sam_rid: found user %s for rid %u\n",
- name, (unsigned int)rid ));
-
- *psid_name_use = SID_NAME_USER;
-
- return ( pw != NULL );
- } else {
- gid_t gid;
- struct group *gr;
-
- DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
-
- gid = pdb_group_rid_to_gid(rid);
- gr = getgrgid(gid);
-
- DEBUG(5,("lookup_global_sam_rid: looking up gid %u %s\n",
- (unsigned int)gid, gr ? "succeeded" : "failed" ));
-
- if( !gr )
- fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
- else
- fstrcpy( name, gr->gr_name);
-
- DEBUG(5,("lookup_global_sam_rid: found group %s for rid %u\n",
- name, (unsigned int)rid ));
-
- /* assume algorithmic groups are domain global groups */
-
- *psid_name_use = SID_NAME_DOM_GRP;
+ if (ret) {
+ sid_copy(&user_sid, pdb_get_user_sid(sam_account));
+ }
- return ( gr != NULL );
- }
-}
-
-/*******************************************************************
- Convert a name into a SID. Used in the lookup name rpc.
- ********************************************************************/
+ TALLOC_FREE(sam_account);
-BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
-{
- DOM_SID local_sid;
- DOM_SID sid;
- fstring user;
- SAM_ACCOUNT *sam_account = NULL;
- struct group *grp;
- GROUP_MAP map;
+ if (ret) {
+ if (!sid_check_is_in_our_domain(&user_sid)) {
+ DEBUG(0, ("User %s with invalid SID %s in passdb\n",
+ user, sid_string_static(&user_sid)));
+ return False;
+ }
- *psid_name_use = SID_NAME_UNKNOWN;
+ sid_peek_rid(&user_sid, rid);
+ *type = SID_NAME_USER;
+ return True;
+ }
+ }
/*
- * user may be quoted a const string, and map_username and
- * friends can modify it. Make a modifiable copy. JRA.
+ * Maybe it is a group ?
*/
- fstrcpy(user, c_user);
-
- sid_copy(&local_sid, get_global_sam_sid());
-
- if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
- fstring sid_str;
- sid_copy( psid, &sid);
- sid_to_string(sid_str, &sid);
- DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
- (unsigned int)*psid_name_use ));
- return True;
- }
-
- (void)map_username(user);
+ become_root();
+ ret = pdb_getgrnam(&map, user);
+ unbecome_root();
- if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
+ if (!ret) {
return False;
}
-
- /* BEGIN ROOT BLOCK */
-
- become_root();
- if (pdb_getsampwnam(sam_account, user)) {
- unbecome_root();
- sid_copy(psid, pdb_get_user_sid(sam_account));
- *psid_name_use = SID_NAME_USER;
-
- pdb_free_sam(&sam_account);
- return True;
- }
-
- pdb_free_sam(&sam_account);
-
- /*
- * Maybe it was a group ?
- */
- /* check if it's a mapped group */
- if (pdb_getgrnam(&map, user)) {
- /* yes it's a mapped group */
- sid_copy(&local_sid, &map.sid);
- *psid_name_use = map.sid_name_use;
- } else {
- /* it's not a mapped group */
- grp = getgrnam(user);
- if(!grp) {
- unbecome_root(); /* ---> exit form block */
- return False;
- }
-
- /*
- *check if it's mapped, if it is reply it doesn't exist
- *
- * that's to prevent this case:
- *
- * unix group ug is mapped to nt group ng
- * someone does a lookup on ug
- * we must not reply as it doesn't "exist" anymore
- * for NT. For NT only ng exists.
- * JFM, 30/11/2001
- */
-
- if (pdb_getgrgid(&map, grp->gr_gid)){
- unbecome_root(); /* ---> exit form block */
- return False;
- }
-
- sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
- *psid_name_use = SID_NAME_ALIAS;
+ /* BUILTIN groups are looked up elsewhere */
+ if (!sid_check_is_in_our_domain(&map.sid)) {
+ DEBUG(10, ("Found group %s (%s) not in our domain -- "
+ "ignoring.", user,
+ sid_string_static(&map.sid)));
+ return False;
}
- unbecome_root();
- /* END ROOT BLOCK */
-
- sid_copy( psid, &local_sid);
+ /* yes it's a mapped group */
+ sid_peek_rid(&map.sid, rid);
+ *type = map.sid_name_use;
return True;
}
@@ -948,34 +626,67 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
Change a password entry in the local smbpasswd file.
*************************************************************/
-BOOL local_password_change(const char *user_name, int local_flags,
+NTSTATUS local_password_change(const char *user_name, int local_flags,
const char *new_passwd,
char *err_str, size_t err_str_len,
char *msg_str, size_t msg_str_len)
{
- SAM_ACCOUNT *sam_pass=NULL;
- uint16 other_acb;
+ struct samu *sam_pass=NULL;
+ uint32 other_acb;
+ NTSTATUS result;
*err_str = '\0';
*msg_str = '\0';
/* Get the smb passwd entry for this user */
- pdb_init_sam(&sam_pass);
+
+ if ( !(sam_pass = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
become_root();
if(!pdb_getsampwnam(sam_pass, user_name)) {
unbecome_root();
- pdb_free_sam(&sam_pass);
+ TALLOC_FREE(sam_pass);
if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
- /* Might not exist in /etc/passwd. Use rid algorithm here */
- if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
- slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s. Does this user exist in the UNIX password database ?\n", user_name);
- return False;
+ int tmp_debug = DEBUGLEVEL;
+ struct passwd *pwd;
+
+ /* Might not exist in /etc/passwd. */
+
+ if (tmp_debug < 1) {
+ DEBUGLEVEL = 1;
+ }
+
+ if ( !(pwd = getpwnam_alloc( NULL, user_name)) ) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ /* create the struct samu and initialize the basic Unix properties */
+
+ if ( !(sam_pass = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ result = samu_set_unix( sam_pass, pwd );
+
+ DEBUGLEVEL = tmp_debug;
+
+ TALLOC_FREE( pwd );
+
+ if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) {
+ return result;
+ }
+
+ if (!NT_STATUS_IS_OK(result)) {
+ slprintf(err_str, err_str_len-1, "Failed to " "initialize account for user %s: %s\n",
+ user_name, nt_errstr(result));
+ return result;
}
} else {
slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
- return False;
+ return NT_STATUS_NO_SUCH_USER;
}
} else {
unbecome_root();
@@ -988,20 +699,20 @@ BOOL local_password_change(const char *user_name, int local_flags,
if (local_flags & LOCAL_TRUST_ACCOUNT) {
if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
} else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
slprintf(err_str, err_str_len - 1, "Failed to set 'domain trust account' flags for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
} else {
if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
slprintf(err_str, err_str_len - 1, "Failed to set 'normal account' flags for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
}
@@ -1013,22 +724,22 @@ BOOL local_password_change(const char *user_name, int local_flags,
if (local_flags & LOCAL_DISABLE_USER) {
if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
slprintf(err_str, err_str_len-1, "Failed to set 'disabled' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
} else if (local_flags & LOCAL_ENABLE_USER) {
if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
}
if (local_flags & LOCAL_SET_NO_PASSWORD) {
if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
slprintf(err_str, err_str_len-1, "Failed to set 'no password required' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
} else if (local_flags & LOCAL_SET_PASSWORD) {
/*
@@ -1043,45 +754,46 @@ BOOL local_password_change(const char *user_name, int local_flags,
if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
slprintf(err_str, err_str_len-1, "Failed to unset 'disabled' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
}
if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
slprintf(err_str, err_str_len-1, "Failed to unset 'no password required' flag for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
slprintf(err_str, err_str_len-1, "Failed to set password for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
}
if (local_flags & LOCAL_ADD_USER) {
- if (pdb_add_sam_account(sam_pass)) {
+ if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return True;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_OK;
} else {
slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
} else if (local_flags & LOCAL_DELETE_USER) {
- if (!pdb_delete_sam_account(sam_pass)) {
+ if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_UNSUCCESSFUL;
}
slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
} else {
- if(!pdb_update_sam_account(sam_pass)) {
+ result = pdb_update_sam_account(sam_pass);
+ if(!NT_STATUS_IS_OK(result)) {
slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
- pdb_free_sam(&sam_pass);
- return False;
+ TALLOC_FREE(sam_pass);
+ return result;
}
if(local_flags & LOCAL_DISABLE_USER)
slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
@@ -1091,627 +803,20 @@ BOOL local_password_change(const char *user_name, int local_flags,
slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
}
- pdb_free_sam(&sam_pass);
- return True;
-}
-
-/****************************************************************************
- Convert a uid to SID - algorithmic.
-****************************************************************************/
-
-DOM_SID *algorithmic_uid_to_sid(DOM_SID *psid, uid_t uid)
-{
- if ( !lp_enable_rid_algorithm() )
- return NULL;
-
- DEBUG(8,("algorithmic_uid_to_sid: falling back to RID algorithm\n"));
- sid_copy( psid, get_global_sam_sid() );
- sid_append_rid( psid, algorithmic_pdb_uid_to_user_rid(uid) );
- DEBUG(10,("algorithmic_uid_to_sid: uid (%d) -> SID %s.\n",
- (unsigned int)uid, sid_string_static(psid) ));
-
- return psid;
-}
-
-/****************************************************************************
- Convert a uid to SID - locally.
-****************************************************************************/
-
-DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
-{
- SAM_ACCOUNT *sampw = NULL;
- struct passwd *unix_pw;
- BOOL ret;
-
- unix_pw = sys_getpwuid( uid );
-
- if ( !unix_pw ) {
- DEBUG(4,("local_uid_to_sid: host has no idea of uid %lu\n", (unsigned long)uid));
- return algorithmic_uid_to_sid( psid, uid);
- }
-
- if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
- DEBUG(0,("local_uid_to_sid: failed to allocate SAM_ACCOUNT object\n"));
- return NULL;
- }
-
- become_root();
- ret = pdb_getsampwnam( sampw, unix_pw->pw_name );
- unbecome_root();
-
- if ( ret )
- sid_copy( psid, pdb_get_user_sid(sampw) );
- else {
- DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
- unix_pw->pw_name, (unsigned long)uid));
-
- algorithmic_uid_to_sid( psid, uid);
- }
-
- pdb_free_sam(&sampw);
-
- DEBUG(10,("local_uid_to_sid: uid (%d) -> SID %s (%s).\n",
- (unsigned int)uid, sid_string_static(psid), unix_pw->pw_name));
-
- return psid;
-}
-
-/****************************************************************************
- Convert a SID to uid - locally.
-****************************************************************************/
-
-BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
-{
- SAM_ACCOUNT *sampw = NULL;
- struct passwd *unix_pw;
- const char *user_name;
-
- *name_type = SID_NAME_UNKNOWN;
-
- /*
- * We can only convert to a uid if this is our local
- * Domain SID (ie. we are the controling authority).
- */
- if (!sid_check_is_in_our_domain(psid) ) {
- DEBUG(5,("local_sid_to_uid: this SID (%s) is not from our domain\n", sid_string_static(psid)));
- return False;
- }
-
- /* lookup the user account */
-
- if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
- DEBUG(0,("local_sid_to_uid: Failed to allocate memory for SAM_ACCOUNT object\n"));
- return False;
- }
-
- become_root();
- if ( !pdb_getsampwsid(sampw, psid) ) {
- unbecome_root();
- pdb_free_sam(&sampw);
- DEBUG(8,("local_sid_to_uid: Could not find SID %s in passdb\n",
- sid_string_static(psid)));
- return False;
- }
- unbecome_root();
-
- user_name = pdb_get_username(sampw);
-
- unix_pw = sys_getpwnam( user_name );
-
- if ( !unix_pw ) {
- DEBUG(0,("local_sid_to_uid: %s found in passdb but getpwnam() return NULL!\n",
- user_name));
- pdb_free_sam( &sampw );
- return False;
- }
-
- *puid = unix_pw->pw_uid;
-
- DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_string_static(psid),
- (unsigned int)*puid, user_name ));
-
- *name_type = SID_NAME_USER;
- pdb_free_sam( &sampw );
- return True;
-}
-
-/****************************************************************************
- Convert a gid to SID - locally.
-****************************************************************************/
-
-DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
-{
- GROUP_MAP group;
- BOOL ret;
-
- /* we don't need to disable winbindd since the gid is stored in
- the GROUP_MAP object */
-
- /* done as root since ldap backend requires root to open a connection */
-
- become_root();
- ret = pdb_getgrgid( &group, gid );
- unbecome_root();
-
- if ( !ret ) {
-
- /* fallback to rid mapping if enabled */
-
- if ( lp_enable_rid_algorithm() ) {
- sid_copy(psid, get_global_sam_sid());
- sid_append_rid(psid, pdb_gid_to_group_rid(gid));
-
- DEBUG(10,("local_gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n",
- (unsigned int)gid, sid_string_static(psid)));
-
- return psid;
- }
- else
- return NULL;
- }
-
- sid_copy( psid, &group.sid );
-
- DEBUG(10,("local_gid_to_sid: gid (%d) -> SID %s.\n",
- (unsigned int)gid, sid_string_static(psid)));
-
- return psid;
-}
-
-/****************************************************************************
- Convert a SID to gid - locally.
-****************************************************************************/
-
-BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
-{
- uint32 rid;
- GROUP_MAP group;
- BOOL ret;
-
- *name_type = SID_NAME_UNKNOWN;
-
- /* This call can enumerate group mappings for foreign sids as well.
- So don't check for a match against our domain SID */
-
- /* we don't need to disable winbindd since the gid is stored in
- the GROUP_MAP object */
-
- become_root();
- ret = pdb_getgrsid(&group, *psid);
- unbecome_root();
-
- if ( !ret ) {
-
- /* Fallback to algorithmic rid mapping if enabled */
-
- if ( lp_enable_rid_algorithm() ) {
-
- if (!sid_check_is_in_our_domain(psid) ) {
- DEBUG(5,("local_sid_to_gid: RID algorithm only supported for our domain (%s is not)\n", sid_string_static(psid)));
- return False;
- }
-
- if (!sid_peek_rid(psid, &rid)) {
- DEBUG(10,("local_sid_to_gid: invalid SID!\n"));
- return False;
- }
-
- DEBUG(10,("local_sid_to_gid: Fall back to algorithmic mapping\n"));
-
- if (algorithmic_pdb_rid_is_user(rid)) {
- DEBUG(3, ("local_sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(psid)));
- return False;
- } else {
- *pgid = pdb_group_rid_to_gid(rid);
- DEBUG(10,("local_sid_to_gid: mapping: %s -> %u\n", sid_string_static(psid), (unsigned int)(*pgid)));
- return True;
- }
- }
-
- return False;
- }
-
- *pgid = group.gid;
- *name_type = group.sid_name_use;
-
- DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u)\n", sid_string_static(psid),
- (unsigned int)*pgid));
-
- return True;
-}
-
-/**********************************************************************
- Marshall/unmarshall SAM_ACCOUNT structs.
- *********************************************************************/
-
-#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
-#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
-#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
-
-/**********************************************************************
- Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
- *********************************************************************/
-
-BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
-{
- return(init_sam_from_buffer_v2(sampass, buf, buflen));
+ TALLOC_FREE(sam_pass);
+ return NT_STATUS_OK;
}
/**********************************************************************
- Intialize a BYTE buffer from a SAM_ACCOUNT struct
+ Marshall/unmarshall struct samu structs.
*********************************************************************/
-uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
-{
- return(init_buffer_from_sam_v2(buf, sampass, size_only));
-}
-
-
-BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
-{
-
- /* times are stored as 32bit integer
- take care on system with 64bit wide time_t
- --SSS */
- uint32 logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time;
- char *username = NULL;
- char *domain = NULL;
- char *nt_username = NULL;
- char *dir_drive = NULL;
- char *unknown_str = NULL;
- char *munged_dial = NULL;
- char *fullname = NULL;
- char *homedir = NULL;
- char *logon_script = NULL;
- char *profile_path = NULL;
- char *acct_desc = NULL;
- char *workstations = NULL;
- uint32 username_len, domain_len, nt_username_len,
- dir_drive_len, unknown_str_len, munged_dial_len,
- fullname_len, homedir_len, logon_script_len,
- profile_path_len, acct_desc_len, workstations_len;
-
- uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
- uint16 acct_ctrl, logon_divs;
- uint16 bad_password_count, logon_count;
- uint8 *hours = NULL;
- uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
- uint32 len = 0;
- uint32 lm_pw_len, nt_pw_len, hourslen;
- BOOL ret = True;
-
- if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
- return False;
- }
-
-/* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
-
- /* unpack the buffer into variables */
- len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
- &logon_time, /* d */
- &logoff_time, /* d */
- &kickoff_time, /* d */
- &pass_last_set_time, /* d */
- &pass_can_change_time, /* d */
- &pass_must_change_time, /* d */
- &username_len, &username, /* B */
- &domain_len, &domain, /* B */
- &nt_username_len, &nt_username, /* B */
- &fullname_len, &fullname, /* B */
- &homedir_len, &homedir, /* B */
- &dir_drive_len, &dir_drive, /* B */
- &logon_script_len, &logon_script, /* B */
- &profile_path_len, &profile_path, /* B */
- &acct_desc_len, &acct_desc, /* B */
- &workstations_len, &workstations, /* B */
- &unknown_str_len, &unknown_str, /* B */
- &munged_dial_len, &munged_dial, /* B */
- &user_rid, /* d */
- &group_rid, /* d */
- &lm_pw_len, &lm_pw_ptr, /* B */
- &nt_pw_len, &nt_pw_ptr, /* B */
- &acct_ctrl, /* w */
- &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
- &logon_divs, /* w */
- &hours_len, /* d */
- &hourslen, &hours, /* B */
- &bad_password_count, /* w */
- &logon_count, /* w */
- &unknown_6); /* d */
-
- if (len == (uint32) -1) {
- ret = False;
- goto done;
- }
-
- pdb_set_logon_time(sampass, logon_time, PDB_SET);
- pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
- pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
- pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
- pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
- pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
-
- pdb_set_username(sampass, username, PDB_SET);
- pdb_set_domain(sampass, domain, PDB_SET);
- pdb_set_nt_username(sampass, nt_username, PDB_SET);
- pdb_set_fullname(sampass, fullname, PDB_SET);
-
- if (homedir) {
- pdb_set_homedir(sampass, homedir, PDB_SET);
- }
- else {
- pdb_set_homedir(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
- PDB_DEFAULT);
- }
-
- if (dir_drive)
- pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
- else {
- pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT);
- }
-
- if (logon_script)
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
- else {
- pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
- PDB_DEFAULT);
- }
-
- if (profile_path) {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
- } else {
- pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
- PDB_DEFAULT);
- }
-
- pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
- pdb_set_workstations(sampass, workstations, PDB_SET);
- pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
-
- if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
- if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
-
- if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
- if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
-
- pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
- pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
- pdb_set_hours_len(sampass, hours_len, PDB_SET);
- pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
- pdb_set_logon_count(sampass, logon_count, PDB_SET);
- pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
- pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
- pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
- pdb_set_hours(sampass, hours, PDB_SET);
-
-done:
-
- SAFE_FREE(username);
- SAFE_FREE(domain);
- SAFE_FREE(nt_username);
- SAFE_FREE(fullname);
- SAFE_FREE(homedir);
- SAFE_FREE(dir_drive);
- SAFE_FREE(logon_script);
- SAFE_FREE(profile_path);
- SAFE_FREE(acct_desc);
- SAFE_FREE(workstations);
- SAFE_FREE(munged_dial);
- SAFE_FREE(unknown_str);
- SAFE_FREE(lm_pw_ptr);
- SAFE_FREE(nt_pw_ptr);
- SAFE_FREE(hours);
-
- return ret;
-}
-
-BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
-{
-
- /* times are stored as 32bit integer
- take care on system with 64bit wide time_t
- --SSS */
- uint32 logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time;
- char *username = NULL;
- char *domain = NULL;
- char *nt_username = NULL;
- char *dir_drive = NULL;
- char *unknown_str = NULL;
- char *munged_dial = NULL;
- char *fullname = NULL;
- char *homedir = NULL;
- char *logon_script = NULL;
- char *profile_path = NULL;
- char *acct_desc = NULL;
- char *workstations = NULL;
- uint32 username_len, domain_len, nt_username_len,
- dir_drive_len, unknown_str_len, munged_dial_len,
- fullname_len, homedir_len, logon_script_len,
- profile_path_len, acct_desc_len, workstations_len;
-
- uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
- uint16 acct_ctrl, logon_divs;
- uint16 bad_password_count, logon_count;
- uint8 *hours = NULL;
- uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
- uint32 len = 0;
- uint32 lm_pw_len, nt_pw_len, hourslen;
- BOOL ret = True;
-
- if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
- return False;
- }
-
-/* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
-
- /* unpack the buffer into variables */
- len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
- &logon_time, /* d */
- &logoff_time, /* d */
- &kickoff_time, /* d */
- /* Change from V0 is addition of bad_password_time field. */
- &bad_password_time, /* d */
- &pass_last_set_time, /* d */
- &pass_can_change_time, /* d */
- &pass_must_change_time, /* d */
- &username_len, &username, /* B */
- &domain_len, &domain, /* B */
- &nt_username_len, &nt_username, /* B */
- &fullname_len, &fullname, /* B */
- &homedir_len, &homedir, /* B */
- &dir_drive_len, &dir_drive, /* B */
- &logon_script_len, &logon_script, /* B */
- &profile_path_len, &profile_path, /* B */
- &acct_desc_len, &acct_desc, /* B */
- &workstations_len, &workstations, /* B */
- &unknown_str_len, &unknown_str, /* B */
- &munged_dial_len, &munged_dial, /* B */
- &user_rid, /* d */
- &group_rid, /* d */
- &lm_pw_len, &lm_pw_ptr, /* B */
- &nt_pw_len, &nt_pw_ptr, /* B */
- &acct_ctrl, /* w */
- &remove_me, /* d */
- &logon_divs, /* w */
- &hours_len, /* d */
- &hourslen, &hours, /* B */
- &bad_password_count, /* w */
- &logon_count, /* w */
- &unknown_6); /* d */
-
- if (len == (uint32) -1) {
- ret = False;
- goto done;
- }
-
- pdb_set_logon_time(sampass, logon_time, PDB_SET);
- pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
- pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
-
- /* Change from V0 is addition of bad_password_time field. */
- pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
- pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
- pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
- pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
-
- pdb_set_username(sampass, username, PDB_SET);
- pdb_set_domain(sampass, domain, PDB_SET);
- pdb_set_nt_username(sampass, nt_username, PDB_SET);
- pdb_set_fullname(sampass, fullname, PDB_SET);
-
- if (homedir) {
- pdb_set_homedir(sampass, homedir, PDB_SET);
- }
- else {
- pdb_set_homedir(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
- PDB_DEFAULT);
- }
-
- if (dir_drive)
- pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
- else {
- pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT);
- }
-
- if (logon_script)
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
- else {
- pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
- PDB_DEFAULT);
- }
-
- if (profile_path) {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
- } else {
- pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
- PDB_DEFAULT);
- }
-
- pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
- pdb_set_workstations(sampass, workstations, PDB_SET);
- pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
-
- if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
- if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
-
- if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
- if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
- ret = False;
- goto done;
- }
- }
-
- pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
-
- pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
- pdb_set_hours_len(sampass, hours_len, PDB_SET);
- pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
- pdb_set_logon_count(sampass, logon_count, PDB_SET);
- pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
- pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
- pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
- pdb_set_hours(sampass, hours, PDB_SET);
-
-done:
-
- SAFE_FREE(username);
- SAFE_FREE(domain);
- SAFE_FREE(nt_username);
- SAFE_FREE(fullname);
- SAFE_FREE(homedir);
- SAFE_FREE(dir_drive);
- SAFE_FREE(logon_script);
- SAFE_FREE(profile_path);
- SAFE_FREE(acct_desc);
- SAFE_FREE(workstations);
- SAFE_FREE(munged_dial);
- SAFE_FREE(unknown_str);
- SAFE_FREE(lm_pw_ptr);
- SAFE_FREE(nt_pw_ptr);
- SAFE_FREE(hours);
-
- return ret;
-}
+#define TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
+/*********************************************************************
+*********************************************************************/
-BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
{
/* times are stored as 32bit integer
@@ -1741,8 +846,8 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
- uint32 user_rid, group_rid, hours_len, unknown_6;
- uint16 acct_ctrl, logon_divs;
+ uint32 user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
+ uint16 logon_divs;
uint16 bad_password_count, logon_count;
uint8 *hours = NULL;
uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
@@ -1754,14 +859,14 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
BOOL expand_explicit = lp_passdb_expand_explicit();
if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
+ DEBUG(0, ("init_sam_from_buffer_v3: NULL parameters found!\n"));
return False;
}
-/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
+/* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
/* unpack the buffer into variables */
- len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V3,
&logon_time, /* d */
&logoff_time, /* d */
&kickoff_time, /* d */
@@ -1787,7 +892,8 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
&nt_pw_len, &nt_pw_ptr, /* B */
/* Change from V1 is addition of password history field. */
&nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
- &acct_ctrl, /* w */
+ /* Change from V2 is the uint32 acb_mask */
+ &acct_ctrl, /* d */
/* Also "remove_me" field was removed. */
&logon_divs, /* w */
&hours_len, /* d */
@@ -1824,7 +930,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
else {
pdb_set_homedir(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, lp_logon_home()),
PDB_DEFAULT);
}
@@ -1843,7 +949,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
else {
pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, lp_logon_script()),
PDB_DEFAULT);
}
@@ -1857,7 +963,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
else {
pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
+ talloc_sub_basic(sampass, username, lp_logon_path()),
PDB_DEFAULT);
}
@@ -1879,7 +985,6 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
}
- /* Change from V1 is addition of password history field. */
pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
@@ -1909,11 +1014,11 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
pdb_set_hours_len(sampass, hours_len, PDB_SET);
pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
pdb_set_logon_count(sampass, logon_count, PDB_SET);
pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
+ /* Change from V2 is the uint32 acct_ctrl */
pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
pdb_set_hours(sampass, hours, PDB_SET);
@@ -1940,7 +1045,10 @@ done:
return ret;
}
-uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
+/*********************************************************************
+*********************************************************************/
+
+uint32 init_buffer_from_sam_v3 (uint8 **buf, struct samu *sampass, BOOL size_only)
{
size_t len, buflen;
@@ -1982,9 +1090,9 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
uint32 nt_pw_hist_len;
uint32 pwHistLen = 0;
- /* do we have a valid SAM_ACCOUNT pointer? */
+ /* do we have a valid struct samu pointer? */
if (sampass == NULL) {
- DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
+ DEBUG(0, ("init_buffer_from_sam: struct samu is NULL!\n"));
return -1;
}
@@ -2120,10 +1228,10 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
munged_dial_len = 0;
}
-/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
+/* TDB_FORMAT_STRING_V3 "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
/* one time to get the size needed */
- len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
+ len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V3,
logon_time, /* d */
logoff_time, /* d */
kickoff_time, /* d */
@@ -2148,7 +1256,7 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
lm_pw_len, lm_pw, /* B */
nt_pw_len, nt_pw, /* B */
nt_pw_hist_len, nt_pw_hist, /* B */
- pdb_get_acct_ctrl(sampass), /* w */
+ pdb_get_acct_ctrl(sampass), /* d */
pdb_get_logon_divs(sampass), /* w */
pdb_get_hours_len(sampass), /* d */
MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
@@ -2162,12 +1270,12 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
/* malloc the space needed */
if ( (*buf=(uint8*)SMB_MALLOC(len)) == NULL) {
- DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
+ DEBUG(0,("init_buffer_from_sam_v3: Unable to malloc() memory for buffer!\n"));
return (-1);
}
/* now for the real call to tdb_pack() */
- buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
+ buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V3,
logon_time, /* d */
logoff_time, /* d */
kickoff_time, /* d */
@@ -2192,7 +1300,7 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
lm_pw_len, lm_pw, /* B */
nt_pw_len, nt_pw, /* B */
nt_pw_hist_len, nt_pw_hist, /* B */
- pdb_get_acct_ctrl(sampass), /* w */
+ pdb_get_acct_ctrl(sampass), /* d */
pdb_get_logon_divs(sampass), /* w */
pdb_get_hours_len(sampass), /* d */
MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
@@ -2202,7 +1310,7 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
/* check to make sure we got it correct */
if (buflen != len) {
- DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
+ DEBUG(0, ("init_buffer_from_sam_v3: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
(unsigned long)buflen, (unsigned long)len));
/* error */
SAFE_FREE (*buf);
@@ -2212,78 +1320,40 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
return (buflen);
}
-BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
+
+/*********************************************************************
+*********************************************************************/
+
+BOOL pdb_copy_sam_account(struct samu *dst, struct samu *src )
{
BOOL result;
uint8 *buf;
int len;
- if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
+ if ( !dst )
return False;
- len = init_buffer_from_sam_v2(&buf, src, False);
+ len = init_buffer_from_sam_v3(&buf, src, False);
if (len == -1)
return False;
- result = init_sam_from_buffer_v2(*dst, buf, len);
- (*dst)->methods = src->methods;
+ result = init_sam_from_buffer_v3( dst, buf, len );
+ dst->methods = src->methods;
+
+ if ( src->unix_pw )
+ dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
free(buf);
return result;
}
-/**********************************************************************
-**********************************************************************/
-
-static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
-{
- uid_t u_low, u_high;
- gid_t g_low, g_high;
-
- if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
- return False;
- }
-
- *low = (u_low < g_low) ? u_low : g_low;
- *high = (u_high < g_high) ? u_high : g_high;
-
- return True;
-}
-
-/******************************************************************
- Get the the non-algorithmic RID range if idmap range are defined
-******************************************************************/
-
-BOOL get_free_rid_range(uint32 *low, uint32 *high)
-{
- uint32 id_low, id_high;
-
- if (!lp_enable_rid_algorithm()) {
- *low = BASE_RID;
- *high = (uint32)-1;
- }
-
- if (!get_free_ugid_range(&id_low, &id_high)) {
- return False;
- }
-
- *low = algorithmic_pdb_uid_to_user_rid(id_low);
- if (algorithmic_pdb_user_rid_to_uid((uint32)-1) < id_high) {
- *high = (uint32)-1;
- } else {
- *high = algorithmic_pdb_uid_to_user_rid(id_high);
- }
-
- return True;
-}
-
/*********************************************************************
Update the bad password count checking the AP_RESET_COUNT_TIME
*********************************************************************/
-BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
+BOOL pdb_update_bad_password_count(struct samu *sampass, BOOL *updated)
{
time_t LastBadPassword;
uint16 BadPasswordCount;
@@ -2326,7 +1396,7 @@ BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
*********************************************************************/
-BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
+BOOL pdb_update_autolock_flag(struct samu *sampass, BOOL *updated)
{
uint32 duration;
time_t LastBadPassword;
@@ -2379,7 +1449,7 @@ bad password time. Leaving locked out.\n",
Increment the bad_password_count
*********************************************************************/
-BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
+BOOL pdb_increment_bad_password_count(struct samu *sampass)
{
uint32 account_policy_lockout;
BOOL autolock_updated = False, badpw_updated = False;
diff --git a/source/passdb/pdb_compat.c b/source/passdb/pdb_compat.c
index abd572a7c14..788663f27a4 100644
--- a/source/passdb/pdb_compat.c
+++ b/source/passdb/pdb_compat.c
@@ -1,6 +1,6 @@
/*
Unix SMB/CIFS implementation.
- SAM_ACCOUNT access routines
+ struct samu access routines
Copyright (C) Jeremy Allison 1996-2001
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Gerald (Jerry) Carter 2000-2001
@@ -27,7 +27,7 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
-uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
+uint32 pdb_get_user_rid (const struct samu *sampass)
{
uint32 u_rid;
@@ -38,7 +38,7 @@ uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
return (0);
}
-uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
+uint32 pdb_get_group_rid (struct samu *sampass)
{
uint32 g_rid;
@@ -48,7 +48,7 @@ uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
return (0);
}
-BOOL pdb_set_user_sid_from_rid (SAM_ACCOUNT *sampass, uint32 rid, enum pdb_value_state flag)
+BOOL pdb_set_user_sid_from_rid (struct samu *sampass, uint32 rid, enum pdb_value_state flag)
{
DOM_SID u_sid;
const DOM_SID *global_sam_sid;
@@ -75,7 +75,7 @@ BOOL pdb_set_user_sid_from_rid (SAM_ACCOUNT *sampass, uint32 rid, enum pdb_value
return True;
}
-BOOL pdb_set_group_sid_from_rid (SAM_ACCOUNT *sampass, uint32 grid, enum pdb_value_state flag)
+BOOL pdb_set_group_sid_from_rid (struct samu *sampass, uint32 grid, enum pdb_value_state flag)
{
DOM_SID g_sid;
const DOM_SID *global_sam_sid;
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index 783e9e23fa3..5cb72e7f863 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -1,6 +1,6 @@
/*
Unix SMB/CIFS implementation.
- SAM_ACCOUNT access routines
+ struct samu access routines
Copyright (C) Jeremy Allison 1996-2001
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Gerald (Jerry) Carter 2000-2001
@@ -37,126 +37,126 @@
#define PDB_NOT_QUITE_NULL ""
/*********************************************************************
- Collection of get...() functions for SAM_ACCOUNT.
+ Collection of get...() functions for struct samu.
********************************************************************/
-uint16 pdb_get_acct_ctrl (const SAM_ACCOUNT *sampass)
+uint32 pdb_get_acct_ctrl (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.acct_ctrl);
+ return (sampass->acct_ctrl);
else
return (ACB_DISABLED);
}
-time_t pdb_get_logon_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_logon_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.logon_time);
+ return (sampass->logon_time);
else
return (0);
}
-time_t pdb_get_logoff_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_logoff_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.logoff_time);
+ return (sampass->logoff_time);
else
return (-1);
}
-time_t pdb_get_kickoff_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_kickoff_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.kickoff_time);
+ return (sampass->kickoff_time);
else
return (-1);
}
-time_t pdb_get_bad_password_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_bad_password_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.bad_password_time);
+ return (sampass->bad_password_time);
else
return (-1);
}
-time_t pdb_get_pass_last_set_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_pass_last_set_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.pass_last_set_time);
+ return (sampass->pass_last_set_time);
else
return (-1);
}
-time_t pdb_get_pass_can_change_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_pass_can_change_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.pass_can_change_time);
+ return (sampass->pass_can_change_time);
else
return (-1);
}
-time_t pdb_get_pass_must_change_time (const SAM_ACCOUNT *sampass)
+time_t pdb_get_pass_must_change_time (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.pass_must_change_time);
+ return (sampass->pass_must_change_time);
else
return (-1);
}
-uint16 pdb_get_logon_divs (const SAM_ACCOUNT *sampass)
+uint16 pdb_get_logon_divs (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.logon_divs);
+ return (sampass->logon_divs);
else
return (-1);
}
-uint32 pdb_get_hours_len (const SAM_ACCOUNT *sampass)
+uint32 pdb_get_hours_len (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.hours_len);
+ return (sampass->hours_len);
else
return (-1);
}
-const uint8* pdb_get_hours (const SAM_ACCOUNT *sampass)
+const uint8* pdb_get_hours (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.hours);
+ return (sampass->hours);
else
return (NULL);
}
-const uint8* pdb_get_nt_passwd (const SAM_ACCOUNT *sampass)
+const uint8* pdb_get_nt_passwd (const struct samu *sampass)
{
if (sampass) {
- SMB_ASSERT((!sampass->private_u.nt_pw.data)
- || sampass->private_u.nt_pw.length == NT_HASH_LEN);
- return ((uint8*)sampass->private_u.nt_pw.data);
+ SMB_ASSERT((!sampass->nt_pw.data)
+ || sampass->nt_pw.length == NT_HASH_LEN);
+ return ((uint8*)sampass->nt_pw.data);
}
else
return (NULL);
}
-const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
+const uint8* pdb_get_lanman_passwd (const struct samu *sampass)
{
if (sampass) {
- SMB_ASSERT((!sampass->private_u.lm_pw.data)
- || sampass->private_u.lm_pw.length == LM_HASH_LEN);
- return ((uint8*)sampass->private_u.lm_pw.data);
+ SMB_ASSERT((!sampass->lm_pw.data)
+ || sampass->lm_pw.length == LM_HASH_LEN);
+ return ((uint8*)sampass->lm_pw.data);
}
else
return (NULL);
}
-const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_hist_len)
+const uint8* pdb_get_pw_history (const struct samu *sampass, uint32 *current_hist_len)
{
if (sampass) {
- SMB_ASSERT((!sampass->private_u.nt_pw_his.data)
- || ((sampass->private_u.nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
- *current_hist_len = sampass->private_u.nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
- return ((uint8*)sampass->private_u.nt_pw_his.data);
+ SMB_ASSERT((!sampass->nt_pw_his.data)
+ || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
+ *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
+ return ((uint8*)sampass->nt_pw_his.data);
} else {
*current_hist_len = 0;
return (NULL);
@@ -169,49 +169,114 @@ const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_his
Used to pass the plaintext to passdb backends that might
want to store more than just the NTLM hashes.
*/
-const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass)
+const char* pdb_get_plaintext_passwd (const struct samu *sampass)
{
if (sampass) {
- return (sampass->private_u.plaintext_pw);
+ return (sampass->plaintext_pw);
}
else
return (NULL);
}
-const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass)
+const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
{
if (sampass)
- return &sampass->private_u.user_sid;
- else
- return (NULL);
+ return &sampass->user_sid;
+
+ return NULL;
}
-const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass)
+const DOM_SID *pdb_get_group_sid(struct samu *sampass)
{
- if (sampass)
- return &sampass->private_u.group_sid;
- else
- return (NULL);
+ DOM_SID *gsid;
+ struct passwd *pwd;
+
+ /* sanity check */
+
+ if ( !sampass ) {
+ return NULL;
+ }
+
+ /* Return the cached group SID if we have that */
+
+ if ( sampass->group_sid ) {
+ return sampass->group_sid;
+ }
+
+ /* generate the group SID from the user's primary Unix group */
+
+ if ( !(gsid = TALLOC_P( sampass, DOM_SID )) ) {
+ return NULL;
+ }
+
+ /* No algorithmic mapping, meaning that we have to figure out the
+ primary group SID according to group mapping and the user SID must
+ be a newly allocated one. We rely on the user's Unix primary gid.
+ We have no choice but to fail if we can't find it. */
+
+ if ( sampass->unix_pw )
+ pwd = sampass->unix_pw;
+ else
+ pwd = getpwnam_alloc( sampass, pdb_get_username(sampass) );
+
+ if ( !pwd ) {
+ DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
+ return NULL;
+ }
+
+ if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
+ enum SID_NAME_USE type = SID_NAME_UNKNOWN;
+ TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
+ BOOL lookup_ret;
+
+ if (!mem_ctx) {
+ return NULL;
+ }
+
+ /* Now check that it's actually a domain group and not something else */
+
+ lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
+
+ TALLOC_FREE( mem_ctx );
+
+ if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
+ sampass->group_sid = gsid;
+ return sampass->group_sid;
+ }
+
+ DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n",
+ pwd->pw_name, sid_type_lookup(type)));
+ }
+
+ /* Just set it to the 'Domain Users' RID of 512 which will
+ always resolve to a name */
+
+ sid_copy( gsid, get_global_sam_sid() );
+ sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
+
+ sampass->group_sid = gsid;
+
+ return sampass->group_sid;
}
/**
- * Get flags showing what is initalised in the SAM_ACCOUNT
- * @param sampass the SAM_ACCOUNT in question
+ * Get flags showing what is initalised in the struct samu
+ * @param sampass the struct samu in question
* @return the flags indicating the members initialised in the struct.
**/
-enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_elements element)
+enum pdb_value_state pdb_get_init_flags (const struct samu *sampass, enum pdb_elements element)
{
enum pdb_value_state ret = PDB_DEFAULT;
- if (!sampass || !sampass->private_u.change_flags || !sampass->private_u.set_flags)
+ if (!sampass || !sampass->change_flags || !sampass->set_flags)
return ret;
- if (bitmap_query(sampass->private_u.set_flags, element)) {
+ if (bitmap_query(sampass->set_flags, element)) {
DEBUG(11, ("element %d: SET\n", element));
ret = PDB_SET;
}
- if (bitmap_query(sampass->private_u.change_flags, element)) {
+ if (bitmap_query(sampass->change_flags, element)) {
DEBUG(11, ("element %d: CHANGED\n", element));
ret = PDB_CHANGED;
}
@@ -223,270 +288,270 @@ enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_el
return ret;
}
-const char* pdb_get_username (const SAM_ACCOUNT *sampass)
+const char* pdb_get_username (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.username);
+ return (sampass->username);
else
return (NULL);
}
-const char* pdb_get_domain (const SAM_ACCOUNT *sampass)
+const char* pdb_get_domain (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.domain);
+ return (sampass->domain);
else
return (NULL);
}
-const char* pdb_get_nt_username (const SAM_ACCOUNT *sampass)
+const char* pdb_get_nt_username (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.nt_username);
+ return (sampass->nt_username);
else
return (NULL);
}
-const char* pdb_get_fullname (const SAM_ACCOUNT *sampass)
+const char* pdb_get_fullname (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.full_name);
+ return (sampass->full_name);
else
return (NULL);
}
-const char* pdb_get_homedir (const SAM_ACCOUNT *sampass)
+const char* pdb_get_homedir (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.home_dir);
+ return (sampass->home_dir);
else
return (NULL);
}
-const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
+const char* pdb_get_unix_homedir (const struct samu *sampass)
{
- if (sampass)
- return (sampass->private_u.unix_home_dir);
- else
- return (NULL);
+ if ( sampass && sampass->unix_pw )
+ return ( sampass->unix_pw->pw_dir );
+
+ return (NULL);
}
-const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
+const char* pdb_get_dir_drive (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.dir_drive);
+ return (sampass->dir_drive);
else
return (NULL);
}
-const char* pdb_get_logon_script (const SAM_ACCOUNT *sampass)
+const char* pdb_get_logon_script (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.logon_script);
+ return (sampass->logon_script);
else
return (NULL);
}
-const char* pdb_get_profile_path (const SAM_ACCOUNT *sampass)
+const char* pdb_get_profile_path (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.profile_path);
+ return (sampass->profile_path);
else
return (NULL);
}
-const char* pdb_get_acct_desc (const SAM_ACCOUNT *sampass)
+const char* pdb_get_acct_desc (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.acct_desc);
+ return (sampass->acct_desc);
else
return (NULL);
}
-const char* pdb_get_workstations (const SAM_ACCOUNT *sampass)
+const char* pdb_get_workstations (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.workstations);
+ return (sampass->workstations);
else
return (NULL);
}
-const char* pdb_get_unknown_str (const SAM_ACCOUNT *sampass)
+const char* pdb_get_unknown_str (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.unknown_str);
+ return (sampass->unknown_str);
else
return (NULL);
}
-const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass)
+const char* pdb_get_munged_dial (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.munged_dial);
+ return (sampass->munged_dial);
else
return (NULL);
}
-uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass)
+uint16 pdb_get_bad_password_count(const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.bad_password_count);
+ return (sampass->bad_password_count);
else
return 0;
}
-uint16 pdb_get_logon_count(const SAM_ACCOUNT *sampass)
+uint16 pdb_get_logon_count(const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.logon_count);
+ return (sampass->logon_count);
else
return 0;
}
-uint32 pdb_get_unknown_6 (const SAM_ACCOUNT *sampass)
+uint32 pdb_get_unknown_6 (const struct samu *sampass)
{
if (sampass)
- return (sampass->private_u.unknown_6);
+ return (sampass->unknown_6);
else
return (-1);
}
-void *pdb_get_backend_private_data (const SAM_ACCOUNT *sampass, const struct pdb_methods *my_methods)
+void *pdb_get_backend_private_data (const struct samu *sampass, const struct pdb_methods *my_methods)
{
- if (sampass && my_methods == sampass->private_u.backend_private_methods)
- return sampass->private_u.backend_private_data;
+ if (sampass && my_methods == sampass->backend_private_methods)
+ return sampass->backend_private_data;
else
return NULL;
}
/*********************************************************************
- Collection of set...() functions for SAM_ACCOUNT.
+ Collection of set...() functions for struct samu.
********************************************************************/
-BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 acct_ctrl, enum pdb_value_state flag)
+BOOL pdb_set_acct_ctrl (struct samu *sampass, uint32 acct_ctrl, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.acct_ctrl = acct_ctrl;
+ sampass->acct_ctrl = acct_ctrl;
return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
}
-BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+BOOL pdb_set_logon_time (struct samu *sampass, time_t mytime, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.logon_time = mytime;
+ sampass->logon_time = mytime;
return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
}
-BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+BOOL pdb_set_logoff_time (struct samu *sampass, time_t mytime, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.logoff_time = mytime;
+ sampass->logoff_time = mytime;
return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
}
-BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+BOOL pdb_set_kickoff_time (struct samu *sampass, time_t mytime, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.kickoff_time = mytime;
+ sampass->kickoff_time = mytime;
return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
}
-BOOL pdb_set_bad_password_time (SAM_ACCOUNT *sampass, time_t mytime,
+BOOL pdb_set_bad_password_time (struct samu *sampass, time_t mytime,
enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.bad_password_time = mytime;
+ sampass->bad_password_time = mytime;
return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
}
-BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+BOOL pdb_set_pass_can_change_time (struct samu *sampass, time_t mytime, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.pass_can_change_time = mytime;
+ sampass->pass_can_change_time = mytime;
return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
}
-BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+BOOL pdb_set_pass_must_change_time (struct samu *sampass, time_t mytime, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.pass_must_change_time = mytime;
+ sampass->pass_must_change_time = mytime;
return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
}
-BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime, enum pdb_value_state flag)
+BOOL pdb_set_pass_last_set_time (struct samu *sampass, time_t mytime, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.pass_last_set_time = mytime;
+ sampass->pass_last_set_time = mytime;
return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
}
-BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len, enum pdb_value_state flag)
+BOOL pdb_set_hours_len (struct samu *sampass, uint32 len, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.hours_len = len;
+ sampass->hours_len = len;
return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
}
-BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours, enum pdb_value_state flag)
+BOOL pdb_set_logon_divs (struct samu *sampass, uint16 hours, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.logon_divs = hours;
+ sampass->logon_divs = hours;
return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
}
/**
- * Set flags showing what is initalised in the SAM_ACCOUNT
- * @param sampass the SAM_ACCOUNT in question
+ * Set flags showing what is initalised in the struct samu
+ * @param sampass the struct samu in question
* @param flag The *new* flag to be set. Old flags preserved
* this flag is only added.
**/
-BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
+BOOL pdb_set_init_flags (struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
{
- if (!sampass || !sampass->mem_ctx)
+ if (!sampass || !sampass)
return False;
- if (!sampass->private_u.set_flags) {
- if ((sampass->private_u.set_flags =
- bitmap_talloc(sampass->mem_ctx,
+ if (!sampass->set_flags) {
+ if ((sampass->set_flags =
+ bitmap_talloc(sampass,
PDB_COUNT))==NULL) {
DEBUG(0,("bitmap_talloc failed\n"));
return False;
}
}
- if (!sampass->private_u.change_flags) {
- if ((sampass->private_u.change_flags =
- bitmap_talloc(sampass->mem_ctx,
+ if (!sampass->change_flags) {
+ if ((sampass->change_flags =
+ bitmap_talloc(sampass,
PDB_COUNT))==NULL) {
DEBUG(0,("bitmap_talloc failed\n"));
return False;
@@ -495,22 +560,22 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p
switch(value_flag) {
case PDB_CHANGED:
- if (!bitmap_set(sampass->private_u.change_flags, element)) {
+ if (!bitmap_set(sampass->change_flags, element)) {
DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
return False;
}
- if (!bitmap_set(sampass->private_u.set_flags, element)) {
+ if (!bitmap_set(sampass->set_flags, element)) {
DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
return False;
}
DEBUG(11, ("element %d -> now CHANGED\n", element));
break;
case PDB_SET:
- if (!bitmap_clear(sampass->private_u.change_flags, element)) {
+ if (!bitmap_clear(sampass->change_flags, element)) {
DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
return False;
}
- if (!bitmap_set(sampass->private_u.set_flags, element)) {
+ if (!bitmap_set(sampass->set_flags, element)) {
DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
return False;
}
@@ -518,11 +583,11 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p
break;
case PDB_DEFAULT:
default:
- if (!bitmap_clear(sampass->private_u.change_flags, element)) {
+ if (!bitmap_clear(sampass->change_flags, element)) {
DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
return False;
}
- if (!bitmap_clear(sampass->private_u.set_flags, element)) {
+ if (!bitmap_clear(sampass->set_flags, element)) {
DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
return False;
}
@@ -533,20 +598,20 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p
return True;
}
-BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
+BOOL pdb_set_user_sid (struct samu *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
{
if (!sampass || !u_sid)
return False;
- sid_copy(&sampass->private_u.user_sid, u_sid);
+ sid_copy(&sampass->user_sid, u_sid);
DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
- sid_string_static(&sampass->private_u.user_sid)));
+ sid_string_static(&sampass->user_sid)));
return pdb_set_init_flags(sampass, PDB_USERSID, flag);
}
-BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb_value_state flag)
+BOOL pdb_set_user_sid_from_string (struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
{
DOM_SID new_sid;
@@ -562,69 +627,70 @@ BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid, enum pdb
}
if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
- DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid));
+ DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
return False;
}
return True;
}
-BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
-{
- if (!sampass || !g_sid)
- return False;
-
- sid_copy(&sampass->private_u.group_sid, g_sid);
-
- DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
- sid_string_static(&sampass->private_u.group_sid)));
-
- return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
-}
+/********************************************************************
+ We never fill this in from a passdb backend but rather set is
+ based on the user's primary group membership. However, the
+ struct samu* is overloaded and reused in domain memship code
+ as well and built from the NET_USER_INFO_3 or PAC so we
+ have to allow the explicitly setting of a group SID here.
+********************************************************************/
-BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid, enum pdb_value_state flag)
+BOOL pdb_set_group_sid (struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
{
- DOM_SID new_sid;
+ gid_t gid;
+
if (!sampass || !g_sid)
return False;
- DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n",
- g_sid));
-
- if (!string_to_sid(&new_sid, g_sid)) {
- DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
+ if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
return False;
}
-
- if (!pdb_set_group_sid(sampass, &new_sid, flag)) {
- DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
- return False;
+
+ /* if we cannot resolve the SID to gid, then just ignore it and
+ store DOMAIN_USERS as the primary groupSID */
+
+ if ( sid_to_gid( g_sid, &gid ) ) {
+ sid_copy(sampass->group_sid, g_sid);
+ } else {
+ sid_copy( sampass->group_sid, get_global_sam_sid() );
+ sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
}
- return True;
+
+ DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
+ sid_string_static(sampass->group_sid)));
+
+ return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
}
/*********************************************************************
Set the user's UNIX name.
********************************************************************/
-BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value_state flag)
+BOOL pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (username) {
DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
- (sampass->private_u.username)?(sampass->private_u.username):"NULL"));
+ (sampass->username)?(sampass->username):"NULL"));
- sampass->private_u.username = talloc_strdup(sampass->mem_ctx, username);
+ sampass->username = talloc_strdup(sampass, username);
- if (!sampass->private_u.username) {
+ if (!sampass->username) {
DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.username = PDB_NOT_QUITE_NULL;
+ sampass->username = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
@@ -634,24 +700,24 @@ BOOL pdb_set_username(SAM_ACCOUNT *sampass, const char *username, enum pdb_value
Set the domain name.
********************************************************************/
-BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_state flag)
+BOOL pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (domain) {
DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
- (sampass->private_u.domain)?(sampass->private_u.domain):"NULL"));
+ (sampass->domain)?(sampass->domain):"NULL"));
- sampass->private_u.domain = talloc_strdup(sampass->mem_ctx, domain);
+ sampass->domain = talloc_strdup(sampass, domain);
- if (!sampass->private_u.domain) {
+ if (!sampass->domain) {
DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.domain = PDB_NOT_QUITE_NULL;
+ sampass->domain = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
@@ -661,24 +727,24 @@ BOOL pdb_set_domain(SAM_ACCOUNT *sampass, const char *domain, enum pdb_value_sta
Set the user's NT name.
********************************************************************/
-BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb_value_state flag)
+BOOL pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (nt_username) {
DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
- (sampass->private_u.nt_username)?(sampass->private_u.nt_username):"NULL"));
+ (sampass->nt_username)?(sampass->nt_username):"NULL"));
- sampass->private_u.nt_username = talloc_strdup(sampass->mem_ctx, nt_username);
+ sampass->nt_username = talloc_strdup(sampass, nt_username);
- if (!sampass->private_u.nt_username) {
+ if (!sampass->nt_username) {
DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.nt_username = PDB_NOT_QUITE_NULL;
+ sampass->nt_username = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
@@ -688,24 +754,24 @@ BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, const char *nt_username, enum pdb
Set the user's full name.
********************************************************************/
-BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_value_state flag)
+BOOL pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (full_name) {
DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
- (sampass->private_u.full_name)?(sampass->private_u.full_name):"NULL"));
+ (sampass->full_name)?(sampass->full_name):"NULL"));
- sampass->private_u.full_name = talloc_strdup(sampass->mem_ctx, full_name);
+ sampass->full_name = talloc_strdup(sampass, full_name);
- if (!sampass->private_u.full_name) {
+ if (!sampass->full_name) {
DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.full_name = PDB_NOT_QUITE_NULL;
+ sampass->full_name = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
@@ -715,24 +781,24 @@ BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, const char *full_name, enum pdb_valu
Set the user's logon script.
********************************************************************/
-BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum pdb_value_state flag)
+BOOL pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (logon_script) {
DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
- (sampass->private_u.logon_script)?(sampass->private_u.logon_script):"NULL"));
+ (sampass->logon_script)?(sampass->logon_script):"NULL"));
- sampass->private_u.logon_script = talloc_strdup(sampass->mem_ctx, logon_script);
+ sampass->logon_script = talloc_strdup(sampass, logon_script);
- if (!sampass->private_u.logon_script) {
+ if (!sampass->logon_script) {
DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.logon_script = PDB_NOT_QUITE_NULL;
+ sampass->logon_script = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
@@ -742,24 +808,24 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, enum p
Set the user's profile path.
********************************************************************/
-BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum pdb_value_state flag)
+BOOL pdb_set_profile_path (struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (profile_path) {
DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
- (sampass->private_u.profile_path)?(sampass->private_u.profile_path):"NULL"));
+ (sampass->profile_path)?(sampass->profile_path):"NULL"));
- sampass->private_u.profile_path = talloc_strdup(sampass->mem_ctx, profile_path);
+ sampass->profile_path = talloc_strdup(sampass, profile_path);
- if (!sampass->private_u.profile_path) {
+ if (!sampass->profile_path) {
DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.profile_path = PDB_NOT_QUITE_NULL;
+ sampass->profile_path = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
@@ -769,24 +835,24 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, enum
Set the user's directory drive.
********************************************************************/
-BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_value_state flag)
+BOOL pdb_set_dir_drive (struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (dir_drive) {
DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
- (sampass->private_u.dir_drive)?(sampass->private_u.dir_drive):"NULL"));
+ (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
- sampass->private_u.dir_drive = talloc_strdup(sampass->mem_ctx, dir_drive);
+ sampass->dir_drive = talloc_strdup(sampass, dir_drive);
- if (!sampass->private_u.dir_drive) {
+ if (!sampass->dir_drive) {
DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.dir_drive = PDB_NOT_QUITE_NULL;
+ sampass->dir_drive = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
@@ -796,76 +862,48 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, enum pdb_va
Set the user's home directory.
********************************************************************/
-BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, enum pdb_value_state flag)
+BOOL pdb_set_homedir (struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (home_dir) {
DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
- (sampass->private_u.home_dir)?(sampass->private_u.home_dir):"NULL"));
+ (sampass->home_dir)?(sampass->home_dir):"NULL"));
- sampass->private_u.home_dir = talloc_strdup(sampass->mem_ctx, home_dir);
+ sampass->home_dir = talloc_strdup(sampass, home_dir);
- if (!sampass->private_u.home_dir) {
+ if (!sampass->home_dir) {
DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.home_dir = PDB_NOT_QUITE_NULL;
+ sampass->home_dir = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
}
/*********************************************************************
- Set the user's unix home directory.
- ********************************************************************/
-
-BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- if (unix_home_dir) {
- DEBUG(10, ("pdb_set_unix_homedir: setting home dir %s, was %s\n", unix_home_dir,
- (sampass->private_u.unix_home_dir)?(sampass->private_u.unix_home_dir):"NULL"));
-
- sampass->private_u.unix_home_dir = talloc_strdup(sampass->mem_ctx,
- unix_home_dir);
-
- if (!sampass->private_u.unix_home_dir) {
- DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
- return False;
- }
-
- } else {
- sampass->private_u.unix_home_dir = PDB_NOT_QUITE_NULL;
- }
-
- return pdb_set_init_flags(sampass, PDB_UNIXHOMEDIR, flag);
-}
-
-/*********************************************************************
Set the user's account description.
********************************************************************/
-BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_value_state flag)
+BOOL pdb_set_acct_desc (struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (acct_desc) {
- sampass->private_u.acct_desc = talloc_strdup(sampass->mem_ctx, acct_desc);
+ sampass->acct_desc = talloc_strdup(sampass, acct_desc);
- if (!sampass->private_u.acct_desc) {
+ if (!sampass->acct_desc) {
DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.acct_desc = PDB_NOT_QUITE_NULL;
+ sampass->acct_desc = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
@@ -875,24 +913,24 @@ BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, const char *acct_desc, enum pdb_va
Set the user's workstation allowed list.
********************************************************************/
-BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum pdb_value_state flag)
+BOOL pdb_set_workstations (struct samu *sampass, const char *workstations, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (workstations) {
DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
- (sampass->private_u.workstations)?(sampass->private_u.workstations):"NULL"));
+ (sampass->workstations)?(sampass->workstations):"NULL"));
- sampass->private_u.workstations = talloc_strdup(sampass->mem_ctx, workstations);
+ sampass->workstations = talloc_strdup(sampass, workstations);
- if (!sampass->private_u.workstations) {
+ if (!sampass->workstations) {
DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.workstations = PDB_NOT_QUITE_NULL;
+ sampass->workstations = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
@@ -902,21 +940,21 @@ BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, const char *workstations, enum
Set the user's 'unknown_str', whatever the heck this actually is...
********************************************************************/
-BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pdb_value_state flag)
+BOOL pdb_set_unknown_str (struct samu *sampass, const char *unknown_str, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (unknown_str) {
- sampass->private_u.unknown_str = talloc_strdup(sampass->mem_ctx, unknown_str);
+ sampass->unknown_str = talloc_strdup(sampass, unknown_str);
- if (!sampass->private_u.unknown_str) {
+ if (!sampass->unknown_str) {
DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.unknown_str = PDB_NOT_QUITE_NULL;
+ sampass->unknown_str = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_UNKNOWNSTR, flag);
@@ -926,21 +964,21 @@ BOOL pdb_set_unknown_str (SAM_ACCOUNT *sampass, const char *unknown_str, enum pd
Set the user's dial string.
********************************************************************/
-BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pdb_value_state flag)
+BOOL pdb_set_munged_dial (struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (munged_dial) {
- sampass->private_u.munged_dial = talloc_strdup(sampass->mem_ctx, munged_dial);
+ sampass->munged_dial = talloc_strdup(sampass, munged_dial);
- if (!sampass->private_u.munged_dial) {
+ if (!sampass->munged_dial) {
DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.munged_dial = PDB_NOT_QUITE_NULL;
+ sampass->munged_dial = PDB_NOT_QUITE_NULL;
}
return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
@@ -950,17 +988,18 @@ BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, const char *munged_dial, enum pd
Set the user's NT hash.
********************************************************************/
-BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
+BOOL pdb_set_nt_passwd (struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
{
if (!sampass)
return False;
- data_blob_clear_free(&sampass->private_u.nt_pw);
+ data_blob_clear_free(&sampass->nt_pw);
if (pwd) {
- sampass->private_u.nt_pw = data_blob(pwd, NT_HASH_LEN);
+ sampass->nt_pw =
+ data_blob_talloc(sampass, pwd, NT_HASH_LEN);
} else {
- sampass->private_u.nt_pw = data_blob(NULL, 0);
+ sampass->nt_pw = data_blob(NULL, 0);
}
return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
@@ -970,17 +1009,18 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[NT_HASH_LEN], enum
Set the user's LM hash.
********************************************************************/
-BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
+BOOL pdb_set_lanman_passwd (struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
{
if (!sampass)
return False;
- data_blob_clear_free(&sampass->private_u.lm_pw);
+ data_blob_clear_free(&sampass->lm_pw);
if (pwd) {
- sampass->private_u.lm_pw = data_blob(pwd, LM_HASH_LEN);
+ sampass->lm_pw =
+ data_blob_talloc(sampass, pwd, LM_HASH_LEN);
} else {
- sampass->private_u.lm_pw = data_blob(NULL, 0);
+ sampass->lm_pw = data_blob(NULL, 0);
}
return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
@@ -993,20 +1033,20 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN],
in pwd.
********************************************************************/
-BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
+BOOL pdb_set_pw_history (struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (historyLen && pwd){
- sampass->private_u.nt_pw_his = data_blob_talloc(sampass->mem_ctx,
+ sampass->nt_pw_his = data_blob_talloc(sampass,
pwd, historyLen*PW_HISTORY_ENTRY_LEN);
- if (!sampass->private_u.nt_pw_his.length) {
+ if (!sampass->nt_pw_his.length) {
DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
return False;
}
} else {
- sampass->private_u.nt_pw_his = data_blob_talloc(sampass->mem_ctx, NULL, 0);
+ sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
}
return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
@@ -1017,75 +1057,75 @@ BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyL
below)
********************************************************************/
-BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum pdb_value_state flag)
+BOOL pdb_set_plaintext_pw_only (struct samu *sampass, const char *password, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (password) {
- if (sampass->private_u.plaintext_pw!=NULL)
- memset(sampass->private_u.plaintext_pw,'\0',strlen(sampass->private_u.plaintext_pw)+1);
+ if (sampass->plaintext_pw!=NULL)
+ memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
- sampass->private_u.plaintext_pw = talloc_strdup(sampass->mem_ctx, password);
+ sampass->plaintext_pw = talloc_strdup(sampass, password);
- if (!sampass->private_u.plaintext_pw) {
+ if (!sampass->plaintext_pw) {
DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
return False;
}
} else {
- sampass->private_u.plaintext_pw = NULL;
+ sampass->plaintext_pw = NULL;
}
return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
}
-BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag)
+BOOL pdb_set_bad_password_count(struct samu *sampass, uint16 bad_password_count, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.bad_password_count = bad_password_count;
+ sampass->bad_password_count = bad_password_count;
return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
}
-BOOL pdb_set_logon_count(SAM_ACCOUNT *sampass, uint16 logon_count, enum pdb_value_state flag)
+BOOL pdb_set_logon_count(struct samu *sampass, uint16 logon_count, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.logon_count = logon_count;
+ sampass->logon_count = logon_count;
return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
}
-BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn, enum pdb_value_state flag)
+BOOL pdb_set_unknown_6 (struct samu *sampass, uint32 unkn, enum pdb_value_state flag)
{
if (!sampass)
return False;
- sampass->private_u.unknown_6 = unkn;
+ sampass->unknown_6 = unkn;
return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
}
-BOOL pdb_set_hours (SAM_ACCOUNT *sampass, const uint8 *hours, enum pdb_value_state flag)
+BOOL pdb_set_hours (struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
{
if (!sampass)
return False;
if (!hours) {
- memset ((char *)sampass->private_u.hours, 0, MAX_HOURS_LEN);
+ memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
return True;
}
- memcpy (sampass->private_u.hours, hours, MAX_HOURS_LEN);
+ memcpy (sampass->hours, hours, MAX_HOURS_LEN);
return pdb_set_init_flags(sampass, PDB_HOURS, flag);
}
-BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data,
+BOOL pdb_set_backend_private_data (struct samu *sampass, void *private_data,
void (*free_fn)(void **),
const struct pdb_methods *my_methods,
enum pdb_value_state flag)
@@ -1093,13 +1133,15 @@ BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data,
if (!sampass)
return False;
- if (sampass->private_u.backend_private_data && sampass->private_u.backend_private_data_free_fn) {
- sampass->private_u.backend_private_data_free_fn(&sampass->private_u.backend_private_data);
+ if (sampass->backend_private_data &&
+ sampass->backend_private_data_free_fn) {
+ sampass->backend_private_data_free_fn(
+ &sampass->backend_private_data);
}
- sampass->private_u.backend_private_data = private_data;
- sampass->private_u.backend_private_data_free_fn = free_fn;
- sampass->private_u.backend_private_methods = my_methods;
+ sampass->backend_private_data = private_data;
+ sampass->backend_private_data_free_fn = free_fn;
+ sampass->backend_private_methods = my_methods;
return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
}
@@ -1112,7 +1154,7 @@ BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data,
password change.
********************************************************************/
-BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
+BOOL pdb_set_pass_changed_now (struct samu *sampass)
{
uint32 expire;
uint32 min_age;
@@ -1152,7 +1194,7 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
Also sets the last change time to NOW.
********************************************************************/
-BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
+BOOL pdb_set_plaintext_passwd (struct samu *sampass, const char *plaintext)
{
uchar new_lanman_p16[LM_HASH_LEN];
uchar new_nt_p16[NT_HASH_LEN];
@@ -1194,11 +1236,11 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
uint32 current_history_len;
/* We need to make sure we don't have a race condition here - the
account policy history length can change between when the pw_history
- was first loaded into the SAM_ACCOUNT struct and now.... JRA. */
+ was first loaded into the struct samu struct and now.... JRA. */
pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
if (current_history_len != pwHistLen) {
- /* After closing and reopening SAM_ACCOUNT the history
+ /* After closing and reopening struct samu the history
values will sync up. We can't do this here. */
/* current_history_len > pwHistLen is not a problem - we
@@ -1206,8 +1248,12 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
if (current_history_len < pwHistLen) {
/* Ensure we have space for the needed history. */
- uchar *new_history = TALLOC(sampass->mem_ctx,
+ uchar *new_history = TALLOC(sampass,
pwHistLen*PW_HISTORY_ENTRY_LEN);
+ if (!new_history) {
+ return False;
+ }
+
/* And copy it into the new buffer. */
if (current_history_len) {
memcpy(new_history, pwhistory,
@@ -1247,7 +1293,7 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
}
/* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
-uint32 pdb_build_fields_present (SAM_ACCOUNT *sampass)
+uint32 pdb_build_fields_present (struct samu *sampass)
{
/* value set to all for testing */
return 0x00ffffff;
diff --git a/source/passdb/pdb_guest.c b/source/passdb/pdb_guest.c
deleted file mode 100644
index 510cf6abc8b..00000000000
--- a/source/passdb/pdb_guest.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 'Guest' password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- * Copyright (C) Andrew Bartlett 2003
- *
- * 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 2 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, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *sam_account, const char *sname)
-{
- const char *guest_account = lp_guestaccount();
-
- if (!sam_account || !sname) {
- DEBUG(0,("invalid name specified"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!methods) {
- DEBUG(0,("invalid methods\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (!strequal(guest_account, sname)) {
- return NT_STATUS_NO_SUCH_USER;
- }
-
- pdb_fill_default_sam(sam_account);
-
- if (!pdb_set_username(sam_account, guest_account, PDB_SET))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_fullname(sam_account, guest_account, PDB_SET))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_domain(sam_account, get_global_sam_name(), PDB_DEFAULT))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_SET))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT))
- return NT_STATUS_UNSUCCESSFUL;
-
- return NT_STATUS_OK;
-}
-
-
-/***************************************************************************
- Search by rid
- **************************************************************************/
-
-static NTSTATUS guestsam_getsampwrid (struct pdb_methods *methods,
- SAM_ACCOUNT *sam_account, uint32 rid)
-{
- if (rid != DOMAIN_USER_RID_GUEST) {
- return NT_STATUS_NO_SUCH_USER;
- }
-
- if (!sam_account) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return guestsam_getsampwnam (methods, sam_account, lp_guestaccount());
-}
-
-static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
-{
- uint32 rid;
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return NT_STATUS_NO_SUCH_USER;
-
- return guestsam_getsampwrid(my_methods, user, rid);
-}
-
-
-/***************************************************************************
- Updates a SAM_ACCOUNT
-
- This isn't a particulary practical option for pdb_guest. We certainly don't
- want to twidde the filesystem, so what should we do?
-
- Current plan is to transparently add the account. It should appear
- as if the pdb_guest version was modified, but its actually stored somehwere.
- ****************************************************************************/
-
-static NTSTATUS guestsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
-{
-#if 1 /* JERRY */
-
- /* apparently thr build farm relies upon this heavior :-( */
-
- return methods->parent->pdb_add_sam_account(methods->parent, newpwd);
-#else
- /* I don't think we should allow any modification of
- the guest account as SID will could messed up with
- the smbpasswd backend --jerry */
-
- return NT_STATUS_NOT_IMPLEMENTED;
-#endif
-}
-
-NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
-{
- NTSTATUS nt_status;
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_context specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "guestsam";
-
- (*pdb_method)->getsampwnam = guestsam_getsampwnam;
- (*pdb_method)->getsampwsid = guestsam_getsampwsid;
- (*pdb_method)->update_sam_account = guestsam_update_sam_account;
-
- /* we should do no group mapping here */
- (*pdb_method)->getgrsid = pdb_nop_getgrsid;
- (*pdb_method)->getgrgid = pdb_nop_getgrgid;
- (*pdb_method)->getgrnam = pdb_nop_getgrnam;
- (*pdb_method)->add_group_mapping_entry = pdb_nop_add_group_mapping_entry;
- (*pdb_method)->update_group_mapping_entry = pdb_nop_update_group_mapping_entry;
- (*pdb_method)->delete_group_mapping_entry = pdb_nop_delete_group_mapping_entry;
- (*pdb_method)->enum_group_mapping = pdb_nop_enum_group_mapping;
-
-
- /* There's not very much to initialise here */
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_guest_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "guest", pdb_init_guestsam);
-}
-
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 875e264bf01..b3522e33a7f 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Bartlett 2002
Copyright (C) Jelmer Vernooij 2002
Copyright (C) Simo Sorce 2003
+ Copyright (C) Volker Lendecke 2006
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
@@ -25,6 +26,10 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
+/* Cache of latest SAM lookup query */
+
+static struct samu *csamuser = NULL;
+
static struct pdb_init_function_entry *backends = NULL;
static void lazy_initialize_passdb(void)
@@ -35,8 +40,10 @@ static void lazy_initialize_passdb(void)
initialized = True;
}
-static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
-
+static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
+ const char **name,
+ enum SID_NAME_USE *psid_name_use,
+ union unid_t *unix_id);
/*******************************************************************
Clean up uninitialised passwords. The only way to tell
that these values are not 'real' is that they do not
@@ -46,7 +53,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
time, such LDAP with a missing attribute would produce.
********************************************************************/
-static void pdb_force_pw_initialization(SAM_ACCOUNT *pass)
+static void pdb_force_pw_initialization(struct samu *pass)
{
const uint8 *lm_pwd, *nt_pwd;
@@ -108,7 +115,7 @@ NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function in
return NT_STATUS_OK;
}
-static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
+struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
{
struct pdb_init_function_entry *entry = backends;
@@ -120,1334 +127,1164 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
return NULL;
}
-static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update, uint16 acb_mask)
+/******************************************************************
+ Make a pdb_methods from scratch
+ *******************************************************************/
+
+NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ char *module_name = smb_xstrdup(selected);
+ char *module_location = NULL, *p;
+ struct pdb_init_function_entry *entry;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
+ lazy_initialize_passdb();
- context->pwent_methods = context->pdb_methods;
+ p = strchr(module_name, ':');
- if (!context->pwent_methods) {
- /* No passdbs at all */
- return ret;
+ if (p) {
+ *p = 0;
+ module_location = p+1;
+ trim_char(module_location, ' ', ' ');
}
- while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update, acb_mask))) {
- context->pwent_methods = context->pwent_methods->next;
- if (context->pwent_methods == NULL)
- return NT_STATUS_UNSUCCESSFUL;
- }
- return ret;
-}
+ trim_char(module_name, ' ', ' ');
-static void context_endsampwent(struct pdb_context *context)
-{
- if ((!context)){
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return;
- }
- if (context->pwent_methods && context->pwent_methods->endsampwent)
- context->pwent_methods->endsampwent(context->pwent_methods);
+ DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
- /* So we won't get strange data when calling getsampwent now */
- context->pwent_methods = NULL;
-}
+ entry = pdb_find_backend_entry(module_name);
+
+ /* Try to find a module that contains this module */
+ if (!entry) {
+ DEBUG(2,("No builtin backend found, trying to load plugin\n"));
+ if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
+ DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
+ SAFE_FREE(module_name);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* No such backend found */
+ if(!entry) {
+ DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
+ SAFE_FREE(module_name);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
-static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(5,("Found pdb backend %s\n", module_name));
- if ((!context) || (!context->pwent_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !NT_STATUS_IS_OK( nt_status = entry->init(methods, module_location) ) ) {
+ DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n",
+ selected, nt_errstr(nt_status)));
+ SAFE_FREE(module_name);
+ return nt_status;
}
- /* Loop until we find something useful */
- while (NT_STATUS_IS_ERR(ret = context->pwent_methods->getsampwent(context->pwent_methods, user))) {
- context->pwent_methods->endsampwent(context->pwent_methods);
+ SAFE_FREE(module_name);
- context->pwent_methods = context->pwent_methods->next;
+ DEBUG(5,("pdb backend %s has a valid init\n", selected));
- /* All methods are checked now. There are no more entries */
- if (context->pwent_methods == NULL)
- return ret;
-
- context->pwent_methods->setsampwent(context->pwent_methods, False, 0);
- }
- user->methods = context->pwent_methods;
- pdb_force_pw_initialization(user);
- return ret;
+ return nt_status;
}
-static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
+/******************************************************************
+ Return an already initialised pdn_methods structure
+*******************************************************************/
+
+static struct pdb_methods *pdb_get_methods_reload( BOOL reload )
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ static struct pdb_methods *pdb = NULL;
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( pdb && reload ) {
+ pdb->free_private_data( &(pdb->private_data) );
+ if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
+ return NULL;
+ }
}
- curmethods = context->pdb_methods;
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) {
- pdb_force_pw_initialization(sam_acct);
- sam_acct->methods = curmethods;
- return ret;
+
+ if ( !pdb ) {
+ if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
+ return NULL;
}
- curmethods = curmethods->next;
}
- return ret;
+ return pdb;
}
-static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
+static struct pdb_methods *pdb_get_methods(void)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ return pdb_get_methods_reload(False);
+}
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- curmethods = context->pdb_methods;
+/******************************************************************
+ Backward compatibility functions for the original passdb interface
+*******************************************************************/
- while (curmethods){
- if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) {
- pdb_force_pw_initialization(sam_acct);
- sam_acct->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
+BOOL pdb_setsampwent(BOOL update, uint16 acb_mask)
+{
+ struct pdb_methods *pdb = pdb_get_methods();
+
+ if ( !pdb ) {
+ return False;
}
- return ret;
+ return NT_STATUS_IS_OK(pdb->setsampwent(pdb, update, acb_mask));
}
-static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+void pdb_endsampwent(void)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- const uint8 *lm_pw, *nt_pw;
- uint16 acb_flags;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
+ struct pdb_methods *pdb = pdb_get_methods();
- /* disable acccounts with no passwords (that has not
- been allowed by the ACB_PWNOTREQ bit */
-
- lm_pw = pdb_get_lanman_passwd( sam_acct );
- nt_pw = pdb_get_nt_passwd( sam_acct );
- acb_flags = pdb_get_acct_ctrl( sam_acct );
- if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) {
- acb_flags |= ACB_DISABLED;
- pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED );
+ if ( !pdb ) {
+ return;
}
-
- /** @todo This is where a 're-read on add' should be done */
- /* We now add a new account to the first database listed.
- * Should we? */
- return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct);
+ pdb->endsampwent(pdb);
}
-static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+BOOL pdb_getsampwent(struct samu *user)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- const uint8 *lm_pw, *nt_pw;
- uint16 acb_flags;
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return False;
}
- if (!sam_acct || !sam_acct->methods){
- DEBUG(0, ("invalid sam_acct specified\n"));
- return ret;
+ if ( !NT_STATUS_IS_OK(pdb->getsampwent(pdb, user) ) ) {
+ return False;
}
- /* disable acccounts with no passwords (that has not
- been allowed by the ACB_PWNOTREQ bit */
-
- lm_pw = pdb_get_lanman_passwd( sam_acct );
- nt_pw = pdb_get_nt_passwd( sam_acct );
- acb_flags = pdb_get_acct_ctrl( sam_acct );
- if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) {
- acb_flags |= ACB_DISABLED;
- pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED );
- }
-
- /** @todo This is where a 're-read on update' should be done */
+ pdb_force_pw_initialization( user );
- return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct);
+ return True;
}
-static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+BOOL pdb_getsampwnam(struct samu *sam_acct, const char *username)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- struct pdb_methods *pdb_selected;
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return False;
}
- if (!sam_acct->methods){
- pdb_selected = context->pdb_methods;
- /* There's no passdb backend specified for this account.
- * Try to delete it in every passdb available
- * Needed to delete accounts in smbpasswd that are not
- * in /etc/passwd.
- */
- while (pdb_selected){
- if (NT_STATUS_IS_OK(ret = pdb_selected->delete_sam_account(pdb_selected, sam_acct))) {
- return ret;
- }
- pdb_selected = pdb_selected->next;
- }
- return ret;
+ if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
+ return False;
}
- if (!sam_acct->methods->delete_sam_account){
- DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n"));
- return ret;
+ if ( csamuser ) {
+ TALLOC_FREE(csamuser);
}
+
+ pdb_force_pw_initialization( sam_acct );
- return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
+ if ( (csamuser = samu_new( NULL )) != NULL ) {
+ pdb_copy_sam_account(csamuser, sam_acct);
+ }
+
+ return True;
}
-static NTSTATUS context_rename_sam_account(struct pdb_context *context, SAM_ACCOUNT *oldname, const char *newname)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+/**********************************************************************
+**********************************************************************/
- struct pdb_methods *pdb_selected;
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+BOOL guest_user_info( struct samu *user )
+{
+ struct passwd *pwd;
+ NTSTATUS result;
+ const char *guestname = lp_guestaccount();
+
+ if ( !(pwd = getpwnam_alloc( NULL, guestname ) ) ) {
+ DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n",
+ guestname));
+ return False;
}
+
+ result = samu_set_unix(user, pwd );
- if (!oldname->methods){
- pdb_selected = context->pdb_methods;
- /* There's no passdb backend specified for this account.
- * Try to delete it in every passdb available
- * Needed to delete accounts in smbpasswd that are not
- * in /etc/passwd.
- */
- while (pdb_selected){
- if (NT_STATUS_IS_OK(ret = pdb_selected->rename_sam_account(pdb_selected, oldname, newname))) {
- return ret;
- }
- pdb_selected = pdb_selected->next;
- }
- return ret;
- }
+ TALLOC_FREE( pwd );
- if (!oldname->methods->rename_sam_account){
- DEBUG(0,("invalid oldname->methods->rename_sam_account\n"));
- return ret;
- }
-
- return oldname->methods->rename_sam_account(oldname->methods, oldname, newname);
+ return NT_STATUS_IS_OK( result );
}
+/**********************************************************************
+**********************************************************************/
-static NTSTATUS context_update_login_attempts(struct pdb_context *context,
- SAM_ACCOUNT *sam_acct, BOOL success)
+BOOL pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!context) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
+ struct pdb_methods *pdb;
+ uint32 rid;
- if (!sam_acct || !sam_acct->methods){
- DEBUG(0, ("invalid sam_acct specified\n"));
- return ret;
+ if ( !(pdb = pdb_get_methods()) ) {
+ return False;
}
- return sam_acct->methods->update_login_attempts(sam_acct->methods, sam_acct, success);
-}
+ /* hard code the Guest RID of 501 */
-static NTSTATUS context_getgrsid(struct pdb_context *context,
- GROUP_MAP *map, DOM_SID sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ if ( !sid_peek_check_rid( get_global_sam_sid(), sid, &rid ) )
+ return False;
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- ret = curmethods->getgrsid(curmethods, map, sid);
- if (NT_STATUS_IS_OK(ret)) {
- map->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
+ if ( rid == DOMAIN_USER_RID_GUEST ) {
+ DEBUG(6,("pdb_getsampwsid: Building guest account\n"));
+ return guest_user_info( sam_acct );
}
+
+ /* check the cache first */
+
+ if ( csamuser && sid_equal(sid, pdb_get_user_sid(csamuser) ) )
+ return pdb_copy_sam_account(sam_acct, csamuser);
- return ret;
+ return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
}
-static NTSTATUS context_getgrgid(struct pdb_context *context,
- GROUP_MAP *map, gid_t gid)
+static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
+ TALLOC_CTX *tmp_ctx, const char *name,
+ uint32 acb_info, uint32 *rid)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct samu *sam_pass;
+ NTSTATUS status;
+ struct passwd *pwd;
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- ret = curmethods->getgrgid(curmethods, map, gid);
- if (NT_STATUS_IS_OK(ret)) {
- map->methods = curmethods;
- return ret;
- }
- curmethods = curmethods->next;
+ if ((sam_pass = samu_new(tmp_ctx)) == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
- return ret;
-}
+ if ( !(pwd = Get_Pwnam_alloc(tmp_ctx, name)) ) {
+ pstring add_script;
+ int add_ret;
-static NTSTATUS context_getgrnam(struct pdb_context *context,
- GROUP_MAP *map, const char *name)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') {
+ pstrcpy(add_script, lp_adduser_script());
+ } else {
+ pstrcpy(add_script, lp_addmachine_script());
+ }
- struct pdb_methods *curmethods;
- if ((!context)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
- curmethods = context->pdb_methods;
- while (curmethods){
- ret = curmethods->getgrnam(curmethods, map, name);
- if (NT_STATUS_IS_OK(ret)) {
- map->methods = curmethods;
- return ret;
+ if (add_script[0] == '\0') {
+ DEBUG(3, ("Could not find user %s and no add script "
+ "defined\n", name));
+ return NT_STATUS_NO_SUCH_USER;
}
- curmethods = curmethods->next;
+
+ all_string_sub(add_script, "%u", name, sizeof(add_script));
+ add_ret = smbrun(add_script,NULL);
+ DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n",
+ add_script, add_ret));
+ flush_pwnam_cache();
+
+ pwd = Get_Pwnam_alloc(tmp_ctx, name);
}
- return ret;
-}
+ /* we have a valid SID coming out of this call */
-static NTSTATUS context_add_group_mapping_entry(struct pdb_context *context,
- GROUP_MAP *map)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ status = samu_alloc_rid_unix( sam_pass, pwd );
+
+ TALLOC_FREE( pwd );
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("pdb_default_create_user: failed to create a new user structure: %s\n", nt_errstr(status)));
+ return status;
}
- return context->pdb_methods->add_group_mapping_entry(context->pdb_methods,
- map);
-}
+ if (!sid_peek_check_rid(get_global_sam_sid(),
+ pdb_get_user_sid(sam_pass), rid)) {
+ DEBUG(0, ("Could not get RID of fresh user\n"));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
-static NTSTATUS context_update_group_mapping_entry(struct pdb_context *context,
- GROUP_MAP *map)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ /* Disable the account on creation, it does not have a reasonable password yet. */
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
+ acb_info |= ACB_DISABLED;
- return context->
- pdb_methods->update_group_mapping_entry(context->pdb_methods, map);
-}
+ pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
-static NTSTATUS context_delete_group_mapping_entry(struct pdb_context *context,
- DOM_SID sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ status = pdb_add_sam_account(sam_pass);
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
+ TALLOC_FREE(sam_pass);
- return context->
- pdb_methods->delete_group_mapping_entry(context->pdb_methods, sid);
+ return status;
}
-static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **pp_rmap, size_t *p_num_entries,
- BOOL unix_only)
+NTSTATUS pdb_create_user(TALLOC_CTX *mem_ctx, const char *name, uint32 flags,
+ uint32 *rid)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return context->pdb_methods->enum_group_mapping(context->pdb_methods,
- sid_name_use, pp_rmap,
- p_num_entries, unix_only);
+ return pdb->create_user(pdb, mem_ctx, name, flags, rid);
}
-static NTSTATUS context_enum_group_members(struct pdb_context *context,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *group,
- uint32 **pp_member_rids,
- size_t *p_num_members)
+/****************************************************************************
+ Delete a UNIX user on demand.
+****************************************************************************/
+
+static int smb_delete_user(const char *unix_user)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ pstring del_script;
+ int ret;
+
+ /* safety check */
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( strequal( unix_user, "root" ) ) {
+ DEBUG(0,("smb_delete_user: Refusing to delete local system root account!\n"));
+ return -1;
}
- return context->pdb_methods->enum_group_members(context->pdb_methods,
- mem_ctx, group,
- pp_member_rids,
- p_num_members);
+ pstrcpy(del_script, lp_deluser_script());
+ if (! *del_script)
+ return -1;
+ all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
+ ret = smbrun(del_script,NULL);
+ flush_pwnam_cache();
+ DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
+
+ return ret;
}
-static NTSTATUS context_enum_group_memberships(struct pdb_context *context,
- const char *username,
- gid_t primary_gid,
- DOM_SID **pp_sids, gid_t **pp_gids,
- size_t *p_num_groups)
+static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ struct samu *sam_acct)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS status;
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ status = pdb_delete_sam_account(sam_acct);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- return context->pdb_methods->
- enum_group_memberships(context->pdb_methods, username,
- primary_gid, pp_sids, pp_gids, p_num_groups);
+ /*
+ * Now delete the unix side ....
+ * note: we don't check if the delete really happened as the script is
+ * not necessary present and maybe the sysadmin doesn't want to delete
+ * the unix side
+ */
+ smb_delete_user( pdb_get_username(sam_acct) );
+
+ return status;
}
-static NTSTATUS context_find_alias(struct pdb_context *context,
- const char *name, DOM_SID *sid)
+NTSTATUS pdb_delete_user(TALLOC_CTX *mem_ctx, struct samu *sam_acct)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
+ uid_t uid = -1;
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return context->pdb_methods->find_alias(context->pdb_methods,
- name, sid);
-}
+ /* sanity check to make sure we don't delete root */
-static NTSTATUS context_create_alias(struct pdb_context *context,
- const char *name, uint32 *rid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ if ( !sid_to_uid( pdb_get_user_sid(sam_acct), &uid ) ) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( uid == 0 ) {
+ return NT_STATUS_ACCESS_DENIED;
}
- return context->pdb_methods->create_alias(context->pdb_methods,
- name, rid);
+ return pdb->delete_user(pdb, mem_ctx, sam_acct);
}
-static NTSTATUS context_delete_alias(struct pdb_context *context,
- const DOM_SID *sid)
+NTSTATUS pdb_add_sam_account(struct samu *sam_acct)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
-
- return context->pdb_methods->delete_alias(context->pdb_methods, sid);
+
+ return pdb->add_sam_account(pdb, sam_acct);
}
-static NTSTATUS context_get_aliasinfo(struct pdb_context *context,
- const DOM_SID *sid,
- struct acct_info *info)
+NTSTATUS pdb_update_sam_account(struct samu *sam_acct)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
+
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if (csamuser != NULL) {
+ TALLOC_FREE(csamuser);
+ csamuser = NULL;
}
- return context->pdb_methods->get_aliasinfo(context->pdb_methods,
- sid, info);
+ return pdb->update_sam_account(pdb, sam_acct);
}
-static NTSTATUS context_set_aliasinfo(struct pdb_context *context,
- const DOM_SID *sid,
- struct acct_info *info)
+NTSTATUS pdb_delete_sam_account(struct samu *sam_acct)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (csamuser != NULL) {
+ TALLOC_FREE(csamuser);
+ csamuser = NULL;
}
- return context->pdb_methods->set_aliasinfo(context->pdb_methods,
- sid, info);
+ return pdb->delete_sam_account(pdb, sam_acct);
}
-static NTSTATUS context_add_aliasmem(struct pdb_context *context,
- const DOM_SID *alias,
- const DOM_SID *member)
+NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
+ uid_t uid;
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- return context->pdb_methods->add_aliasmem(context->pdb_methods,
- alias, member);
-}
-
-static NTSTATUS context_del_aliasmem(struct pdb_context *context,
- const DOM_SID *alias,
- const DOM_SID *member)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if (csamuser != NULL) {
+ TALLOC_FREE(csamuser);
+ csamuser = NULL;
}
- return context->pdb_methods->del_aliasmem(context->pdb_methods,
- alias, member);
-}
-
-static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
- const DOM_SID *alias, DOM_SID **pp_members,
- size_t *p_num)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ /* sanity check to make sure we don't rename root */
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !sid_to_uid( pdb_get_user_sid(oldname), &uid ) ) {
+ return NT_STATUS_NO_SUCH_USER;
}
- return context->pdb_methods->enum_aliasmem(context->pdb_methods,
- alias, pp_members, p_num);
-}
-
-static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *domain_sid,
- const DOM_SID *members,
- size_t num_members,
- uint32 **pp_alias_rids,
- size_t *p_num_alias_rids)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( uid == 0 ) {
+ return NT_STATUS_ACCESS_DENIED;
}
- return context->pdb_methods->
- enum_alias_memberships(context->pdb_methods, mem_ctx,
- domain_sid, members, num_members,
- pp_alias_rids, p_num_alias_rids);
+ return pdb->rename_sam_account(pdb, oldname, newname);
}
-static NTSTATUS context_lookup_rids(struct pdb_context *context,
- const DOM_SID *domain_sid,
- size_t num_rids,
- uint32 *rids,
- const char **pp_names,
- uint32 *pp_attrs)
+NTSTATUS pdb_update_login_attempts(struct samu *sam_acct, BOOL success)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- return context->pdb_methods->lookup_rids(context->pdb_methods,
- domain_sid, num_rids,
- rids, pp_names, pp_attrs);
+ return pdb->update_login_attempts(pdb, sam_acct, success);
}
-static NTSTATUS context_get_account_policy(struct pdb_context *context,
- int policy_index, uint32 *value)
+BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return False;
}
- return context->pdb_methods->get_account_policy(context->pdb_methods,
- policy_index, value);
+ return NT_STATUS_IS_OK(pdb->getgrsid(pdb, map, sid));
}
-static NTSTATUS context_set_account_policy(struct pdb_context *context,
- int policy_index, uint32 value)
+BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return False;
}
- return context->pdb_methods->set_account_policy(context->pdb_methods,
- policy_index, value);
+ return NT_STATUS_IS_OK(pdb->getgrgid(pdb, map, gid));
}
-static NTSTATUS context_get_seq_num(struct pdb_context *context, time_t *seq_num)
+BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct pdb_methods *pdb = pdb_get_methods();
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
+ if ( !pdb ) {
+ return False;
}
- return context->pdb_methods->get_seq_num(context->pdb_methods, seq_num);
+ return NT_STATUS_IS_OK(pdb->getgrnam(pdb, map, name));
}
-
-/******************************************************************
- Free and cleanup a pdb context, any associated data and anything
- that the attached modules might have associated.
- *******************************************************************/
-static void free_pdb_context(struct pdb_context **context)
+static NTSTATUS pdb_default_create_dom_group(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const char *name,
+ uint32 *rid)
{
- struct pdb_methods *pdb_selected = (*context)->pdb_methods;
+ DOM_SID group_sid;
+ struct group *grp;
- while (pdb_selected){
- if(pdb_selected->free_private_data)
- pdb_selected->free_private_data(&(pdb_selected->private_data));
- pdb_selected = pdb_selected->next;
- }
+ grp = getgrnam(name);
- talloc_destroy((*context)->mem_ctx);
- *context = NULL;
-}
+ if (grp == NULL) {
+ gid_t gid;
-static BOOL context_search_users(struct pdb_context *context,
- struct pdb_search *search, uint16 acct_flags)
-{
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return False;
+ if (smb_create_group(name, &gid) != 0) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ grp = getgrgid(gid);
}
- return context->pdb_methods->search_users(context->pdb_methods,
- search, acct_flags);
-}
+ if (grp == NULL) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
-static BOOL context_search_groups(struct pdb_context *context,
- struct pdb_search *search)
-{
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return False;
+ if (pdb_rid_algorithm()) {
+ *rid = pdb_gid_to_group_rid( grp->gr_gid );
+ } else {
+ if (!pdb_new_rid(rid)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
}
- return context->pdb_methods->search_groups(context->pdb_methods,
- search);
+ sid_compose(&group_sid, get_global_sam_sid(), *rid);
+
+ return add_initial_entry(grp->gr_gid, sid_string_static(&group_sid),
+ SID_NAME_DOM_GRP, name, NULL);
}
-static BOOL context_search_aliases(struct pdb_context *context,
- struct pdb_search *search,
- const DOM_SID *sid)
+NTSTATUS pdb_create_dom_group(TALLOC_CTX *mem_ctx, const char *name,
+ uint32 *rid)
{
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return False;
+ struct pdb_methods *pdb = pdb_get_methods();
+
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return context->pdb_methods->search_aliases(context->pdb_methods,
- search, sid);
+ return pdb->create_dom_group(pdb, mem_ctx, name, rid);
}
-/******************************************************************
- Make a pdb_methods from scratch
- *******************************************************************/
-
-static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected)
+static NTSTATUS pdb_default_delete_dom_group(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ uint32 rid)
{
- char *module_name = smb_xstrdup(selected);
- char *module_location = NULL, *p;
- struct pdb_init_function_entry *entry;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-
- lazy_initialize_passdb();
+ DOM_SID group_sid;
+ GROUP_MAP map;
+ NTSTATUS status;
+ struct group *grp;
+ const char *grp_name;
- p = strchr(module_name, ':');
+ sid_compose(&group_sid, get_global_sam_sid(), rid);
- if (p) {
- *p = 0;
- module_location = p+1;
- trim_char(module_location, ' ', ' ');
+ if (!get_domain_group_from_sid(group_sid, &map)) {
+ DEBUG(10, ("Could not find group for rid %d\n", rid));
+ return NT_STATUS_NO_SUCH_GROUP;
}
- trim_char(module_name, ' ', ' ');
+ /* We need the group name for the smb_delete_group later on */
-
- DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
-
- entry = pdb_find_backend_entry(module_name);
-
- /* Try to find a module that contains this module */
- if (!entry) {
- DEBUG(2,("No builtin backend found, trying to load plugin\n"));
- if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
- DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
- SAFE_FREE(module_name);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- /* No such backend found */
- if(!entry) {
- DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
- SAFE_FREE(module_name);
- return NT_STATUS_INVALID_PARAMETER;
+ if (map.gid == (gid_t)-1) {
+ return NT_STATUS_NO_SUCH_GROUP;
}
- DEBUG(5,("Found pdb backend %s\n", module_name));
- nt_status = entry->init(context, methods, module_location);
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5,("pdb backend %s has a valid init\n", selected));
- } else {
- DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
+ grp = getgrgid(map.gid);
+ if (grp == NULL) {
+ return NT_STATUS_NO_SUCH_GROUP;
}
- SAFE_FREE(module_name);
- return nt_status;
-}
-/******************************************************************
- Make a pdb_context from scratch.
- *******************************************************************/
+ /* Copy the name, no idea what pdb_delete_group_mapping_entry does.. */
-static NTSTATUS make_pdb_context(struct pdb_context **context)
-{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("pdb_context internal allocation context");
-
- if (!mem_ctx) {
- DEBUG(0, ("make_pdb_context: talloc init failed!\n"));
+ grp_name = talloc_strdup(mem_ctx, grp->gr_name);
+ if (grp_name == NULL) {
return NT_STATUS_NO_MEMORY;
- }
+ }
- *context = TALLOC_P(mem_ctx, struct pdb_context);
- if (!*context) {
- DEBUG(0, ("make_pdb_context: talloc failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ status = pdb_delete_group_mapping_entry(group_sid);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- ZERO_STRUCTP(*context);
-
- (*context)->mem_ctx = mem_ctx;
-
- (*context)->pdb_setsampwent = context_setsampwent;
- (*context)->pdb_endsampwent = context_endsampwent;
- (*context)->pdb_getsampwent = context_getsampwent;
- (*context)->pdb_getsampwnam = context_getsampwnam;
- (*context)->pdb_getsampwsid = context_getsampwsid;
- (*context)->pdb_add_sam_account = context_add_sam_account;
- (*context)->pdb_update_sam_account = context_update_sam_account;
- (*context)->pdb_delete_sam_account = context_delete_sam_account;
- (*context)->pdb_rename_sam_account = context_rename_sam_account;
- (*context)->pdb_update_login_attempts = context_update_login_attempts;
- (*context)->pdb_getgrsid = context_getgrsid;
- (*context)->pdb_getgrgid = context_getgrgid;
- (*context)->pdb_getgrnam = context_getgrnam;
- (*context)->pdb_add_group_mapping_entry = context_add_group_mapping_entry;
- (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
- (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
- (*context)->pdb_enum_group_mapping = context_enum_group_mapping;
- (*context)->pdb_enum_group_members = context_enum_group_members;
- (*context)->pdb_enum_group_memberships = context_enum_group_memberships;
-
- (*context)->pdb_find_alias = context_find_alias;
- (*context)->pdb_create_alias = context_create_alias;
- (*context)->pdb_delete_alias = context_delete_alias;
- (*context)->pdb_get_aliasinfo = context_get_aliasinfo;
- (*context)->pdb_set_aliasinfo = context_set_aliasinfo;
- (*context)->pdb_add_aliasmem = context_add_aliasmem;
- (*context)->pdb_del_aliasmem = context_del_aliasmem;
- (*context)->pdb_enum_aliasmem = context_enum_aliasmem;
- (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
- (*context)->pdb_lookup_rids = context_lookup_rids;
-
- (*context)->pdb_get_account_policy = context_get_account_policy;
- (*context)->pdb_set_account_policy = context_set_account_policy;
-
- (*context)->pdb_get_seq_num = context_get_seq_num;
-
- (*context)->pdb_search_users = context_search_users;
- (*context)->pdb_search_groups = context_search_groups;
- (*context)->pdb_search_aliases = context_search_aliases;
-
- (*context)->free_fn = free_pdb_context;
+ /* Don't check the result of smb_delete_group */
+
+ smb_delete_group(grp_name);
return NT_STATUS_OK;
}
+NTSTATUS pdb_delete_dom_group(TALLOC_CTX *mem_ctx, uint32 rid)
+{
+ struct pdb_methods *pdb = pdb_get_methods();
-/******************************************************************
- Make a pdb_context, given an array of strings
- *******************************************************************/
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
-NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **selected)
+ return pdb->delete_dom_group(pdb, mem_ctx, rid);
+}
+
+NTSTATUS pdb_add_group_mapping_entry(GROUP_MAP *map)
{
- int i = 0;
- struct pdb_methods *curmethods, *tmpmethods;
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- BOOL have_guest = False;
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
- return nt_status;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- if (!selected) {
- DEBUG(0, ("ERROR: empty passdb backend list!\n"));
- return nt_status;
- }
+ return pdb->add_group_mapping_entry(pdb, map);
+}
- while (selected[i]){
- if (strcmp(selected[i], "guest") == 0) {
- have_guest = True;
- }
- /* Try to initialise pdb */
- DEBUG(5,("Trying to load: %s\n", selected[i]));
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) {
- DEBUG(1, ("Loading %s failed!\n", selected[i]));
- free_pdb_context(context);
- return nt_status;
- }
- curmethods->parent = *context;
- DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
- i++;
+NTSTATUS pdb_update_group_mapping_entry(GROUP_MAP *map)
+{
+ struct pdb_methods *pdb = pdb_get_methods();
+
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- if (have_guest)
- return NT_STATUS_OK;
+ return pdb->update_group_mapping_entry(pdb, map);
+}
- if ( (lp_guestaccount() == NULL) ||
- (*lp_guestaccount() == '\0') ) {
- /* We explicitly don't want guest access. No idea what
- else that breaks, but be it that way. */
- return NT_STATUS_OK;
- }
+NTSTATUS pdb_delete_group_mapping_entry(DOM_SID sid)
+{
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods,
- *context,
- "guest"))) {
- DEBUG(1, ("Loading guest module failed!\n"));
- free_pdb_context(context);
- return nt_status;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- curmethods->parent = *context;
- DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
-
- return NT_STATUS_OK;
+ return pdb->delete_group_mapping_entry(pdb, sid);
}
-/******************************************************************
- Make a pdb_context, given a text string.
- *******************************************************************/
-
-NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected)
+BOOL pdb_enum_group_mapping(const DOM_SID *sid, enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rmap,
+ size_t *p_num_entries, BOOL unix_only)
{
- NTSTATUS ret;
- char **newsel = str_list_make(selected, NULL);
- ret = make_pdb_context_list(context, (const char **)newsel);
- str_list_free(&newsel);
- return ret;
-}
+ struct pdb_methods *pdb = pdb_get_methods();
-/******************************************************************
- Return an already initialised pdb_context, to facilitate backward
- compatibility (see functions below).
-*******************************************************************/
+ if ( !pdb ) {
+ return False;
+ }
-static struct pdb_context *pdb_get_static_context(BOOL reload)
+ return NT_STATUS_IS_OK(pdb-> enum_group_mapping(pdb, sid, sid_name_use,
+ pp_rmap, p_num_entries, unix_only));
+}
+
+NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ uint32 **pp_member_rids,
+ size_t *p_num_members)
{
- static struct pdb_context *pdb_context = NULL;
+ struct pdb_methods *pdb = pdb_get_methods();
+ NTSTATUS result;
- if ((pdb_context) && (reload)) {
- pdb_context->free_fn(&pdb_context);
- if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
- return NULL;
- }
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- if (!pdb_context) {
- if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
- return NULL;
+ result = pdb->enum_group_members(pdb, mem_ctx,
+ sid, pp_member_rids, p_num_members);
+
+ /* special check for rid 513 */
+
+ if ( !NT_STATUS_IS_OK( result ) ) {
+ uint32 rid;
+
+ sid_peek_rid( sid, &rid );
+
+ if ( rid == DOMAIN_GROUP_RID_USERS ) {
+ *p_num_members = 0;
+ *pp_member_rids = NULL;
+
+ return NT_STATUS_OK;
}
}
-
- return pdb_context;
+
+ return result;
}
-/******************************************************************
- Backward compatibility functions for the original passdb interface
-*******************************************************************/
-
-BOOL pdb_setsampwent(BOOL update, uint16 acb_mask)
+NTSTATUS pdb_enum_group_memberships(TALLOC_CTX *mem_ctx, struct samu *user,
+ DOM_SID **pp_sids, gid_t **pp_gids,
+ size_t *p_num_groups)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update, acb_mask));
+ return pdb->enum_group_memberships(
+ pdb, mem_ctx, user,
+ pp_sids, pp_gids, p_num_groups);
}
-void pdb_endsampwent(void)
+static NTSTATUS pdb_default_set_unix_primary_group(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ struct samu *sampass)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct group *grp;
+ gid_t gid;
- if (!pdb_context) {
- return;
+ if (!sid_to_gid(pdb_get_group_sid(sampass), &gid) ||
+ (grp = getgrgid(gid)) == NULL) {
+ return NT_STATUS_INVALID_PRIMARY_GROUP;
}
- pdb_context->pdb_endsampwent(pdb_context);
+ if (smb_set_primary_group(grp->gr_name,
+ pdb_get_username(sampass)) != 0) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_OK;
}
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+NTSTATUS pdb_set_unix_primary_group(TALLOC_CTX *mem_ctx, struct samu *user)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user));
+ return pdb->set_unix_primary_group(pdb, mem_ctx, user);
}
-static SAM_ACCOUNT *sam_account_cache = NULL;
+/*
+ * Helper function to see whether a user is in a group. We can't use
+ * user_in_group_sid here because this creates dependencies only smbd can
+ * fulfil.
+ */
-BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
+static BOOL pdb_user_in_group(TALLOC_CTX *mem_ctx, struct samu *account,
+ const DOM_SID *group_sid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ DOM_SID *sids;
+ gid_t *gids;
+ size_t i, num_groups;
- if (!pdb_context) {
+ if (!NT_STATUS_IS_OK(pdb_enum_group_memberships(mem_ctx, account,
+ &sids, &gids,
+ &num_groups))) {
return False;
}
- if (!NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context,
- sam_acct, username)))
- return False;
-
- if (sam_account_cache != NULL) {
- pdb_free_sam(&sam_account_cache);
- sam_account_cache = NULL;
+ for (i=0; i<num_groups; i++) {
+ if (sid_equal(group_sid, &sids[i])) {
+ return True;
+ }
}
-
- pdb_copy_sam_account(sam_acct, &sam_account_cache);
- return True;
+ return False;
}
-BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
+static NTSTATUS pdb_default_add_groupmem(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ uint32 group_rid,
+ uint32 member_rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ DOM_SID group_sid, member_sid;
+ struct samu *account = NULL;
+ GROUP_MAP map;
+ struct group *grp;
+ struct passwd *pwd;
+ const char *group_name;
+ uid_t uid;
- if (!pdb_context) {
- return False;
+ sid_compose(&group_sid, get_global_sam_sid(), group_rid);
+ sid_compose(&member_sid, get_global_sam_sid(), member_rid);
+
+ if (!get_domain_group_from_sid(group_sid, &map) ||
+ (map.gid == (gid_t)-1) ||
+ ((grp = getgrgid(map.gid)) == NULL)) {
+ return NT_STATUS_NO_SUCH_GROUP;
}
- if ((sam_account_cache != NULL) &&
- (sid_equal(sid, pdb_get_user_sid(sam_account_cache))))
- return pdb_copy_sam_account(sam_account_cache, &sam_acct);
+ group_name = talloc_strdup(mem_ctx, grp->gr_name);
+ if (group_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid));
-}
+ if ( !(account = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
-BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ if (!pdb_getsampwsid(account, &member_sid) ||
+ !sid_to_uid(&member_sid, &uid) ||
+ ((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
- if (!pdb_context) {
- return False;
+ if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
+ return NT_STATUS_MEMBER_IN_GROUP;
}
-
- return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct));
-}
-BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ /*
+ * ok, the group exist, the user exist, the user is not in the group,
+ * we can (finally) add it to the group !
+ */
- if (!pdb_context) {
- return False;
- }
+ smb_add_user_group(group_name, pwd->pw_name);
- if (sam_account_cache != NULL) {
- pdb_free_sam(&sam_account_cache);
- sam_account_cache = NULL;
+ if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
+ return NT_STATUS_ACCESS_DENIED;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct));
+ return NT_STATUS_OK;
}
-BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
+NTSTATUS pdb_add_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
+ uint32 member_rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return False;
- }
+ struct pdb_methods *pdb = pdb_get_methods();
- if (sam_account_cache != NULL) {
- pdb_free_sam(&sam_account_cache);
- sam_account_cache = NULL;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
+ return pdb->add_groupmem(pdb, mem_ctx, group_rid, member_rid);
}
-NTSTATUS pdb_rename_sam_account(SAM_ACCOUNT *oldname, const char *newname)
+static NTSTATUS pdb_default_del_groupmem(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ uint32 group_rid,
+ uint32 member_rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ DOM_SID group_sid, member_sid;
+ struct samu *account = NULL;
+ GROUP_MAP map;
+ struct group *grp;
+ struct passwd *pwd;
+ const char *group_name;
+ uid_t uid;
- if (!pdb_context) {
- return NT_STATUS_NOT_IMPLEMENTED;
+ sid_compose(&group_sid, get_global_sam_sid(), group_rid);
+ sid_compose(&member_sid, get_global_sam_sid(), member_rid);
+
+ if (!get_domain_group_from_sid(group_sid, &map) ||
+ (map.gid == (gid_t)-1) ||
+ ((grp = getgrgid(map.gid)) == NULL)) {
+ return NT_STATUS_NO_SUCH_GROUP;
}
- if (sam_account_cache != NULL) {
- pdb_free_sam(&sam_account_cache);
- sam_account_cache = NULL;
+ group_name = talloc_strdup(mem_ctx, grp->gr_name);
+ if (group_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
- return pdb_context->pdb_rename_sam_account(pdb_context, oldname, newname);
-}
+ if ( !(account = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
-NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ if (!pdb_getsampwsid(account, &member_sid) ||
+ !sid_to_uid(&member_sid, &uid) ||
+ ((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
- if (!pdb_context) {
- return NT_STATUS_NOT_IMPLEMENTED;
+ if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
+ return NT_STATUS_MEMBER_NOT_IN_GROUP;
+ }
+
+ /*
+ * ok, the group exist, the user exist, the user is in the group,
+ * we can (finally) delete it from the group!
+ */
+
+ smb_delete_user_group(group_name, pwd->pw_name);
+
+ if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
+ return NT_STATUS_ACCESS_DENIED;
}
- return pdb_context->pdb_update_login_attempts(pdb_context, sam_acct, success);
+ return NT_STATUS_OK;
}
-BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
+NTSTATUS pdb_del_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
+ uint32 member_rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrsid(pdb_context, map, sid));
+ return pdb->del_groupmem(pdb, mem_ctx, group_rid, member_rid);
}
-BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
+BOOL pdb_find_alias(const char *name, DOM_SID *sid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrgid(pdb_context, map, gid));
+ return NT_STATUS_IS_OK(pdb->find_alias(pdb, name, sid));
}
-BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
+NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrnam(pdb_context, map, name));
+ return pdb->create_alias(pdb, name, rid);
}
-BOOL pdb_add_group_mapping_entry(GROUP_MAP *map)
+BOOL pdb_delete_alias(const DOM_SID *sid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_add_group_mapping_entry(pdb_context, map));
+ return NT_STATUS_IS_OK(pdb->delete_alias(pdb, sid));
+
}
-BOOL pdb_update_group_mapping_entry(GROUP_MAP *map)
+BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_update_group_mapping_entry(pdb_context, map));
+ return NT_STATUS_IS_OK(pdb->get_aliasinfo(pdb, sid, info));
}
-BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
+BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_delete_group_mapping_entry(pdb_context, sid));
+ return NT_STATUS_IS_OK(pdb->set_aliasinfo(pdb, sid, info));
}
-BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rmap,
- size_t *p_num_entries, BOOL unix_only)
+NTSTATUS pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_UNSUCCESSFUL;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_group_mapping(pdb_context, sid_name_use,
- pp_rmap, p_num_entries, unix_only));
+ return pdb->add_aliasmem(pdb, alias, member);
}
-NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 **pp_member_rids,
- size_t *p_num_members)
+NTSTATUS pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
- return pdb_context->pdb_enum_group_members(pdb_context, mem_ctx, sid,
- pp_member_rids, p_num_members);
+ return pdb->del_aliasmem(pdb, alias, member);
}
-NTSTATUS pdb_enum_group_memberships(const char *username, gid_t primary_gid,
- DOM_SID **pp_sids, gid_t **pp_gids,
- size_t *p_num_groups)
+NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias,
+ DOM_SID **pp_members, size_t *p_num_members)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
- return pdb_context->pdb_enum_group_memberships(pdb_context, username,
- primary_gid, pp_sids, pp_gids,
- p_num_groups);
+ return pdb->enum_aliasmem(pdb, alias,
+ pp_members, p_num_members);
}
-BOOL pdb_find_alias(const char *name, DOM_SID *sid)
+NTSTATUS pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ const DOM_SID *members, size_t num_members,
+ uint32 **pp_alias_rids,
+ size_t *p_num_alias_rids)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_find_alias(pdb_context,
- name, sid));
+ return pdb->enum_alias_memberships(pdb, mem_ctx,
+ domain_sid,
+ members, num_members,
+ pp_alias_rids,
+ p_num_alias_rids);
}
-NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
+NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char **names,
+ uint32 *attrs)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- return pdb_context->pdb_create_alias(pdb_context, name, rid);
+ return pdb->lookup_rids(pdb, domain_sid,
+ num_rids, rids, names, attrs);
}
-BOOL pdb_delete_alias(const DOM_SID *sid)
+NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
+ int num_names,
+ const char **names,
+ uint32 *rids,
+ uint32 *attrs)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return False;
+ if ( !pdb ) {
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_delete_alias(pdb_context,
- sid));
-
+ return pdb->lookup_names(pdb, domain_sid,
+ num_names, names, rids, attrs);
}
-BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
+BOOL pdb_get_account_policy(int policy_index, uint32 *value)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_get_aliasinfo(pdb_context, sid,
- info));
+ return NT_STATUS_IS_OK(pdb->get_account_policy(pdb, policy_index, value));
}
-BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
+BOOL pdb_set_account_policy(int policy_index, uint32 value)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_set_aliasinfo(pdb_context, sid,
- info));
+ return NT_STATUS_IS_OK(pdb->set_account_policy(pdb, policy_index, value));
}
-BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+BOOL pdb_get_seq_num(time_t *seq_num)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_add_aliasmem(pdb_context, alias, member));
+ return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num));
}
-BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
+BOOL pdb_uid_to_rid(uid_t uid, uint32 *rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_del_aliasmem(pdb_context, alias, member));
+ return pdb->uid_to_rid(pdb, uid, rid);
}
-BOOL pdb_enum_aliasmem(const DOM_SID *alias,
- DOM_SID **pp_members, size_t *p_num_members)
+BOOL pdb_gid_to_sid(gid_t gid, DOM_SID *sid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_aliasmem(pdb_context, alias,
- pp_members, p_num_members));
+ return pdb->gid_to_sid(pdb, gid, sid);
}
-BOOL pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
- const DOM_SID *members, size_t num_members,
- uint32 **pp_alias_rids, size_t *p_num_alias_rids)
+BOOL pdb_sid_to_id(const DOM_SID *sid, union unid_t *id,
+ enum SID_NAME_USE *type)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_alias_memberships(pdb_context, mem_ctx,
- domain_sid,
- members, num_members,
- pp_alias_rids,
- p_num_alias_rids));
+ return pdb->sid_to_id(pdb, sid, id, type);
}
-NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
- int num_rids,
- uint32 *rids,
- const char **names,
- uint32 *attrs)
+BOOL pdb_rid_algorithm(void)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
- if (!pdb_context) {
- return NT_STATUS_NOT_IMPLEMENTED;
+ if ( !pdb ) {
+ return False;
}
- return pdb_context->pdb_lookup_rids(pdb_context, domain_sid,
- num_rids, rids, names, attrs);
+ return pdb->rid_algorithm(pdb);
}
-BOOL pdb_get_account_policy(int policy_index, uint32 *value)
+/********************************************************************
+ Allocate a new RID from the passdb backend. Verify that it is free
+ by calling lookup_global_sam_rid() to verify that the RID is not
+ in use. This handles servers that have existing users or groups
+ with add RIDs (assigned from previous algorithmic mappings)
+********************************************************************/
+
+BOOL pdb_new_rid(uint32 *rid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
+ const char *name = NULL;
+ enum SID_NAME_USE type;
+ uint32 allocated_rid = 0;
+ int i;
+ TALLOC_CTX *ctx;
- if (!pdb_context) {
+ if ( !pdb ) {
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_get_account_policy(pdb_context, policy_index, value));
-}
+ if (pdb_rid_algorithm()) {
+ DEBUG(0, ("Trying to allocate a RID when algorithmic RIDs "
+ "are active\n"));
+ return False;
+ }
-BOOL pdb_set_account_policy(int policy_index, uint32 value)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ if (algorithmic_rid_base() != BASE_RID) {
+ DEBUG(0, ("'algorithmic rid base' is set but a passdb backend "
+ "without algorithmic RIDs is chosen.\n"));
+ DEBUGADD(0, ("Please map all used groups using 'net groupmap "
+ "add', set the maximum used RID using\n"));
+ DEBUGADD(0, ("'net setmaxrid' and remove the parameter\n"));
+ return False;
+ }
- if (!pdb_context) {
+ if ( (ctx = talloc_init("pdb_new_rid")) == NULL ) {
+ DEBUG(0,("pdb_new_rid: Talloc initialization failure\n"));
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_set_account_policy(pdb_context, policy_index, value));
-}
+ /* Attempt to get an unused RID (max tires is 250...yes that it is
+ and arbitrary number I pulkled out of my head). -- jerry */
-BOOL pdb_get_seq_num(time_t *seq_num)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ for ( i=0; allocated_rid==0 && i<250; i++ ) {
+ /* get a new RID */
+
+ if ( !pdb->new_rid(pdb, &allocated_rid) ) {
+ return False;
+ }
+
+ /* validate that the RID is not in use */
+
+ if ( lookup_global_sam_rid( ctx, allocated_rid, &name, &type, NULL ) ) {
+ allocated_rid = 0;
+ }
+ }
+
+ TALLOC_FREE( ctx );
- if (!pdb_context) {
+ if ( allocated_rid == 0 ) {
+ DEBUG(0,("pdb_new_rid: Failed to find unused RID\n"));
return False;
}
- return NT_STATUS_IS_OK(pdb_context->
- pdb_get_seq_num(pdb_context, seq_num));
+ *rid = allocated_rid;
+
+ return True;
}
+
/***************************************************************
Initialize the static context (at smbd startup etc).
@@ -1456,7 +1293,7 @@ BOOL pdb_get_seq_num(time_t *seq_num)
BOOL initialize_password_db(BOOL reload)
{
- return (pdb_get_static_context(reload) != NULL);
+ return (pdb_get_methods_reload(reload) != NULL);
}
@@ -1464,48 +1301,47 @@ BOOL initialize_password_db(BOOL reload)
Default implementations of some functions.
****************************************************************************/
-static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
+static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, struct samu *user, const char *sname)
{
return NT_STATUS_NO_SUCH_USER;
}
-static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
{
return NT_STATUS_NO_SUCH_USER;
}
-static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, struct samu *newpwd)
{
- DEBUG(0,("this backend (%s) should not be listed as the first passdb backend! You can't add users to it.\n", methods->name));
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, struct samu *newpwd)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd)
+static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, struct samu *pwd)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd, const char *newname)
+static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, struct samu *pwd, const char *newname)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success)
+static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, struct samu *newpwd, BOOL success)
{
return NT_STATUS_OK;
}
-static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
+static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint32 acb_mask)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
+static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, struct samu *user)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
@@ -1531,6 +1367,116 @@ static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq
return NT_STATUS_OK;
}
+static BOOL pdb_default_uid_to_rid(struct pdb_methods *methods, uid_t uid,
+ uint32 *rid)
+{
+ struct samu *sampw = NULL;
+ struct passwd *unix_pw;
+ BOOL ret;
+
+ unix_pw = sys_getpwuid( uid );
+
+ if ( !unix_pw ) {
+ DEBUG(4,("pdb_default_uid_to_rid: host has no idea of uid "
+ "%lu\n", (unsigned long)uid));
+ return False;
+ }
+
+ if ( !(sampw = samu_new( NULL )) ) {
+ DEBUG(0,("pdb_default_uid_to_rid: samu_new() failed!\n"));
+ return False;
+ }
+
+ become_root();
+ ret = NT_STATUS_IS_OK(
+ methods->getsampwnam(methods, sampw, unix_pw->pw_name ));
+ unbecome_root();
+
+ if (!ret) {
+ DEBUG(5, ("pdb_default_uid_to_rid: Did not find user "
+ "%s (%d)\n", unix_pw->pw_name, uid));
+ TALLOC_FREE(sampw);
+ return False;
+ }
+
+ ret = sid_peek_check_rid(get_global_sam_sid(),
+ pdb_get_user_sid(sampw), rid);
+
+ if (!ret) {
+ DEBUG(1, ("Could not peek rid out of sid %s\n",
+ sid_string_static(pdb_get_user_sid(sampw))));
+ }
+
+ TALLOC_FREE(sampw);
+ return ret;
+}
+
+static BOOL pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid,
+ DOM_SID *sid)
+{
+ GROUP_MAP map;
+
+ if (!NT_STATUS_IS_OK(methods->getgrgid(methods, &map, gid))) {
+ return False;
+ }
+
+ sid_copy(sid, &map.sid);
+ return True;
+}
+
+static BOOL pdb_default_sid_to_id(struct pdb_methods *methods,
+ const DOM_SID *sid,
+ union unid_t *id, enum SID_NAME_USE *type)
+{
+ TALLOC_CTX *mem_ctx;
+ BOOL ret = False;
+ const char *name;
+ uint32 rid;
+
+ mem_ctx = talloc_new(NULL);
+
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return False;
+ }
+
+ if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
+ /* Here we might have users as well as groups and aliases */
+ ret = lookup_global_sam_rid(mem_ctx, rid, &name, type, id);
+ goto done;
+ }
+
+ if (sid_peek_check_rid(&global_sid_Builtin, sid, &rid)) {
+ /* Here we only have aliases */
+ GROUP_MAP map;
+ if (!NT_STATUS_IS_OK(methods->getgrsid(methods, &map, *sid))) {
+ DEBUG(10, ("Could not find map for sid %s\n",
+ sid_string_static(sid)));
+ goto done;
+ }
+ if ((map.sid_name_use != SID_NAME_ALIAS) &&
+ (map.sid_name_use != SID_NAME_WKN_GRP)) {
+ DEBUG(10, ("Map for sid %s is a %s, expected an "
+ "alias\n", sid_string_static(sid),
+ sid_type_lookup(map.sid_name_use)));
+ goto done;
+ }
+
+ id->gid = map.gid;
+ *type = SID_NAME_ALIAS;
+ ret = True;
+ goto done;
+ }
+
+ DEBUG(5, ("Sid %s is neither ours nor builtin, don't know it\n",
+ sid_string_static(sid)));
+
+ done:
+
+ TALLOC_FREE(mem_ctx);
+ return ret;
+}
+
static void add_uid_to_array_unique(TALLOC_CTX *mem_ctx,
uid_t uid, uid_t **pp_uids, size_t *p_num)
{
@@ -1554,31 +1500,36 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
{
struct group *grp;
char **gr;
- struct sys_pwent *userlist, *user;
+ struct passwd *pwd;
+ char *winbindd_env;
*pp_uids = NULL;
*p_num = 0;
/* We only look at our own sam, so don't care about imported stuff */
+ winbindd_env = getenv(WINBINDD_DONT_ENV);
winbind_off();
if ((grp = getgrgid(gid)) == NULL) {
- winbind_on();
+ /* allow winbindd lookups, but only if they weren't already disabled */
+ if ( !(winbindd_env && strequal(winbindd_env, "1")) ) {
+ winbind_on();
+ }
+
return False;
}
/* Primary group members */
- userlist = getpwent_list();
-
- for (user = userlist; user != NULL; user = user->next) {
- if (user->pw_gid != gid)
- continue;
- add_uid_to_array_unique(mem_ctx, user->pw_uid, pp_uids, p_num);
+ setpwent();
+ while ((pwd = getpwent()) != NULL) {
+ if (pwd->pw_gid == gid) {
+ add_uid_to_array_unique(mem_ctx, pwd->pw_uid,
+ pp_uids, p_num);
+ }
}
-
- pwent_free(userlist);
+ endpwent();
/* Secondary group members */
@@ -1590,7 +1541,11 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num);
}
- winbind_on();
+ /* allow winbindd lookups, but only if they weren't already disabled */
+
+ if ( !(winbindd_env && strequal(winbindd_env, "1")) ) {
+ winbind_on();
+ }
return True;
}
@@ -1608,7 +1563,7 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
*pp_member_rids = NULL;
*p_num_members = 0;
- if (!NT_STATUS_IS_OK(sid_to_gid(group, &gid)))
+ if (!sid_to_gid(group, &gid))
return NT_STATUS_NO_SUCH_GROUP;
if(!get_memberuids(mem_ctx, gid, &uids, &num_uids))
@@ -1622,13 +1577,10 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
for (i=0; i<num_uids; i++) {
DOM_SID sid;
- if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
- DEBUG(1, ("Could not map member uid to SID\n"));
- continue;
- }
+ uid_to_sid(&sid, uids[i]);
if (!sid_check_is_in_our_domain(&sid)) {
- DEBUG(1, ("Inconsistent SAM -- group member uid not "
+ DEBUG(5, ("Inconsistent SAM -- group member uid not "
"in our domain\n"));
continue;
}
@@ -1640,6 +1592,140 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
return NT_STATUS_OK;
}
+NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ struct samu *user,
+ DOM_SID **pp_sids,
+ gid_t **pp_gids,
+ size_t *p_num_groups)
+{
+ size_t i;
+ gid_t gid;
+ struct passwd *pw;
+ const char *username = pdb_get_username(user);
+
+
+ /* Ignore the primary group SID. Honor the real Unix primary group.
+ The primary group SID is only of real use to Windows clients */
+
+ if ( !(pw = getpwnam_alloc(mem_ctx, username)) ) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ gid = pw->pw_gid;
+
+ TALLOC_FREE( pw );
+
+ if (!getgroups_unix_user(mem_ctx, username, gid, pp_gids, p_num_groups)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (*p_num_groups == 0) {
+ smb_panic("primary group missing");
+ }
+
+ *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
+
+ if (*pp_sids == NULL) {
+ TALLOC_FREE(*pp_gids);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<*p_num_groups; i++) {
+ gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Look up a rid in the SAM we're responsible for (i.e. passdb)
+ ********************************************************************/
+
+static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
+ const char **name,
+ enum SID_NAME_USE *psid_name_use,
+ union unid_t *unix_id)
+{
+ struct samu *sam_account = NULL;
+ GROUP_MAP map;
+ BOOL ret;
+ DOM_SID sid;
+
+ *psid_name_use = SID_NAME_UNKNOWN;
+
+ DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
+ (unsigned int)rid));
+
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
+
+ /* see if the passdb can help us with the name of the user */
+
+ if ( !(sam_account = samu_new( NULL )) ) {
+ return False;
+ }
+
+ /* BEING ROOT BLLOCK */
+ become_root();
+ if (pdb_getsampwsid(sam_account, &sid)) {
+ struct passwd *pw;
+
+ unbecome_root(); /* -----> EXIT BECOME_ROOT() */
+ *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
+ *psid_name_use = SID_NAME_USER;
+
+ TALLOC_FREE(sam_account);
+
+ if (unix_id == NULL) {
+ return True;
+ }
+
+ pw = Get_Pwnam(*name);
+ if (pw == NULL) {
+ return False;
+ }
+ unix_id->uid = pw->pw_uid;
+ return True;
+ }
+ TALLOC_FREE(sam_account);
+
+ ret = pdb_getgrsid(&map, sid);
+ unbecome_root();
+ /* END BECOME_ROOT BLOCK */
+
+ /* do not resolve SIDs to a name unless there is a valid
+ gid associated with it */
+
+ if ( ret && (map.gid != (gid_t)-1) ) {
+ *name = talloc_strdup(mem_ctx, map.nt_name);
+ *psid_name_use = map.sid_name_use;
+
+ if ( unix_id ) {
+ unix_id->gid = map.gid;
+ }
+
+ return True;
+ }
+
+ /* Windows will always map RID 513 to something. On a non-domain
+ controller, this gets mapped to SERVER\None. */
+
+ if ( unix_id ) {
+ DEBUG(5, ("Can't find a unix id for an unmapped group\n"));
+ return False;
+ }
+
+ if ( rid == DOMAIN_GROUP_RID_USERS ) {
+ *name = talloc_strdup(mem_ctx, "None" );
+ *psid_name_use = SID_NAME_DOM_GRP;
+
+ return True;
+ }
+
+ return False;
+}
+
NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
const DOM_SID *domain_sid,
int num_rids,
@@ -1655,14 +1741,11 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
if (sid_check_is_builtin(domain_sid)) {
for (i=0; i<num_rids; i++) {
- fstring name;
+ const char *name;
- if (lookup_builtin_rid(rids[i], name)) {
+ if (lookup_builtin_rid(names, rids[i], &name)) {
attrs[i] = SID_NAME_ALIAS;
- names[i] = talloc_strdup(names, name);
- if (names[i] == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ names[i] = name;
DEBUG(5,("lookup_rids: %s:%d\n",
names[i], attrs[i]));
have_mapped = True;
@@ -1680,14 +1763,14 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
}
for (i = 0; i < num_rids; i++) {
- fstring tmpname;
- enum SID_NAME_USE type;
+ const char *name;
- if (lookup_global_sam_rid(rids[i], tmpname, &type)) {
- attrs[i] = (uint32)type;
- names[i] = talloc_strdup(names, tmpname);
- if (names[i] == NULL)
+ if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i],
+ NULL)) {
+ if (name == NULL) {
return NT_STATUS_NO_MEMORY;
+ }
+ names[i] = name;
DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
have_mapped = True;
} else {
@@ -1706,6 +1789,63 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
return result;
}
+NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
+ const DOM_SID *domain_sid,
+ int num_names,
+ const char **names,
+ uint32 *rids,
+ uint32 *attrs)
+{
+ int i;
+ NTSTATUS result;
+ BOOL have_mapped = False;
+ BOOL have_unmapped = False;
+
+ if (sid_check_is_builtin(domain_sid)) {
+
+ for (i=0; i<num_names; i++) {
+ uint32 rid;
+
+ if (lookup_builtin_name(names[i], &rid)) {
+ attrs[i] = SID_NAME_ALIAS;
+ rids[i] = rid;
+ DEBUG(5,("lookup_rids: %s:%d\n",
+ names[i], attrs[i]));
+ have_mapped = True;
+ } else {
+ have_unmapped = True;
+ attrs[i] = SID_NAME_UNKNOWN;
+ }
+ }
+ goto done;
+ }
+
+ /* Should not happen, but better check once too many */
+ if (!sid_check_is_domain(domain_sid)) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ for (i = 0; i < num_names; i++) {
+ if (lookup_global_sam_name(names[i], 0, &rids[i], &attrs[i])) {
+ DEBUG(5,("lookup_names: %s-> %d:%d\n", names[i],
+ rids[i], attrs[i]));
+ have_mapped = True;
+ } else {
+ have_unmapped = True;
+ attrs[i] = SID_NAME_UNKNOWN;
+ }
+ }
+
+ done:
+
+ result = NT_STATUS_NONE_MAPPED;
+
+ if (have_mapped)
+ result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
+
+ return result;
+}
+
static struct pdb_search *pdb_search_init(enum pdb_search_type type)
{
TALLOC_CTX *mem_ctx;
@@ -1772,24 +1912,22 @@ static BOOL next_entry_users(struct pdb_search *s,
struct samr_displayentry *entry)
{
struct user_search *state = s->private_data;
- SAM_ACCOUNT *user = NULL;
- NTSTATUS status;
+ struct samu *user = NULL;
next:
- status = pdb_init_sam(&user);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Could not pdb_init_sam\n"));
+ if ( !(user = samu_new( NULL )) ) {
+ DEBUG(0, ("next_entry_users: samu_new() failed!\n"));
return False;
}
if (!pdb_getsampwent(user)) {
- pdb_free_sam(&user);
+ TALLOC_FREE(user);
return False;
}
if ((state->acct_flags != 0) &&
((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
- pdb_free_sam(&user);
+ TALLOC_FREE(user);
goto next;
}
@@ -1798,7 +1936,7 @@ static BOOL next_entry_users(struct pdb_search *s,
pdb_get_fullname(user), pdb_get_acct_desc(user),
entry);
- pdb_free_sam(&user);
+ TALLOC_FREE(user);
return True;
}
@@ -1810,7 +1948,7 @@ static void search_end_users(struct pdb_search *search)
static BOOL pdb_default_search_users(struct pdb_methods *methods,
struct pdb_search *search,
- uint16 acct_flags)
+ uint32 acct_flags)
{
struct user_search *state;
@@ -1871,7 +2009,7 @@ static void search_end_groups(struct pdb_search *search)
}
static BOOL pdb_search_grouptype(struct pdb_search *search,
- enum SID_NAME_USE type)
+ const DOM_SID *sid, enum SID_NAME_USE type)
{
struct group_search *state;
@@ -1881,7 +2019,7 @@ static BOOL pdb_search_grouptype(struct pdb_search *search,
return False;
}
- if (!pdb_enum_group_mapping(type, &state->groups, &state->num_groups,
+ if (!pdb_enum_group_mapping(sid, type, &state->groups, &state->num_groups,
True)) {
DEBUG(0, ("Could not enum groups\n"));
return False;
@@ -1897,7 +2035,7 @@ static BOOL pdb_search_grouptype(struct pdb_search *search,
static BOOL pdb_default_search_groups(struct pdb_methods *methods,
struct pdb_search *search)
{
- return pdb_search_grouptype(search, SID_NAME_DOM_GRP);
+ return pdb_search_grouptype(search, get_global_sam_sid(), SID_NAME_DOM_GRP);
}
static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
@@ -1905,14 +2043,7 @@ static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
const DOM_SID *sid)
{
- if (sid_equal(sid, get_global_sam_sid()))
- return pdb_search_grouptype(search, SID_NAME_ALIAS);
-
- if (sid_equal(sid, &global_sid_Builtin))
- return pdb_search_grouptype(search, SID_NAME_WKN_GRP);
-
- DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
- return False;
+ return pdb_search_grouptype(search, sid, SID_NAME_ALIAS);
}
static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
@@ -1941,17 +2072,17 @@ static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
return (search->num_entries > idx) ? &search->cache[idx] : NULL;
}
-struct pdb_search *pdb_search_users(uint16 acct_flags)
+struct pdb_search *pdb_search_users(uint32 acct_flags)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
struct pdb_search *result;
- if (pdb_context == NULL) return NULL;
+ if (pdb == NULL) return NULL;
result = pdb_search_init(PDB_USER_SEARCH);
if (result == NULL) return NULL;
- if (!pdb_context->pdb_search_users(pdb_context, result, acct_flags)) {
+ if (!pdb->search_users(pdb, result, acct_flags)) {
talloc_destroy(result->mem_ctx);
return NULL;
}
@@ -1960,15 +2091,15 @@ struct pdb_search *pdb_search_users(uint16 acct_flags)
struct pdb_search *pdb_search_groups(void)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
struct pdb_search *result;
- if (pdb_context == NULL) return NULL;
+ if (pdb == NULL) return NULL;
result = pdb_search_init(PDB_GROUP_SEARCH);
if (result == NULL) return NULL;
- if (!pdb_context->pdb_search_groups(pdb_context, result)) {
+ if (!pdb->search_groups(pdb, result)) {
talloc_destroy(result->mem_ctx);
return NULL;
}
@@ -1977,15 +2108,15 @@ struct pdb_search *pdb_search_groups(void)
struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
+ struct pdb_methods *pdb = pdb_get_methods();
struct pdb_search *result;
- if (pdb_context == NULL) return NULL;
+ if (pdb == NULL) return NULL;
result = pdb_search_init(PDB_ALIAS_SEARCH);
if (result == NULL) return NULL;
- if (!pdb_context->pdb_search_aliases(pdb_context, result, sid)) {
+ if (!pdb->search_aliases(pdb, result, sid)) {
talloc_destroy(result->mem_ctx);
return NULL;
}
@@ -2026,21 +2157,28 @@ void pdb_search_destroy(struct pdb_search *search)
talloc_destroy(search->mem_ctx);
}
-NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
+/*******************************************************************
+ Create a pdb_methods structure and initialize it with the default
+ operations. In this way a passdb module can simply implement
+ the functionality it cares about. However, normally this is done
+ in groups of related functions.
+*******************************************************************/
+
+NTSTATUS make_pdb_method( struct pdb_methods **methods )
{
- *methods = TALLOC_P(mem_ctx, struct pdb_methods);
+ /* allocate memory for the structure as its own talloc CTX */
- if (!*methods) {
+ if ( !(*methods = TALLOC_ZERO_P(NULL, struct pdb_methods) ) ) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(*methods);
-
(*methods)->setsampwent = pdb_default_setsampwent;
(*methods)->endsampwent = pdb_default_endsampwent;
(*methods)->getsampwent = pdb_default_getsampwent;
(*methods)->getsampwnam = pdb_default_getsampwnam;
(*methods)->getsampwsid = pdb_default_getsampwsid;
+ (*methods)->create_user = pdb_default_create_user;
+ (*methods)->delete_user = pdb_default_delete_user;
(*methods)->add_sam_account = pdb_default_add_sam_account;
(*methods)->update_sam_account = pdb_default_update_sam_account;
(*methods)->delete_sam_account = pdb_default_delete_sam_account;
@@ -2050,12 +2188,17 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*methods)->getgrsid = pdb_default_getgrsid;
(*methods)->getgrgid = pdb_default_getgrgid;
(*methods)->getgrnam = pdb_default_getgrnam;
+ (*methods)->create_dom_group = pdb_default_create_dom_group;
+ (*methods)->delete_dom_group = pdb_default_delete_dom_group;
(*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
(*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
(*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
(*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
(*methods)->enum_group_members = pdb_default_enum_group_members;
(*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
+ (*methods)->set_unix_primary_group = pdb_default_set_unix_primary_group;
+ (*methods)->add_groupmem = pdb_default_add_groupmem;
+ (*methods)->del_groupmem = pdb_default_del_groupmem;
(*methods)->find_alias = pdb_default_find_alias;
(*methods)->create_alias = pdb_default_create_alias;
(*methods)->delete_alias = pdb_default_delete_alias;
@@ -2069,6 +2212,9 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*methods)->get_account_policy = pdb_default_get_account_policy;
(*methods)->set_account_policy = pdb_default_set_account_policy;
(*methods)->get_seq_num = pdb_default_get_seq_num;
+ (*methods)->uid_to_rid = pdb_default_uid_to_rid;
+ (*methods)->gid_to_sid = pdb_default_gid_to_sid;
+ (*methods)->sid_to_id = pdb_default_sid_to_id;
(*methods)->search_users = pdb_default_search_users;
(*methods)->search_groups = pdb_default_search_groups;
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 05fc8943829..1e3a5fdb6f0 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1,11 +1,12 @@
/*
Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
- Copyright (C) Jean François Micouleau 1998
+ Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001-2003
Copyright (C) Shahms King 2001
Copyright (C) Andrew Bartlett 2002-2003
Copyright (C) Stefan (metze) Metzmacher 2002-2003
+ Copyright (C) Simo Sorce 2006
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
@@ -30,7 +31,7 @@
* Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
*
* Other LDAP based login attributes: accountExpires, etc.
-* (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
+* (should be the domain of Samba proper, but the sam_password/struct samu
* structures don't have fields for some of these attributes)
*
* SSL is done, but can't get the certificate based authentication to work
@@ -77,20 +78,15 @@
#endif
-#ifndef SAM_ACCOUNT
-#define SAM_ACCOUNT struct sam_passwd
-#endif
-
#include "smbldap.h"
/**********************************************************************
- Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
+ Simple helper function to make stuff better readable
**********************************************************************/
-
-void private_data_free_fn(void **result)
+
+static LDAP *priv2ld(struct ldapsam_privates *priv)
{
- ldap_msgfree(*result);
- *result = NULL;
+ return priv->smbldap_state->ldap_struct;
}
/**********************************************************************
@@ -117,14 +113,14 @@ static const char* get_userattr_key2string( int schema_ver, int key )
Return the list of attribute names given a user schema version.
**********************************************************************/
-const char** get_userattr_list( int schema_ver )
+const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
{
switch ( schema_ver ) {
case SCHEMAVER_SAMBAACCOUNT:
- return get_attr_list( attrib_map_v22 );
+ return get_attr_list( mem_ctx, attrib_map_v22 );
case SCHEMAVER_SAMBASAMACCOUNT:
- return get_attr_list( attrib_map_v30 );
+ return get_attr_list( mem_ctx, attrib_map_v30 );
default:
DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
break;
@@ -137,14 +133,17 @@ const char** get_userattr_list( int schema_ver )
Return the list of attribute names to delete given a user schema version.
**************************************************************************/
-static const char** get_userattr_delete_list( int schema_ver )
+static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
+ int schema_ver )
{
switch ( schema_ver ) {
case SCHEMAVER_SAMBAACCOUNT:
- return get_attr_list( attrib_map_to_delete_v22 );
+ return get_attr_list( mem_ctx,
+ attrib_map_to_delete_v22 );
case SCHEMAVER_SAMBASAMACCOUNT:
- return get_attr_list( attrib_map_to_delete_v30 );
+ return get_attr_list( mem_ctx,
+ attrib_map_to_delete_v30 );
default:
DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
break;
@@ -250,13 +249,6 @@ static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_
LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
if (rc != LDAP_SUCCESS) {
-
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct,
- LDAP_OPT_ERROR_STRING, &ld_error);
- DEBUG(0,("ldapsam_get_seq_num: Failed search for suffix: %s, error: %s (%s)\n",
- suffix,ldap_err2string(rc), ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
goto done;
}
@@ -399,58 +391,37 @@ static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
object found in search_result depending on lp_ldap_delete_dn
******************************************************************/
-static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
- LDAPMessage *result,
- const char *objectclass,
- const char **attrs)
+static int ldapsam_delete_entry(struct ldapsam_privates *priv,
+ TALLOC_CTX *mem_ctx,
+ LDAPMessage *entry,
+ const char *objectclass,
+ const char **attrs)
{
- int rc;
- LDAPMessage *entry = NULL;
LDAPMod **mods = NULL;
- char *name, *dn;
+ char *name;
+ const char *dn;
BerElement *ptr = NULL;
- rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if (rc != 1) {
- DEBUG(0, ("ldapsam_delete_entry: Entry must exist exactly once!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- return NT_STATUS_UNSUCCESSFUL;
+ dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry);
+ if (dn == NULL) {
+ return LDAP_NO_MEMORY;
}
if (lp_ldap_delete_dn()) {
- NTSTATUS ret = NT_STATUS_OK;
- rc = smbldap_delete(ldap_state->smbldap_state, dn);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_delete_entry: Could not delete object %s\n", dn));
- ret = NT_STATUS_UNSUCCESSFUL;
- }
- SAFE_FREE(dn);
- return ret;
+ return smbldap_delete(priv->smbldap_state, dn);
}
/* Ok, delete only the SAM attributes */
- for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
+ for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
name != NULL;
- name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr)) {
+ name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
const char **attrib;
/* We are only allowed to delete the attributes that
really exist. */
for (attrib = attrs; *attrib != NULL; attrib++) {
- /* Don't delete LDAP_ATTR_MOD_TIMESTAMP attribute. */
- if (strequal(*attrib, get_userattr_key2string(ldap_state->schema_ver,
- LDAP_ATTR_MOD_TIMESTAMP))) {
- continue;
- }
if (strequal(*attrib, name)) {
DEBUG(10, ("ldapsam_delete_entry: deleting "
"attribute %s\n", name));
@@ -458,96 +429,20 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
NULL);
}
}
-
ldap_memfree(name);
}
-
+
if (ptr != NULL) {
ber_free(ptr, 0);
}
smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
-
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
- ldap_mods_free(mods, True);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
-
- DEBUG(0, ("ldapsam_delete_entry: Could not delete attributes for %s, error: %s (%s)\n",
- dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
- SAFE_FREE(dn);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- SAFE_FREE(dn);
- return NT_STATUS_OK;
-}
-
-/* New Interface is being implemented here */
-
-#if 0 /* JERRY - not uesed anymore */
-
-/**********************************************************************
-Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
-*********************************************************************/
-static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
- SAM_ACCOUNT * sampass,
- LDAPMessage * entry,
- gid_t *gid)
-{
- pstring homedir;
- pstring temp;
- char **ldap_values;
- char **values;
-
- if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
- DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
- return False;
- }
-
- for (values=ldap_values;*values;values++) {
- if (strequal(*values, LDAP_OBJ_POSIXACCOUNT )) {
- break;
- }
- }
-
- if (!*values) { /*end of array, no posixAccount */
- DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
- ldap_value_free(ldap_values);
- return False;
- }
- ldap_value_free(ldap_values);
-
- if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
- {
- return False;
- }
-
- if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
- {
- return False;
- }
-
- *gid = (gid_t)atol(temp);
-
- pdb_set_unix_homedir(sampass, homedir, PDB_SET);
+ talloc_autofree_ldapmod(mem_ctx, mods);
- DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
-
- return True;
+ return smbldap_modify(priv->smbldap_state, dn, mods);
}
-
-#endif
-
-static time_t ldapsam_get_entry_timestamp(
- struct ldapsam_privates *ldap_state,
- LDAPMessage * entry)
+
+static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
{
pstring temp;
struct tm tm;
@@ -563,12 +458,12 @@ static time_t ldapsam_get_entry_timestamp(
}
/**********************************************************************
- Initialize SAM_ACCOUNT from an LDAP query.
+ Initialize struct samu from an LDAP query.
(Based on init_sam_from_buffer in pdb_tdb.c)
*********************************************************************/
static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
- SAM_ACCOUNT * sampass,
+ struct samu * sampass,
LDAPMessage * entry)
{
time_t logon_time,
@@ -594,8 +489,8 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
uint8 smblmpwd[LM_HASH_LEN],
smbntpwd[NT_HASH_LEN];
BOOL use_samba_attrs = True;
- uint16 acct_ctrl = 0,
- logon_divs;
+ uint32 acct_ctrl = 0;
+ uint16 logon_divs;
uint16 bad_password_count = 0,
logon_count = 0;
uint32 hours_len;
@@ -627,13 +522,16 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
return False;
}
- if (ldap_state->smbldap_state->ldap_struct == NULL) {
- DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
+ if (priv2ld(ldap_state) == NULL) {
+ DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
+ "ldap_struct is NULL!\n"));
return False;
}
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
- DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
+ if (!smbldap_get_single_pstring(priv2ld(ldap_state), entry, "uid",
+ username)) {
+ DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
+ "this user!\n"));
return False;
}
@@ -655,36 +553,12 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
}
-
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp)) {
- pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
- } else {
- pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
- }
} else {
if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
user_rid = (uint32)atol(temp);
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
}
-
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp)) {
- pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
- } else {
- uint32 group_rid;
-
- group_rid = (uint32)atol(temp);
-
- /* for some reason, we often have 0 as a primary group RID.
- Make sure that we treat this just as a 'default' value */
-
- if ( group_rid > 0 )
- pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
- else
- pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
- }
}
if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
@@ -773,7 +647,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
{
pdb_set_homedir( sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, lp_logon_home()),
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, homedir );
@@ -788,7 +662,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
{
pdb_set_logon_script( sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, lp_logon_script()),
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, logon_script );
@@ -803,7 +677,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
{
pdb_set_profile_path( sampass,
- talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()),
+ talloc_sub_basic( sampass, username, lp_logon_path()),
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, profile_path );
@@ -992,6 +866,15 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
ZERO_STRUCT(hours);
}
+ if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
+ if (smbldap_get_single_pstring(priv2ld(ldap_state), entry,
+ "uidNumber", temp)) {
+ /* We've got a uid, feed the cache */
+ uid_t uid = strtoul(temp, NULL, 10);
+ store_uid_sid_cache(pdb_get_user_sid(sampass), uid);
+ }
+ }
+
/* check the timestamp of the cache vs ldap entry */
if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
entry)))
@@ -1033,14 +916,14 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
}
/**********************************************************************
- Initialize the ldap db from a SAM_ACCOUNT. Called on update.
+ Initialize the ldap db from a struct samu. Called on update.
(Based on init_buffer_from_sam in pdb_tdb.c)
*********************************************************************/
static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
LDAPMessage *existing,
- LDAPMod *** mods, SAM_ACCOUNT * sampass,
- BOOL (*need_update)(const SAM_ACCOUNT *,
+ LDAPMod *** mods, struct samu * sampass,
+ BOOL (*need_update)(const struct samu *,
enum pdb_elements))
{
pstring temp;
@@ -1057,9 +940,16 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
* took out adding "objectclass: sambaAccount"
* do this on a per-mod basis
*/
- if (need_update(sampass, PDB_USERNAME))
+ if (need_update(sampass, PDB_USERNAME)) {
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
"uid", pdb_get_username(sampass));
+ if (ldap_state->is_nds_ldap) {
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+ "cn", pdb_get_username(sampass));
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+ "sn", pdb_get_username(sampass));
+ }
+ }
DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
@@ -1354,7 +1244,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
Connect to LDAP server for password enumeration.
*********************************************************************/
-static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
+static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
{
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
@@ -1380,10 +1270,10 @@ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update,
DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n",
acb_mask, suffix));
- attr_list = get_userattr_list(ldap_state->schema_ver);
+ attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter,
attr_list, 0, &ldap_state->result);
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
if (rc != LDAP_SUCCESS) {
DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
@@ -1421,10 +1311,12 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods)
Get the next entry in the LDAP password database.
*********************************************************************/
-static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods,
+ struct samu *user)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)my_methods->private_data;
BOOL bret = False;
while (!bret) {
@@ -1434,14 +1326,15 @@ static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT
ldap_state->index++;
bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
- ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- ldap_state->entry);
+ ldap_state->entry = ldap_next_entry(priv2ld(ldap_state),
+ ldap_state->entry);
}
return NT_STATUS_OK;
}
-static void append_attr(const char ***attr_list, const char *new_attr)
+static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
+ const char *new_attr)
{
int i;
@@ -1453,17 +1346,18 @@ static void append_attr(const char ***attr_list, const char *new_attr)
;
}
- (*attr_list) = SMB_REALLOC_ARRAY((*attr_list), const char *, i+2);
+ (*attr_list) = TALLOC_REALLOC_ARRAY(mem_ctx, (*attr_list),
+ const char *, i+2);
SMB_ASSERT((*attr_list) != NULL);
- (*attr_list)[i] = SMB_STRDUP(new_attr);
+ (*attr_list)[i] = talloc_strdup((*attr_list), new_attr);
(*attr_list)[i+1] = NULL;
}
/**********************************************************************
-Get SAM_ACCOUNT entry from LDAP by username.
+Get struct samu entry from LDAP by username.
*********************************************************************/
-static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
+static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu *user, const char *sname)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
@@ -1473,10 +1367,14 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
const char ** attr_list;
int rc;
- attr_list = get_userattr_list( ldap_state->schema_ver );
- append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
- rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
- free_attr_list( attr_list );
+ attr_list = get_userattr_list( user, ldap_state->schema_ver );
+ append_attr(user, &attr_list,
+ get_userattr_key2string(ldap_state->schema_ver,
+ LDAP_ATTR_MOD_TIMESTAMP));
+ append_attr(user, &attr_list, "uidNumber");
+ rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
+ attr_list);
+ TALLOC_FREE( attr_list );
if ( rc != LDAP_SUCCESS )
return NT_STATUS_NO_SUCH_USER;
@@ -1500,9 +1398,9 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
ldap_msgfree(result);
return NT_STATUS_NO_SUCH_USER;
}
- pdb_set_backend_private_data(user, result,
- private_data_free_fn,
+ pdb_set_backend_private_data(user, result, NULL,
my_methods, PDB_CHANGED);
+ talloc_autofree_ldapmsg(user, result);
ret = NT_STATUS_OK;
} else {
ldap_msgfree(result);
@@ -1518,24 +1416,37 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
uint32 rid;
switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBASAMACCOUNT:
- attr_list = get_userattr_list(ldap_state->schema_ver);
- append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
- rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list);
- free_attr_list( attr_list );
+ case SCHEMAVER_SAMBASAMACCOUNT: {
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return LDAP_NO_MEMORY;
+ }
+
+ attr_list = get_userattr_list(tmp_ctx,
+ ldap_state->schema_ver);
+ append_attr(tmp_ctx, &attr_list,
+ get_userattr_key2string(
+ ldap_state->schema_ver,
+ LDAP_ATTR_MOD_TIMESTAMP));
+ append_attr(tmp_ctx, &attr_list, "uidNumber");
+ rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
+ result, attr_list);
+ TALLOC_FREE(tmp_ctx);
if ( rc != LDAP_SUCCESS )
return rc;
break;
+ }
case SCHEMAVER_SAMBAACCOUNT:
if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
return rc;
}
- attr_list = get_userattr_list(ldap_state->schema_ver);
+ attr_list = get_userattr_list(NULL,
+ ldap_state->schema_ver);
rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
if ( rc != LDAP_SUCCESS )
return rc;
@@ -1545,10 +1456,10 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
}
/**********************************************************************
- Get SAM_ACCOUNT entry from LDAP by SID.
+ Get struct samu entry from LDAP by SID.
*********************************************************************/
-static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
{
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
LDAPMessage *result = NULL;
@@ -1588,9 +1499,9 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT
return NT_STATUS_NO_SUCH_USER;
}
- pdb_set_backend_private_data(user, result,
- private_data_free_fn,
+ pdb_set_backend_private_data(user, result, NULL,
my_methods, PDB_CHANGED);
+ talloc_autofree_ldapmsg(user, result);
return NT_STATUS_OK;
}
@@ -1605,14 +1516,14 @@ static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state)
**********************************************************************/
static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
- SAM_ACCOUNT *newpwd, char *dn,
+ struct samu *newpwd, char *dn,
LDAPMod **mods, int ldap_op,
- BOOL (*need_update)(const SAM_ACCOUNT *, enum pdb_elements))
+ BOOL (*need_update)(const struct samu *, enum pdb_elements))
{
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
- if (!my_methods || !newpwd || !dn) {
+ if (!newpwd || !dn) {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1621,10 +1532,16 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
/* may be password change below however */
} else {
switch(ldap_op) {
- case LDAP_MOD_ADD:
- smbldap_set_mod(&mods, LDAP_MOD_ADD,
- "objectclass",
- LDAP_OBJ_ACCOUNT);
+ case LDAP_MOD_ADD:
+ if (ldap_state->is_nds_ldap) {
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ "objectclass",
+ "inetOrgPerson");
+ } else {
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ "objectclass",
+ LDAP_OBJ_ACCOUNT);
+ }
rc = smbldap_add(ldap_state->smbldap_state,
dn, mods);
break;
@@ -1639,14 +1556,6 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
}
if (rc!=LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
- ldap_op == LDAP_MOD_ADD ? "add" : "modify",
- dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
return NT_STATUS_UNSUCCESSFUL;
}
}
@@ -1747,15 +1656,17 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
Delete entry from LDAP for username.
*********************************************************************/
-static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
+static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
+ struct samu * sam_acct)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *priv =
+ (struct ldapsam_privates *)my_methods->private_data;
const char *sname;
int rc;
- LDAPMessage *result = NULL;
- NTSTATUS ret;
+ LDAPMessage *msg, *entry;
+ NTSTATUS result = NT_STATUS_NO_MEMORY;
const char **attr_list;
- fstring objclass;
+ TALLOC_CTX *mem_ctx;
if (!sam_acct) {
DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
@@ -1764,35 +1675,42 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_A
sname = pdb_get_username(sam_acct);
- DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname));
+ DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
+ "LDAP.\n", sname));
- attr_list= get_userattr_delete_list( ldap_state->schema_ver );
- rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ goto done;
+ }
- if (rc != LDAP_SUCCESS) {
- free_attr_list( attr_list );
- return NT_STATUS_NO_SUCH_USER;
+ attr_list = get_userattr_delete_list(mem_ctx, priv->schema_ver );
+ if (attr_list == NULL) {
+ goto done;
}
-
- switch ( ldap_state->schema_ver ) {
- case SCHEMAVER_SAMBASAMACCOUNT:
- fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
- break;
-
- case SCHEMAVER_SAMBAACCOUNT:
- fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
- break;
- default:
- fstrcpy( objclass, "UNKNOWN" );
- DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
- break;
+
+ rc = ldapsam_search_suffix_by_name(priv, sname, &msg, attr_list);
+
+ if ((rc != LDAP_SUCCESS) ||
+ (ldap_count_entries(priv2ld(priv), msg) != 1) ||
+ ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
+ DEBUG(5, ("Could not find user %s\n", sname));
+ result = NT_STATUS_NO_SUCH_USER;
+ goto done;
}
+
+ rc = ldapsam_delete_entry(
+ priv, mem_ctx, entry,
+ priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
+ LDAP_OBJ_SAMBASAMACCOUNT : LDAP_OBJ_SAMBAACCOUNT,
+ attr_list);
- ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
- ldap_msgfree(result);
- free_attr_list( attr_list );
+ result = (rc == LDAP_SUCCESS) ?
+ NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
- return ret;
+ done:
+ TALLOC_FREE(mem_ctx);
+ return result;
}
/**********************************************************************
@@ -1800,17 +1718,17 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_A
we need LDAP modification.
*********************************************************************/
-static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
+static BOOL element_is_changed(const struct samu *sampass,
enum pdb_elements element)
{
return IS_SAM_CHANGED(sampass, element);
}
/**********************************************************************
- Update SAM_ACCOUNT.
+ Update struct samu.
*********************************************************************/
-static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
+static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
@@ -1823,13 +1741,15 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
result = pdb_get_backend_private_data(newpwd, my_methods);
if (!result) {
- attr_list = get_userattr_list(ldap_state->schema_ver);
+ attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
if (rc != LDAP_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
}
- pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED);
+ pdb_set_backend_private_data(newpwd, result, NULL,
+ my_methods, PDB_CHANGED);
+ talloc_autofree_ldapmsg(newpwd, result);
}
if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
@@ -1866,12 +1786,6 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
SAFE_FREE(dn);
if (!NT_STATUS_IS_OK(ret)) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
- pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
- SAFE_FREE(ld_error);
return ret;
}
@@ -1881,12 +1795,12 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
}
/***************************************************************************
- Renames a SAM_ACCOUNT
+ Renames a struct samu
- The "rename user script" has full responsibility for changing everything
***************************************************************************/
static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
- SAM_ACCOUNT *old_acct,
+ struct samu *old_acct,
const char *newname)
{
const char *oldname;
@@ -1913,8 +1827,11 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
oldname, newname));
- pstring_sub(rename_script, "%unew", newname);
- pstring_sub(rename_script, "%uold", oldname);
+ /* we have to allow the account name to end with a '$' */
+ string_sub2(rename_script, "%unew", newname, sizeof(pstring),
+ True, False, True);
+ string_sub2(rename_script, "%uold", oldname, sizeof(pstring),
+ True, False, True);
rc = smbrun(rename_script, NULL);
DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
@@ -1931,7 +1848,7 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
we need LDAP modification.
*********************************************************************/
-static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
+static BOOL element_is_set_or_changed(const struct samu *sampass,
enum pdb_elements element)
{
return (IS_SAM_SET(sampass, element) ||
@@ -1939,10 +1856,10 @@ static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
}
/**********************************************************************
- Add SAM_ACCOUNT to LDAP.
+ Add struct samu to LDAP.
*********************************************************************/
-static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
+static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
@@ -1966,12 +1883,12 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
}
/* free this list after the second search or in case we exit on failure */
- attr_list = get_userattr_list(ldap_state->schema_ver);
+ attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
if (rc != LDAP_SUCCESS) {
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1979,7 +1896,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
username));
ldap_msgfree(result);
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
return NT_STATUS_UNSUCCESSFUL;
}
ldap_msgfree(result);
@@ -1992,7 +1909,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
sid_to_string(sid_string, sid)));
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2011,7 +1928,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
rc = smbldap_search_suffix(ldap_state->smbldap_state,
filter, attr_list, &result);
if ( rc != LDAP_SUCCESS ) {
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2019,7 +1936,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
if (num_result > 1) {
DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2033,7 +1950,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
if (!tmp) {
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2059,15 +1976,15 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
filter, attr_list, &result);
if ( rc != LDAP_SUCCESS ) {
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
return NT_STATUS_UNSUCCESSFUL;
}
num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (num_result > 1) {
- DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
- free_attr_list( attr_list );
+ DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
+ TALLOC_FREE( attr_list );
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2081,7 +1998,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
if (!tmp) {
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2090,7 +2007,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
}
}
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
if (num_result == 0) {
/* Check if we need to add an entry */
@@ -2155,23 +2072,11 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
int rc;
const char **attr_list;
- attr_list = get_attr_list(groupmap_attr_list);
+ attr_list = get_attr_list(NULL, groupmap_attr_list);
rc = smbldap_search(ldap_state->smbldap_state,
lp_ldap_group_suffix (), scope,
filter, attr_list, 0, result);
- free_attr_list( attr_list );
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0, ("ldapsam_search_one_group: "
- "Problem during the LDAP search: LDAP error: %s (%s)\n",
- ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
- DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
- lp_ldap_group_suffix(), filter));
- SAFE_FREE(ld_error);
- }
+ TALLOC_FREE(attr_list);
return rc;
}
@@ -2245,39 +2150,10 @@ for gidNumber(%lu)\n",(unsigned long)map->gid));
}
fstrcpy(map->comment, temp);
- return True;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static BOOL init_ldap_from_group(LDAP *ldap_struct,
- LDAPMessage *existing,
- LDAPMod ***mods,
- const GROUP_MAP *map)
-{
- pstring tmp;
-
- if (mods == NULL || map == NULL) {
- DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
- return False;
+ if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
+ store_gid_sid_cache(&map->sid, map->gid);
}
- *mods = NULL;
-
- sid_to_string(tmp, &map->sid);
-
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
- pstr_sprintf(tmp, "%i", map->sid_name_use);
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
-
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
- smbldap_make_mod(ldap_struct, existing, mods,
- get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
-
return True;
}
@@ -2299,7 +2175,7 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
return NT_STATUS_NO_SUCH_GROUP;
}
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
+ count = ldap_count_entries(priv2ld(ldap_state), result);
if (count < 1) {
DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
@@ -2308,13 +2184,13 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
}
if (count > 1) {
- DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
- filter, count));
+ DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
+ "count=%d\n", filter, count));
ldap_msgfree(result);
return NT_STATUS_NO_SUCH_GROUP;
}
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
if (!entry) {
ldap_msgfree(result);
@@ -2322,8 +2198,8 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
}
if (!init_group_from_ldap(ldap_state, map, entry)) {
- DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
- filter));
+ DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
+ "group filter %s\n", filter));
ldap_msgfree(result);
return NT_STATUS_NO_SUCH_GROUP;
}
@@ -2448,216 +2324,256 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
struct smbldap_state *conn = ldap_state->smbldap_state;
- pstring filter;
- int rc, count;
- LDAPMessage *msg = NULL;
+ const char *id_attrs[] = { "memberUid", "gidNumber", NULL };
+ const char *sid_attrs[] = { "sambaSID", NULL };
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ LDAPMessage *result = NULL;
LDAPMessage *entry;
+ char *filter;
char **values = NULL;
char **memberuid;
- char *sid_filter = NULL;
- char *tmp;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
- return pdb_default_enum_group_members(methods, mem_ctx, group,
- pp_member_rids,
- p_num_members);
+ char *gidstr;
+ int rc, count;
*pp_member_rids = NULL;
*p_num_members = 0;
- pstr_sprintf(filter,
- "(&(objectClass=sambaSamAccount)"
- "(sambaPrimaryGroupSid=%s))",
- sid_string_static(group));
+ filter = talloc_asprintf(mem_ctx,
+ "(&(objectClass=%s)"
+ "(objectClass=%s)"
+ "(sambaSID=%s))",
+ LDAP_OBJ_POSIXGROUP,
+ LDAP_OBJ_GROUPMAP,
+ sid_string_static(group));
- {
- const char *attrs[] = { "sambaSID", NULL };
- rc = smbldap_search(conn, lp_ldap_user_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0,
- &msg);
- }
+ rc = smbldap_search(conn, lp_ldap_group_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
+ &result);
if (rc != LDAP_SUCCESS)
goto done;
- for (entry = ldap_first_entry(conn->ldap_struct, msg);
- entry != NULL;
- entry = ldap_next_entry(conn->ldap_struct, entry))
- {
- uint32 rid;
-
- if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
- entry,
- get_global_sam_sid(),
- &rid)) {
- DEBUG(2, ("Could not find sid from ldap entry\n"));
- continue;
- }
-
- add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
- p_num_members);
- }
-
- if (msg != NULL)
- ldap_msgfree(msg);
-
- pstr_sprintf(filter,
- "(&(objectClass=sambaGroupMapping)"
- "(objectClass=posixGroup)"
- "(sambaSID=%s))",
- sid_string_static(group));
-
- {
- const char *attrs[] = { "memberUid", NULL };
- rc = smbldap_search(conn, lp_ldap_user_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0,
- &msg);
- }
-
- if (rc != LDAP_SUCCESS)
- goto done;
+ talloc_autofree_ldapmsg(mem_ctx, result);
- count = ldap_count_entries(conn->ldap_struct, msg);
+ count = ldap_count_entries(conn->ldap_struct, result);
if (count > 1) {
DEBUG(1, ("Found more than one groupmap entry for %s\n",
sid_string_static(group)));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
goto done;
}
if (count == 0) {
- result = NT_STATUS_OK;
+ ret = NT_STATUS_NO_SUCH_GROUP;
goto done;
}
- entry = ldap_first_entry(conn->ldap_struct, msg);
+ entry = ldap_first_entry(conn->ldap_struct, result);
if (entry == NULL)
goto done;
- values = ldap_get_values(conn->ldap_struct, msg, "memberUid");
- if (values == NULL) {
- result = NT_STATUS_OK;
+ gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
+ if (!gidstr) {
+ DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
goto done;
}
- sid_filter = SMB_STRDUP("(&(objectClass=sambaSamAccount)(|");
- if (sid_filter == NULL) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
+ values = ldap_get_values(conn->ldap_struct, entry, "memberUid");
+
+ if (values) {
- for (memberuid = values; *memberuid != NULL; memberuid += 1) {
- tmp = sid_filter;
- asprintf(&sid_filter, "%s(uid=%s)", tmp, *memberuid);
- free(tmp);
- if (sid_filter == NULL) {
- result = NT_STATUS_NO_MEMORY;
+ filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBAACCOUNT);
+ if (filter == NULL) {
+ ret = NT_STATUS_NO_MEMORY;
goto done;
}
- }
- tmp = sid_filter;
- asprintf(&sid_filter, "%s))", sid_filter);
- free(tmp);
- if (sid_filter == NULL) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
+ for (memberuid = values; *memberuid != NULL; memberuid += 1) {
+ filter = talloc_asprintf_append(filter, "(uid=%s)", *memberuid);
+ if (filter == NULL) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ }
+
+ filter = talloc_asprintf_append(filter, "))");
+ if (filter == NULL) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
- {
- const char *attrs[] = { "sambaSID", NULL };
rc = smbldap_search(conn, lp_ldap_user_suffix(),
- LDAP_SCOPE_SUBTREE, sid_filter, attrs, 0,
- &msg);
+ LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
+ &result);
+
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ count = ldap_count_entries(conn->ldap_struct, result);
+ DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
+
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
+ for (entry = ldap_first_entry(conn->ldap_struct, result);
+ entry != NULL;
+ entry = ldap_next_entry(conn->ldap_struct, entry))
+ {
+ char *sidstr;
+ DOM_SID sid;
+ uint32 rid;
+
+ sidstr = smbldap_talloc_single_attribute(conn->ldap_struct,
+ entry, "sambaSID",
+ mem_ctx);
+ if (!sidstr) {
+ DEBUG(0, ("Severe DB error, sambaSamAccount can't miss "
+ "the sambaSID attribute\n"));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ if (!string_to_sid(&sid, sidstr))
+ goto done;
+
+ if (!sid_check_is_in_our_domain(&sid)) {
+ DEBUG(0, ("Inconsistent SAM -- group member uid not "
+ "in our domain\n"));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ sid_peek_rid(&sid, &rid);
+
+ add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
+ p_num_members);
+ }
}
+ filter = talloc_asprintf(mem_ctx,
+ "(&(objectClass=%s)"
+ "(gidNumber=%s))",
+ LDAP_OBJ_SAMBASAMACCOUNT,
+ gidstr);
+
+ rc = smbldap_search(conn, lp_ldap_user_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
+ &result);
+
if (rc != LDAP_SUCCESS)
goto done;
- for (entry = ldap_first_entry(conn->ldap_struct, msg);
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
+ for (entry = ldap_first_entry(conn->ldap_struct, result);
entry != NULL;
entry = ldap_next_entry(conn->ldap_struct, entry))
{
- fstring str;
- DOM_SID sid;
uint32 rid;
- if (!smbldap_get_single_attribute(conn->ldap_struct,
- entry, "sambaSID",
- str, sizeof(str)-1))
- continue;
-
- if (!string_to_sid(&sid, str))
+ if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
+ entry,
+ get_global_sam_sid(),
+ &rid)) {
+ DEBUG(0, ("Severe DB error, sambaSamAccount can't miss "
+ "the sambaSID attribute\n"));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
goto done;
-
- if (!sid_check_is_in_our_domain(&sid)) {
- DEBUG(1, ("Inconsistent SAM -- group member uid not "
- "in our domain\n"));
- continue;
}
- sid_peek_rid(&sid, &rid);
-
add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
p_num_members);
}
- result = NT_STATUS_OK;
+ ret = NT_STATUS_OK;
done:
- SAFE_FREE(sid_filter);
- if (values != NULL)
+ if (values)
ldap_value_free(values);
- if (msg != NULL)
- ldap_msgfree(msg);
-
- return result;
+ return ret;
}
static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
- const char *username,
- gid_t primary_gid,
- DOM_SID **pp_sids, gid_t **pp_gids,
+ TALLOC_CTX *mem_ctx,
+ struct samu *user,
+ DOM_SID **pp_sids,
+ gid_t **pp_gids,
size_t *p_num_groups)
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
struct smbldap_state *conn = ldap_state->smbldap_state;
- pstring filter;
+ char *filter;
const char *attrs[] = { "gidNumber", "sambaSID", NULL };
char *escape_name;
- int rc;
- LDAPMessage *msg = NULL;
+ int rc, count;
+ LDAPMessage *result = NULL;
LDAPMessage *entry;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
size_t num_sids, num_gids;
-
- if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
- return pdb_default_enum_group_memberships(methods, username,
- primary_gid, pp_sids,
- pp_gids, p_num_groups);
+ char *gidstr;
+ gid_t primary_gid = -1;
*pp_sids = NULL;
num_sids = 0;
- escape_name = escape_ldap_string_alloc(username);
-
+ escape_name = escape_ldap_string_alloc(pdb_get_username(user));
if (escape_name == NULL)
return NT_STATUS_NO_MEMORY;
- pstr_sprintf(filter, "(&(objectClass=posixGroup)"
- "(|(memberUid=%s)(gidNumber=%d)))",
- username, primary_gid);
+ /* retrieve the users primary gid */
+ filter = talloc_asprintf(mem_ctx,
+ "(&(objectClass=%s)(uid=%s))",
+ LDAP_OBJ_SAMBASAMACCOUNT,
+ escape_name);
+
+ rc = smbldap_search(conn, lp_ldap_user_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
+
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
+ count = ldap_count_entries(priv2ld(ldap_state), result);
+
+ switch (count) {
+ case 0:
+ DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
+ ret = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ case 1:
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+
+ gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
+ if (!gidstr) {
+ DEBUG (1, ("Unable to find the member's gid!\n"));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+ primary_gid = strtoul(gidstr, NULL, 10);
+ break;
+ default:
+ DEBUG(1, ("found more than one accoutn with the same user name ?!\n"));
+ ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ filter = talloc_asprintf(mem_ctx,
+ "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%d)))",
+ LDAP_OBJ_POSIXGROUP, escape_name, primary_gid);
rc = smbldap_search(conn, lp_ldap_group_suffix(),
- LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg);
+ LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
if (rc != LDAP_SUCCESS)
goto done;
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
num_gids = 0;
*pp_gids = NULL;
@@ -2666,13 +2582,13 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
/* We need to add the primary group as the first gid/sid */
- add_gid_to_array_unique(NULL, primary_gid, pp_gids, &num_gids);
+ add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids);
/* This sid will be replaced later */
- add_sid_to_array_unique(NULL, &global_sid_NULL, pp_sids, &num_sids);
+ add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids, &num_sids);
- for (entry = ldap_first_entry(conn->ldap_struct, msg);
+ for (entry = ldap_first_entry(conn->ldap_struct, result);
entry != NULL;
entry = ldap_next_entry(conn->ldap_struct, entry))
{
@@ -2702,167 +2618,218 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
if (gid == primary_gid) {
sid_copy(&(*pp_sids)[0], &sid);
} else {
- add_gid_to_array_unique(NULL, gid, pp_gids, &num_gids);
- add_sid_to_array_unique(NULL, &sid, pp_sids, &num_sids);
+ add_gid_to_array_unique(mem_ctx, gid, pp_gids,
+ &num_gids);
+ add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
+ &num_sids);
}
}
if (sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
- DEBUG(3, ("primary group of [%s] not found\n", username));
+ DEBUG(3, ("primary group of [%s] not found\n",
+ pdb_get_username(user)));
goto done;
}
*p_num_groups = num_sids;
- result = NT_STATUS_OK;
+ ret = NT_STATUS_OK;
done:
SAFE_FREE(escape_name);
- if (msg != NULL)
- ldap_msgfree(msg);
-
- return result;
+ return ret;
}
/**********************************************************************
+ * Augment a posixGroup object with a sambaGroupMapping domgroup
*********************************************************************/
-static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
- gid_t gid,
- LDAPMessage **result)
+static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
+ struct ldapsam_privates *ldap_state,
+ GROUP_MAP *map)
{
- pstring filter;
+ const char *filter, *dn;
+ LDAPMessage *msg, *entry;
+ LDAPMod **mods;
+ int rc;
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))",
- LDAP_OBJ_POSIXGROUP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- (unsigned long)gid);
+ filter = talloc_asprintf(mem_ctx,
+ "(&(objectClass=posixGroup)(gidNumber=%u))",
+ map->gid);
+ if (filter == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
- return ldapsam_search_one_group(ldap_state, filter, result);
-}
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
+ get_attr_list(mem_ctx, groupmap_attr_list),
+ &msg);
+ talloc_autofree_ldapmsg(mem_ctx, msg);
-/**********************************************************************
- *********************************************************************/
+ if ((rc != LDAP_SUCCESS) ||
+ (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) != 1) ||
+ ((entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg)) == NULL)) {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ dn = smbldap_talloc_dn(mem_ctx, ldap_state->smbldap_state->ldap_struct, entry);
+ if (dn == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ mods = NULL;
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
+ "sambaGroupMapping");
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaSid",
+ sid_string_static(&map->sid));
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaGroupType",
+ talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
+ map->nt_name);
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "description",
+ map->comment);
+ talloc_autofree_ldapmod(mem_ctx, mods);
+
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
+ if (rc != LDAP_SUCCESS) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_OK;
+}
static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
GROUP_MAP *map)
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
- LDAPMessage *result = NULL;
+ LDAPMessage *msg = NULL;
LDAPMod **mods = NULL;
- int count;
+ const char *attrs[] = { NULL };
+ char *filter;
- char *tmp;
- pstring dn;
- LDAPMessage *entry;
+ char *dn;
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS result;
- GROUP_MAP dummy;
+ DOM_SID sid;
int rc;
- if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
- map->gid))) {
- DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map->gid));
- return NT_STATUS_UNSUCCESSFUL;
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return NT_STATUS_NO_MEMORY;
}
- rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
- if (rc != LDAP_SUCCESS) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
+ sid_string_static(&map->sid));
+ if (filter == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
- if ( count == 0 ) {
- /* There's no posixGroup account, let's try to find an
- * appropriate idmap entry for aliases */
+ rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
+ talloc_autofree_ldapmsg(mem_ctx, msg);
- pstring suffix;
- pstring filter;
- const char **attr_list;
+ if ((rc == LDAP_SUCCESS) &&
+ (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) > 0)) {
- ldap_msgfree(result);
+ DEBUG(3, ("SID %s already present in LDAP, refusing to add "
+ "group mapping entry\n",
+ sid_string_static(&map->sid)));
+ result = NT_STATUS_GROUP_EXISTS;
+ goto done;
+ }
- pstrcpy( suffix, lp_ldap_idmap_suffix() );
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%u))",
- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_GIDNUMBER,
- map->gid);
-
- attr_list = get_attr_list( sidmap_attr_list );
- rc = smbldap_search(ldap_state->smbldap_state, suffix,
- LDAP_SCOPE_SUBTREE, filter, attr_list,
- 0, &result);
+ switch (map->sid_name_use) {
- free_attr_list(attr_list);
+ case SID_NAME_DOM_GRP:
+ /* To map a domain group we need to have a posix group
+ to attach to. */
+ result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
+ goto done;
+ break;
- if (rc != LDAP_SUCCESS) {
- DEBUG(3,("Failure looking up entry (%s)\n",
- ldap_err2string(rc) ));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ case SID_NAME_ALIAS:
+ if (!sid_check_is_in_our_domain(&map->sid)
+ && !sid_check_is_in_builtin(&map->sid) )
+ {
+ DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
+ sid_string_static(&map->sid)));
+ result = NT_STATUS_INVALID_PARAMETER;
+ goto done;
}
- }
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
- if ( count == 0 ) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
+ break;
- if (count > 1) {
- DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
- (unsigned long)map->gid));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ default:
+ DEBUG(3, ("Got invalid use '%s' for mapping\n",
+ sid_type_lookup(map->sid_name_use)));
+ result = NT_STATUS_INVALID_PARAMETER;
+ goto done;
}
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
- tmp = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!tmp) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ /* Domain groups have been mapped in a separate routine, we have to
+ * create an alias now */
+
+ if (map->gid == -1) {
+ DEBUG(10, ("Refusing to map gid==-1\n"));
+ result = NT_STATUS_INVALID_PARAMETER;
+ goto done;
}
- pstrcpy(dn, tmp);
- SAFE_FREE(tmp);
- if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
- result, &mods, map)) {
- DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
- ldap_mods_free(mods, True);
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ if (pdb_gid_to_sid(map->gid, &sid)) {
+ DEBUG(3, ("Gid %d is already mapped to SID %s, refusing to "
+ "add\n", map->gid, sid_string_static(&sid)));
+ result = NT_STATUS_GROUP_EXISTS;
+ goto done;
}
- ldap_msgfree(result);
+ /* Ok, enough checks done. It's still racy to go ahead now, but that's
+ * the best we can get out of LDAP. */
- if (mods == NULL) {
- DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
+ sid_string_static(&map->sid),
+ lp_ldap_group_suffix());
+ if (dn == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
- smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
+ mods = NULL;
- rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
- ldap_mods_free(mods, True);
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "objectClass",
+ "sambaSidEntry");
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "objectClass",
+ "sambaGroupMapping");
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid,
- ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
- SAFE_FREE(ld_error);
- return NT_STATUS_UNSUCCESSFUL;
- }
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaSid",
+ sid_string_static(&map->sid));
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaGroupType",
+ talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "displayName",
+ map->nt_name);
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "description",
+ map->comment);
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "gidNumber",
+ talloc_asprintf(mem_ctx, "%u", map->gid));
+ talloc_autofree_ldapmod(mem_ctx, mods);
- DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
- return NT_STATUS_OK;
+ rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
+
+ result = (rc == LDAP_SUCCESS) ?
+ NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
+
+ done:
+ TALLOC_FREE(mem_ctx);
+ return result;
}
/**********************************************************************
+ * Update a group mapping entry. We're quite strict about what can be changed:
+ * Only the description and displayname may be changed. It simply does not
+ * make any sense to change the SID, gid or the type in a mapping.
*********************************************************************/
static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
@@ -2871,63 +2838,81 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
int rc;
- char *dn = NULL;
- LDAPMessage *result = NULL;
+ const char *filter, *dn;
+ LDAPMessage *msg = NULL;
LDAPMessage *entry = NULL;
LDAPMod **mods = NULL;
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS result;
- rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
- if (rc != LDAP_SUCCESS) {
- return NT_STATUS_UNSUCCESSFUL;
+ /* Make 100% sure that sid, gid and type are not changed by looking up
+ * exactly the values we're given in LDAP. */
+
+ filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)"
+ "(sambaSid=%s)(gidNumber=%u)"
+ "(sambaGroupType=%d))",
+ LDAP_OBJ_GROUPMAP,
+ sid_string_static(&map->sid), map->gid,
+ map->sid_name_use);
+ if (filter == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
- if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
- DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
+ get_attr_list(mem_ctx, groupmap_attr_list),
+ &msg);
+ talloc_autofree_ldapmsg(mem_ctx, msg);
+
+ if ((rc != LDAP_SUCCESS) ||
+ (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) != 1) ||
+ ((entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg)) == NULL)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
}
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ dn = smbldap_talloc_dn(mem_ctx, ldap_state->smbldap_state->ldap_struct, entry);
- if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
- result, &mods, map)) {
- DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
- ldap_msgfree(result);
- if (mods != NULL)
- ldap_mods_free(mods,True);
- return NT_STATUS_UNSUCCESSFUL;
+ if (dn == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
+ mods = NULL;
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
+ map->nt_name);
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "description",
+ map->comment);
+ talloc_autofree_ldapmod(mem_ctx, mods);
+
if (mods == NULL) {
- DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
- ldap_msgfree(result);
- return NT_STATUS_OK;
+ DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
+ "nothing to do\n"));
+ result = NT_STATUS_OK;
+ goto done;
}
- dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!dn) {
- ldap_msgfree(result);
- return NT_STATUS_UNSUCCESSFUL;
- }
rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
- SAFE_FREE(dn);
-
- ldap_mods_free(mods, True);
- ldap_msgfree(result);
if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid,
- ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
- SAFE_FREE(ld_error);
- return NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_ACCESS_DENIED;
+ goto done;
}
- DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
- return NT_STATUS_OK;
+ DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
+ "group %lu in LDAP\n", (unsigned long)map->gid));
+
+ result = NT_STATUS_OK;
+
+ done:
+ TALLOC_FREE(mem_ctx);
+ return result;
}
/**********************************************************************
@@ -2936,53 +2921,103 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
DOM_SID sid)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
- pstring sidstring, filter;
- LDAPMessage *result = NULL;
+ struct ldapsam_privates *priv =
+ (struct ldapsam_privates *)methods->private_data;
+ LDAPMessage *msg, *entry;
int rc;
- NTSTATUS ret;
- const char **attr_list;
+ NTSTATUS result;
+ TALLOC_CTX *mem_ctx;
+ char *filter;
- sid_to_string(sidstring, &sid);
-
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
+ LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID,
+ sid_string_static(&sid));
+ if (filter == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ rc = smbldap_search_suffix(priv->smbldap_state, filter,
+ get_attr_list(mem_ctx, groupmap_attr_list),
+ &msg);
+ talloc_autofree_ldapmsg(mem_ctx, msg);
+
+ if ((rc != LDAP_SUCCESS) ||
+ (ldap_count_entries(priv2ld(priv), msg) != 1) ||
+ ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
+ result = NT_STATUS_NO_SUCH_GROUP;
+ goto done;
+ }
- rc = ldapsam_search_one_group(ldap_state, filter, &result);
+ rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
+ get_attr_list(mem_ctx,
+ groupmap_attr_list_to_delete));
+
+ if ((rc == LDAP_NAMING_VIOLATION) ||
+ (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
+ const char *attrs[] = { "sambaGroupType", "description",
+ "displayName", "sambaSIDList",
+ NULL };
- if (rc != LDAP_SUCCESS) {
- return NT_STATUS_NO_SUCH_GROUP;
+ /* Second try. Don't delete the sambaSID attribute, this is
+ for "old" entries that are tacked on a winbind
+ sambaIdmapEntry. */
+
+ rc = ldapsam_delete_entry(priv, mem_ctx, entry,
+ LDAP_OBJ_GROUPMAP, attrs);
}
- attr_list = get_attr_list( groupmap_attr_list_to_delete );
- ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
- free_attr_list ( attr_list );
+ if ((rc == LDAP_NAMING_VIOLATION) ||
+ (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
+ const char *attrs[] = { "sambaGroupType", "description",
+ "displayName", "sambaSIDList",
+ "gidNumber", NULL };
- ldap_msgfree(result);
+ /* Third try. This is a post-3.0.21 alias (containing only
+ * sambaSidEntry and sambaGroupMapping classes), we also have
+ * to delete the gidNumber attribute, only the sambaSidEntry
+ * remains */
- return ret;
-}
+ rc = ldapsam_delete_entry(priv, mem_ctx, entry,
+ LDAP_OBJ_GROUPMAP, attrs);
+ }
+
+ result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+
+ done:
+ TALLOC_FREE(mem_ctx);
+ return result;
+ }
/**********************************************************************
*********************************************************************/
-static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
+ BOOL update)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)my_methods->private_data;
fstring filter;
int rc;
const char **attr_list;
pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
- attr_list = get_attr_list( groupmap_attr_list );
+ attr_list = get_attr_list( NULL, groupmap_attr_list );
rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter,
attr_list, 0, &ldap_state->result);
- free_attr_list( attr_list );
+ TALLOC_FREE(attr_list);
if (rc != LDAP_SUCCESS) {
- DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
+ DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
+ ldap_err2string(rc)));
+ DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
+ lp_ldap_group_suffix(), filter));
ldap_msgfree(ldap_state->result);
ldap_state->result = NULL;
return NT_STATUS_UNSUCCESSFUL;
@@ -2992,7 +3027,9 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
ldap_state->result)));
- ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
+ ldap_state->entry =
+ ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
+ ldap_state->result);
ldap_state->index = 0;
return NT_STATUS_OK;
@@ -3013,7 +3050,8 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
GROUP_MAP *map)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)my_methods->private_data;
BOOL bret = False;
while (!bret) {
@@ -3021,10 +3059,12 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
return ret;
ldap_state->index++;
- bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
+ bret = init_group_from_ldap(ldap_state, map,
+ ldap_state->entry);
- ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- ldap_state->entry);
+ ldap_state->entry =
+ ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
+ ldap_state->entry);
}
return NT_STATUS_OK;
@@ -3034,43 +3074,44 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
*********************************************************************/
static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **pp_rmap, size_t *p_num_entries,
+ const DOM_SID *domsid, enum SID_NAME_USE sid_name_use,
+ GROUP_MAP **pp_rmap,
+ size_t *p_num_entries,
BOOL unix_only)
{
GROUP_MAP map;
- GROUP_MAP *mapt;
size_t entries = 0;
*p_num_entries = 0;
*pp_rmap = NULL;
if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
- DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
+ DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
+ "passdb\n"));
return NT_STATUS_ACCESS_DENIED;
}
while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
if (sid_name_use != SID_NAME_UNKNOWN &&
sid_name_use != map.sid_name_use) {
- DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
+ DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
+ "not of the requested type\n", map.nt_name));
continue;
}
if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
- DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map.nt_name));
+ DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
+ "non mapped\n", map.nt_name));
continue;
}
- mapt=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
- if (!mapt) {
- DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
- SAFE_FREE(*pp_rmap);
+ (*pp_rmap)=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
+ if (!(*pp_rmap)) {
+ DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
+ "enlarge group map!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
- else
- (*pp_rmap) = mapt;
- mapt[entries] = map;
+ (*pp_rmap)[entries] = map;
entries += 1;
@@ -3095,14 +3136,28 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
int count;
LDAPMod **mods = NULL;
int rc;
+ enum SID_NAME_USE type = SID_NAME_USE_NONE;
pstring filter;
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_GROUP_SID),
- sid_string_static(alias));
+ if (sid_check_is_in_builtin(alias)) {
+ type = SID_NAME_ALIAS;
+ }
+
+ if (sid_check_is_in_our_domain(alias)) {
+ type = SID_NAME_ALIAS;
+ }
+
+ if (type == SID_NAME_USE_NONE) {
+ DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
+ sid_string_static(alias)));
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ pstr_sprintf(filter,
+ "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
+ LDAP_OBJ_GROUPMAP, sid_string_static(alias),
+ type);
if (ldapsam_search_one_group(ldap_state, filter,
&result) != LDAP_SUCCESS)
@@ -3118,8 +3173,8 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
}
if (count > 1) {
- DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for filter %s: "
- "count=%d\n", filter, count));
+ DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
+ "filter %s: count=%d\n", filter, count));
ldap_msgfree(result);
return NT_STATUS_NO_SUCH_ALIAS;
}
@@ -3147,22 +3202,20 @@ static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
ldap_mods_free(mods, True);
ldap_msgfree(result);
+ SAFE_FREE(dn);
+
+ if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
+ return NT_STATUS_MEMBER_IN_ALIAS;
+ }
+
+ if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
+ return NT_STATUS_MEMBER_NOT_IN_ALIAS;
+ }
if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct,
- LDAP_OPT_ERROR_STRING,&ld_error);
-
- DEBUG(0, ("ldapsam_modify_aliasmem: Could not modify alias "
- "for %s, error: %s (%s)\n", dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
- SAFE_FREE(dn);
return NT_STATUS_UNSUCCESSFUL;
}
- SAFE_FREE(dn);
-
return NT_STATUS_OK;
}
@@ -3182,7 +3235,8 @@ static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
}
static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
- const DOM_SID *alias, DOM_SID **pp_members,
+ const DOM_SID *alias,
+ DOM_SID **pp_members,
size_t *p_num_members)
{
struct ldapsam_privates *ldap_state =
@@ -3194,15 +3248,29 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
int i;
pstring filter;
size_t num_members = 0;
+ enum SID_NAME_USE type = SID_NAME_USE_NONE;
*pp_members = NULL;
*p_num_members = 0;
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_GROUP_SID),
- sid_string_static(alias));
+ if (sid_check_is_in_builtin(alias)) {
+ type = SID_NAME_ALIAS;
+ }
+
+ if (sid_check_is_in_our_domain(alias)) {
+ type = SID_NAME_ALIAS;
+ }
+
+ if (type == SID_NAME_USE_NONE) {
+ DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
+ sid_string_static(alias)));
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ pstr_sprintf(filter,
+ "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
+ LDAP_OBJ_GROUPMAP, sid_string_static(alias),
+ type);
if (ldapsam_search_one_group(ldap_state, filter,
&result) != LDAP_SUCCESS)
@@ -3218,8 +3286,8 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
}
if (count > 1) {
- DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for filter %s: "
- "count=%d\n", filter, count));
+ DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
+ "filter %s: count=%d\n", filter, count));
ldap_msgfree(result);
return NT_STATUS_NO_SUCH_ALIAS;
}
@@ -3279,14 +3347,25 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
int i;
int rc;
char *filter;
+ enum SID_NAME_USE type = SID_NAME_USE_NONE;
+
+ if (sid_check_is_builtin(domain_sid)) {
+ type = SID_NAME_ALIAS;
+ }
- /* This query could be further optimized by adding a
- (&(sambaSID=<domain-sid>*)) so that only those aliases that are
- asked for in the getuseraliases are returned. */
+ if (sid_check_is_domain(domain_sid)) {
+ type = SID_NAME_ALIAS;
+ }
+
+ if (type == SID_NAME_USE_NONE) {
+ DEBUG(5, ("SID %s is neither builtin nor domain!\n",
+ sid_string_static(domain_sid)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
filter = talloc_asprintf(mem_ctx,
- "(&(|(objectclass=%s)(objectclass=%s))(|",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY);
+ "(&(|(objectclass=%s)(sambaGroupType=%d))(|",
+ LDAP_OBJ_GROUPMAP, type);
for (i=0; i<num_members; i++)
filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
@@ -3331,7 +3410,9 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
return NT_STATUS_OK;
}
-static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
+ int policy_index,
+ uint32 value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
int rc;
@@ -3352,7 +3433,8 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
policy_attr = get_account_policy_attr(policy_index);
if (policy_attr == NULL) {
- DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid policy\n"));
+ DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
+ "policy\n"));
return ntstatus;
}
@@ -3363,40 +3445,39 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
- rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn, mods);
+ rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
+ mods);
ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct,
- LDAP_OPT_ERROR_STRING,&ld_error);
-
- DEBUG(0, ("ldapsam_set_account_policy_in_ldap: Could not set account policy "
- "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
return ntstatus;
}
if (!cache_account_policy_set(policy_index, value)) {
- DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to update local tdb cache\n"));
+ DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
+ "update local tdb cache\n"));
return ntstatus;
}
return NT_STATUS_OK;
}
-static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
+ int policy_index, uint32 value)
{
if (!account_policy_migrated(False)) {
- return (account_policy_set(policy_index, value)) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return (account_policy_set(policy_index, value)) ?
+ NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
- return ldapsam_set_account_policy_in_ldap(methods, policy_index, value);
+ return ldapsam_set_account_policy_in_ldap(methods, policy_index,
+ value);
}
-static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
+ int policy_index,
+ uint32 *value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
LDAPMessage *result = NULL;
@@ -3419,7 +3500,8 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
policy_attr = get_account_policy_attr(policy_index);
if (!policy_attr) {
- DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid policy index: %d\n", policy_index));
+ DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
+ "policy index: %d\n", policy_index));
return ntstatus;
}
@@ -3427,31 +3509,24 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
attrs[1] = NULL;
rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
- LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &result);
+ LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
+ &result);
if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->smbldap_state->ldap_struct,
- LDAP_OPT_ERROR_STRING,&ld_error);
-
- DEBUG(3, ("ldapsam_get_account_policy_from_ldap: Could not get account policy "
- "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc),
- ld_error?ld_error:"unknown"));
- SAFE_FREE(ld_error);
return ntstatus;
}
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
+ count = ldap_count_entries(priv2ld(ldap_state), result);
if (count < 1) {
goto out;
}
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
if (entry == NULL) {
goto out;
}
- vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, policy_attr);
+ vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
if (vals == NULL) {
goto out;
}
@@ -3470,7 +3545,8 @@ out:
/* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
- - if user hasn't decided to use account policies inside LDAP just reuse the old tdb values
+ - if user hasn't decided to use account policies inside LDAP just reuse the
+ old tdb values
- if there is a valid cache entry, return that
- if there is an LDAP entry, update cache and return
@@ -3478,32 +3554,38 @@ out:
Guenther
*/
-static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
+ int policy_index, uint32 *value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
if (!account_policy_migrated(False)) {
- return (account_policy_get(policy_index, value)) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return (account_policy_get(policy_index, value))
+ ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
if (cache_account_policy_get(policy_index, value)) {
- DEBUG(11,("ldapsam_get_account_policy: got valid value from cache\n"));
+ DEBUG(11,("ldapsam_get_account_policy: got valid value from "
+ "cache\n"));
return NT_STATUS_OK;
}
- ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index, value);
+ ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index,
+ value);
if (NT_STATUS_IS_OK(ntstatus)) {
goto update_cache;
}
- DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from ldap\n"));
+ DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
+ "ldap\n"));
#if 0
/* should we automagically migrate old tdb value here ? */
if (account_policy_get(policy_index, value))
goto update_ldap;
- DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying default\n", policy_index));
+ DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
+ "default\n", policy_index));
#endif
if (!account_policy_get_default(policy_index, value)) {
@@ -3520,7 +3602,8 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int poli
update_cache:
if (!cache_account_policy_set(policy_index, *value)) {
- DEBUG(0,("ldapsam_get_account_policy: failed to update local tdb as a cache\n"));
+ DEBUG(0,("ldapsam_get_account_policy: failed to update local "
+ "tdb as a cache\n"));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -3536,39 +3619,43 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
- LDAP *ldap_struct = ldap_state->smbldap_state->ldap_struct;
LDAPMessage *msg = NULL;
LDAPMessage *entry;
char *allsids = NULL;
- char *tmp;
int i, rc, num_mapped;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_NO_MEMORY;
+ TALLOC_CTX *mem_ctx;
+ LDAP *ld;
+ BOOL is_builtin;
- if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
- return pdb_default_lookup_rids(methods, domain_sid,
- num_rids, rids, names, attrs);
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ goto done;
+ }
- if (!sid_equal(domain_sid, get_global_sam_sid())) {
- /* TODO: Sooner or later we need to look up BUILTIN rids as
- * well. -- vl */
+ if (!sid_check_is_builtin(domain_sid) &&
+ !sid_check_is_domain(domain_sid)) {
+ result = NT_STATUS_INVALID_PARAMETER;
goto done;
}
for (i=0; i<num_rids; i++)
attrs[i] = SID_NAME_UNKNOWN;
- allsids = SMB_STRDUP("");
- if (allsids == NULL) return NT_STATUS_NO_MEMORY;
+ allsids = talloc_strdup(mem_ctx, "");
+ if (allsids == NULL) {
+ goto done;
+ }
for (i=0; i<num_rids; i++) {
DOM_SID sid;
- sid_copy(&sid, domain_sid);
- sid_append_rid(&sid, rids[i]);
- tmp = allsids;
- asprintf(&allsids, "%s(sambaSid=%s)", allsids,
- sid_string_static(&sid));
- if (allsids == NULL) return NT_STATUS_NO_MEMORY;
- free(tmp);
+ sid_compose(&sid, domain_sid, rids[i]);
+ allsids = talloc_asprintf_append(allsids, "(sambaSid=%s)",
+ sid_string_static(&sid));
+ if (allsids == NULL) {
+ goto done;
+ }
}
/* First look for users */
@@ -3577,40 +3664,43 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
char *filter;
const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
- asprintf(&filter, ("(&(objectClass=sambaSamAccount)(|%s))"),
- allsids);
- if (filter == NULL) return NT_STATUS_NO_MEMORY;
+ filter = talloc_asprintf(
+ mem_ctx, ("(&(objectClass=%s)(|%s))"),
+ LDAP_OBJ_SAMBASAMACCOUNT, allsids);
+
+ if (filter == NULL) {
+ goto done;
+ }
rc = smbldap_search(ldap_state->smbldap_state,
lp_ldap_user_suffix(),
LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
&msg);
-
- SAFE_FREE(filter);
+ talloc_autofree_ldapmsg(mem_ctx, msg);
}
if (rc != LDAP_SUCCESS)
goto done;
+ ld = ldap_state->smbldap_state->ldap_struct;
num_mapped = 0;
- for (entry = ldap_first_entry(ldap_struct, msg);
+ for (entry = ldap_first_entry(ld, msg);
entry != NULL;
- entry = ldap_next_entry(ldap_struct, entry))
- {
+ entry = ldap_next_entry(ld, entry)) {
uint32 rid;
int rid_index;
- fstring str;
+ const char *name;
- if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
- get_global_sam_sid(),
+ if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
&rid)) {
DEBUG(2, ("Could not find sid from ldap entry\n"));
continue;
}
- if (!smbldap_get_single_attribute(ldap_struct, entry,
- "uid", str, sizeof(str)-1)) {
+ name = smbldap_talloc_single_attribute(ld, entry, "uid",
+ names);
+ if (name == NULL) {
DEBUG(2, ("Could not retrieve uid attribute\n"));
continue;
}
@@ -3626,9 +3716,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
}
attrs[rid_index] = SID_NAME_USER;
- names[rid_index] = talloc_strdup(names, str);
- if (names[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
-
+ names[rid_index] = name;
num_mapped += 1;
}
@@ -3638,49 +3726,82 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
goto done;
}
- if (msg != NULL) {
- ldap_msgfree(msg);
- }
-
/* Same game for groups */
{
char *filter;
- const char *ldap_attrs[] = { "cn", "sambaSid", NULL };
+ const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
+ "sambaGroupType", NULL };
- asprintf(&filter, ("(&(objectClass=sambaGroupMapping)(|%s))"),
- allsids);
- if (filter == NULL) return NT_STATUS_NO_MEMORY;
+ filter = talloc_asprintf(
+ mem_ctx, "(&(objectClass=%s)(|%s))",
+ LDAP_OBJ_GROUPMAP, allsids);
+ if (filter == NULL) {
+ goto done;
+ }
rc = smbldap_search(ldap_state->smbldap_state,
lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
&msg);
-
- SAFE_FREE(filter);
+ talloc_autofree_ldapmsg(mem_ctx, msg);
}
if (rc != LDAP_SUCCESS)
goto done;
- for (entry = ldap_first_entry(ldap_struct, msg);
+ /* ldap_struct might have changed due to a reconnect */
+
+ ld = ldap_state->smbldap_state->ldap_struct;
+
+ /* For consistency checks, we already checked we're only domain or builtin */
+
+ is_builtin = sid_check_is_builtin(domain_sid);
+
+ for (entry = ldap_first_entry(ld, msg);
entry != NULL;
- entry = ldap_next_entry(ldap_struct, entry))
+ entry = ldap_next_entry(ld, entry))
{
uint32 rid;
int rid_index;
- fstring str;
+ const char *attr;
+ enum SID_NAME_USE type;
+ const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
+
+ attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
+ mem_ctx);
+ if (attr == NULL) {
+ DEBUG(2, ("Could not extract type from ldap entry %s\n",
+ dn));
+ continue;
+ }
- if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
- get_global_sam_sid(),
+ type = atol(attr);
+
+ /* Consistency checks */
+ if ((is_builtin && (type != SID_NAME_ALIAS)) ||
+ (!is_builtin && ((type != SID_NAME_ALIAS) &&
+ (type != SID_NAME_DOM_GRP)))) {
+ DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
+ }
+
+ if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
&rid)) {
- DEBUG(2, ("Could not find sid from ldap entry\n"));
+ DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
continue;
}
- if (!smbldap_get_single_attribute(ldap_struct, entry,
- "cn", str, sizeof(str)-1)) {
- DEBUG(2, ("Could not retrieve cn attribute\n"));
+ attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
+
+ if (attr == NULL) {
+ DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
+ dn));
+ attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
+ }
+
+ if (attr == NULL) {
+ DEBUG(2, ("Could not retrieve naming attribute from %s\n",
+ dn));
continue;
}
@@ -3694,9 +3815,8 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
continue;
}
- attrs[rid_index] = SID_NAME_DOM_GRP;
- names[rid_index] = talloc_strdup(names, str);
- if (names[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+ attrs[rid_index] = type;
+ names[rid_index] = attr;
num_mapped += 1;
}
@@ -3706,15 +3826,11 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
result = (num_mapped == num_rids) ?
NT_STATUS_OK : STATUS_SOME_UNMAPPED;
done:
- SAFE_FREE(allsids);
-
- if (msg != NULL)
- ldap_msgfree(msg);
-
+ TALLOC_FREE(mem_ctx);
return result;
}
-char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
+static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
{
char *filter = NULL;
char *escaped = NULL;
@@ -3727,8 +3843,7 @@ char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
escaped = escape_ldap_string_alloc(username);
if (escaped == NULL) goto done;
- filter = realloc_string_sub(filter, "%u", username);
- result = talloc_strdup(mem_ctx, filter);
+ result = talloc_string_sub(mem_ctx, filter, "%u", username);
done:
SAFE_FREE(filter);
@@ -3762,7 +3877,7 @@ const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
struct ldap_search_state {
struct smbldap_state *connection;
- uint16 acct_flags;
+ uint32 acct_flags;
uint16 group_type;
const char *base;
@@ -3834,7 +3949,6 @@ static BOOL ldapsam_search_firstpage(struct pdb_search *search)
static BOOL ldapsam_search_nextpage(struct pdb_search *search)
{
struct ldap_search_state *state = search->private_data;
- LDAP *ld = state->connection->ldap_struct;
int rc;
if (!state->connection->paged_results) {
@@ -3851,7 +3965,7 @@ static BOOL ldapsam_search_nextpage(struct pdb_search *search)
if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
return False;
- state->current_entry = ldap_first_entry(ld, state->entries);
+ state->current_entry = ldap_first_entry(state->connection->ldap_struct, state->entries);
if (state->current_entry == NULL) {
ldap_msgfree(state->entries);
@@ -3865,7 +3979,6 @@ static BOOL ldapsam_search_next_entry(struct pdb_search *search,
struct samr_displayentry *entry)
{
struct ldap_search_state *state = search->private_data;
- LDAP *ld = state->connection->ldap_struct;
BOOL result;
retry:
@@ -3876,17 +3989,17 @@ static BOOL ldapsam_search_next_entry(struct pdb_search *search,
!ldapsam_search_nextpage(search))
return False;
- result = state->ldap2displayentry(state, search->mem_ctx, ld,
+ result = state->ldap2displayentry(state, search->mem_ctx, state->connection->ldap_struct,
state->current_entry, entry);
if (!result) {
char *dn;
- dn = ldap_get_dn(ld, state->current_entry);
+ dn = ldap_get_dn(state->connection->ldap_struct, state->current_entry);
DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
if (dn != NULL) ldap_memfree(dn);
}
- state->current_entry = ldap_next_entry(ld, state->current_entry);
+ state->current_entry = ldap_next_entry(state->connection->ldap_struct, state->current_entry);
if (state->current_entry == NULL) {
ldap_msgfree(state->entries);
@@ -3935,7 +4048,7 @@ static BOOL ldapuser2displayentry(struct ldap_search_state *state,
{
char **vals;
DOM_SID sid;
- uint16 acct_flags;
+ uint32 acct_flags;
vals = ldap_get_values(ld, entry, "sambaAcctFlags");
if ((vals == NULL) || (vals[0] == NULL)) {
@@ -4003,7 +4116,8 @@ static BOOL ldapuser2displayentry(struct ldap_search_state *state,
ldap_value_free(vals);
if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
- DEBUG(0, ("sid %s does not belong to our domain\n", sid_string_static(&sid)));
+ DEBUG(0, ("sid %s does not belong to our domain\n",
+ sid_string_static(&sid)));
return False;
}
@@ -4013,7 +4127,7 @@ static BOOL ldapuser2displayentry(struct ldap_search_state *state,
static BOOL ldapsam_search_users(struct pdb_methods *methods,
struct pdb_search *search,
- uint16 acct_flags)
+ uint32 acct_flags)
{
struct ldapsam_privates *ldap_state = methods->private_data;
struct ldap_search_state *state;
@@ -4103,10 +4217,14 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
DEBUG(5, ("\"cn\" not found\n"));
return False;
}
- pull_utf8_talloc(mem_ctx, CONST_DISCARD(char **, &result->account_name), vals[0]);
+ pull_utf8_talloc(mem_ctx,
+ CONST_DISCARD(char **, &result->account_name),
+ vals[0]);
}
else {
- pull_utf8_talloc(mem_ctx, CONST_DISCARD(char **, &result->account_name), vals[0]);
+ pull_utf8_talloc(mem_ctx,
+ CONST_DISCARD(char **, &result->account_name),
+ vals[0]);
}
ldap_value_free(vals);
@@ -4147,21 +4265,15 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
case SID_NAME_DOM_GRP:
case SID_NAME_ALIAS:
- if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
- DEBUG(0, ("%s is not in our domain\n", sid_string_static(&sid)));
+ if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
+ && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
+ {
+ DEBUG(0, ("%s is not in our domain\n",
+ sid_string_static(&sid)));
return False;
}
break;
- case SID_NAME_WKN_GRP:
-
- if (!sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid)) {
-
- DEBUG(0, ("%s is not in builtin sid\n", sid_string_static(&sid)));
- return False;
- }
- break;
-
default:
DEBUG(0,("unkown group type: %d\n", group_type));
return False;
@@ -4172,6 +4284,7 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
struct pdb_search *search,
+ const DOM_SID *sid,
enum SID_NAME_USE type)
{
struct ldapsam_privates *ldap_state = methods->private_data;
@@ -4190,9 +4303,11 @@ static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
state->scope = LDAP_SCOPE_SUBTREE;
state->filter = talloc_asprintf(search->mem_ctx,
"(&(objectclass=sambaGroupMapping)"
- "(sambaGroupType=%d))", type);
+ "(sambaGroupType=%d)(sambaSID=%s))",
+ type, sid_string_static(sid));
state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
- "displayName", "description", "sambaGroupType", NULL);
+ "displayName", "description",
+ "sambaGroupType", NULL);
state->attrsonly = 0;
state->pagedresults_cookie = NULL;
state->entries = NULL;
@@ -4214,25 +4329,1005 @@ static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
static BOOL ldapsam_search_groups(struct pdb_methods *methods,
struct pdb_search *search)
{
- return ldapsam_search_grouptype(methods, search, SID_NAME_DOM_GRP);
+ return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
}
static BOOL ldapsam_search_aliases(struct pdb_methods *methods,
struct pdb_search *search,
const DOM_SID *sid)
{
- if (sid_check_is_domain(sid))
- return ldapsam_search_grouptype(methods, search,
- SID_NAME_ALIAS);
+ return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
+}
+
+static BOOL ldapsam_rid_algorithm(struct pdb_methods *methods)
+{
+ return False;
+}
+
+static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
+ uint32 *rid)
+{
+ struct smbldap_state *smbldap_state = priv->smbldap_state;
+
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ LDAPMod **mods = NULL;
+ NTSTATUS status;
+ char *value;
+ int rc;
+ uint32 nextRid = 0;
- if (sid_check_is_builtin(sid))
- return ldapsam_search_grouptype(methods, search,
- SID_NAME_WKN_GRP);
+ TALLOC_CTX *mem_ctx;
- DEBUG(5, ("Don't know SID %s\n", sid_string_static(sid)));
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = smbldap_search_domain_info(smbldap_state, &result,
+ get_global_sam_name(), False);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Could not get domain info: %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
+ entry = ldap_first_entry(priv2ld(priv), result);
+ if (entry == NULL) {
+ DEBUG(0, ("Could not get domain info entry\n"));
+ status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ /* Find the largest of the three attributes "sambaNextRid",
+ "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
+ concept of differentiating between user and group rids, and will
+ use only "sambaNextRid" in the future. But for compatibility
+ reasons I look if others have chosen different strategies -- VL */
+
+ value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+ "sambaNextRid", mem_ctx);
+ if (value != NULL) {
+ uint32 tmp = (uint32)strtoul(value, NULL, 10);
+ nextRid = MAX(nextRid, tmp);
+ }
+
+ value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+ "sambaNextUserRid", mem_ctx);
+ if (value != NULL) {
+ uint32 tmp = (uint32)strtoul(value, NULL, 10);
+ nextRid = MAX(nextRid, tmp);
+ }
+
+ value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+ "sambaNextGroupRid", mem_ctx);
+ if (value != NULL) {
+ uint32 tmp = (uint32)strtoul(value, NULL, 10);
+ nextRid = MAX(nextRid, tmp);
+ }
+
+ if (nextRid == 0) {
+ nextRid = BASE_RID-1;
+ }
+
+ nextRid += 1;
+
+ smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
+ talloc_asprintf(mem_ctx, "%d", nextRid));
+ talloc_autofree_ldapmod(mem_ctx, mods);
+
+ rc = smbldap_modify(smbldap_state,
+ smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry),
+ mods);
+
+ /* ACCESS_DENIED is used as a placeholder for "the modify failed,
+ * please retry" */
+
+ status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
+
+ done:
+ if (NT_STATUS_IS_OK(status)) {
+ *rid = nextRid;
+ }
+
+ TALLOC_FREE(mem_ctx);
+ return status;
+}
+
+static BOOL ldapsam_new_rid(struct pdb_methods *methods, uint32 *rid)
+{
+ int i;
+
+ for (i=0; i<10; i++) {
+ NTSTATUS result = ldapsam_get_new_rid(methods->private_data,
+ rid);
+ if (NT_STATUS_IS_OK(result)) {
+ return True;
+ }
+
+ if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
+ return False;
+ }
+
+ /* The ldap update failed (maybe a race condition), retry */
+ }
+
+ /* Tried 10 times, fail. */
return False;
}
+static BOOL ldapsam_sid_to_id(struct pdb_methods *methods,
+ const DOM_SID *sid,
+ union unid_t *id, enum SID_NAME_USE *type)
+{
+ struct ldapsam_privates *priv = methods->private_data;
+ char *filter;
+ const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
+ NULL };
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ BOOL ret = False;
+ char *value;
+ int rc;
+
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_new(NULL);
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_new failed\n"));
+ return False;
+ }
+
+ filter = talloc_asprintf(mem_ctx,
+ "(&(sambaSid=%s)"
+ "(|(objectClass=%s)(objectClass=%s)))",
+ sid_string_static(sid),
+ LDAP_OBJ_GROUPMAP, LDAP_OBJ_SAMBASAMACCOUNT);
+ if (filter == NULL) {
+ DEBUG(5, ("talloc_asprintf failed\n"));
+ goto done;
+ }
+
+ rc = smbldap_search_suffix(priv->smbldap_state, filter,
+ attrs, &result);
+ if (rc != LDAP_SUCCESS) {
+ goto done;
+ }
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
+ if (ldap_count_entries(priv2ld(priv), result) != 1) {
+ DEBUG(10, ("Got %d entries, expected one\n",
+ ldap_count_entries(priv2ld(priv), result)));
+ goto done;
+ }
+
+ entry = ldap_first_entry(priv2ld(priv), result);
+
+ value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+ "sambaGroupType", mem_ctx);
+
+ if (value != NULL) {
+ const char *gid_str;
+ /* It's a group */
+
+ gid_str = smbldap_talloc_single_attribute(
+ priv2ld(priv), entry, "gidNumber", mem_ctx);
+ if (gid_str == NULL) {
+ DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
+ smbldap_talloc_dn(mem_ctx, priv2ld(priv),
+ entry)));
+ goto done;
+ }
+
+ id->gid = strtoul(gid_str, NULL, 10);
+ *type = strtoul(value, NULL, 10);
+ ret = True;
+ goto done;
+ }
+
+ /* It must be a user */
+
+ value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
+ "uidNumber", mem_ctx);
+ if (value == NULL) {
+ DEBUG(1, ("Could not find uidNumber in %s\n",
+ smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
+ goto done;
+ }
+
+ id->uid = strtoul(value, NULL, 10);
+ *type = SID_NAME_USER;
+
+ ret = True;
+ done:
+ TALLOC_FREE(mem_ctx);
+ return ret;
+}
+
+/*
+ * The following functions is called only if
+ * ldapsam:trusted and ldapsam:editposix are
+ * set to true
+ */
+
+/*
+ * ldapsam_create_user creates a new
+ * posixAccount and sambaSamAccount object
+ * in the ldap users subtree
+ *
+ * The uid is allocated by winbindd.
+ */
+
+static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
+ TALLOC_CTX *tmp_ctx, const char *name,
+ uint32 acb_info, uint32 *rid)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ LDAPMessage *entry = NULL;
+ LDAPMessage *result = NULL;
+ uint32 num_result;
+ BOOL is_machine = False;
+ BOOL add_posix = False;
+ LDAPMod **mods = NULL;
+ struct samu *user;
+ char *filter;
+ char *username;
+ char *homedir;
+ char *gidstr;
+ char *uidstr;
+ char *shell;
+ const char *dn = NULL;
+ DOM_SID group_sid;
+ DOM_SID user_sid;
+ gid_t gid = -1;
+ uid_t uid = -1;
+ NTSTATUS ret;
+ int rc;
+
+ if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
+ acb_info & ACB_WSTRUST ||
+ acb_info & ACB_SVRTRUST ||
+ acb_info & ACB_DOMTRUST) {
+ is_machine = True;
+ }
+
+ username = escape_ldap_string_alloc(name);
+ filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
+ username, LDAP_OBJ_POSIXACCOUNT);
+ SAFE_FREE(username);
+
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (num_result == 1) {
+ char *tmp;
+ /* check if it is just a posix account.
+ * or if there is a sid attached to this entry
+ */
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
+ if (tmp) {
+ DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
+ return NT_STATUS_USER_EXISTS;
+ }
+
+ /* it is just a posix account, retrieve the dn for later use */
+ dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
+ if (!dn) {
+ DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ if (num_result == 0) {
+ add_posix = True;
+ }
+
+ /* Create the basic samu structure and generate the mods for the ldap commit */
+ if (!NT_STATUS_IS_OK((ret = ldapsam_get_new_rid(ldap_state, rid)))) {
+ DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
+ return ret;
+ }
+
+ sid_compose(&user_sid, get_global_sam_sid(), *rid);
+
+ user = samu_new(tmp_ctx);
+ if (!user) {
+ DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_username(user, name, PDB_SET)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (is_machine) {
+ if (acb_info & ACB_NORMAL) {
+ if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ } else {
+ if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+ } else {
+ if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!init_ldap_from_sam(ldap_state, NULL, &mods, user, element_is_set_or_changed)) {
+ DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
+ DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
+ }
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
+
+ if (add_posix) {
+ DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
+
+ /* retrieve the Domain Users group gid */
+ if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS) ||
+ !sid_to_gid(&group_sid, &gid)) {
+ DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
+ return NT_STATUS_INVALID_PRIMARY_GROUP;
+ }
+
+ /* lets allocate a new userid for this user */
+ if (!winbind_allocate_uid(&uid)) {
+ DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+
+ if (is_machine) {
+ /* TODO: choose a more appropriate default for machines */
+ homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), "SMB_workstations_home", ldap_state->domain_name, uid, gid);
+ shell = talloc_strdup(tmp_ctx, "/bin/false");
+ } else {
+ homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), name, ldap_state->domain_name, uid, gid);
+ shell = talloc_sub_specified(tmp_ctx, lp_template_shell(), name, ldap_state->domain_name, uid, gid);
+ }
+ uidstr = talloc_asprintf(tmp_ctx, "%d", uid);
+ gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
+ if (is_machine) {
+ dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", name, lp_ldap_machine_suffix ());
+ } else {
+ dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", name, lp_ldap_user_suffix ());
+ }
+
+ if (!homedir || !shell || !uidstr || !gidstr || !dn) {
+ DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
+ }
+
+ talloc_autofree_ldapmod(tmp_ctx, mods);
+
+ if (add_posix) {
+ rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
+ } else {
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
+
+ flush_pwnam_cache();
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ int num_result;
+ const char *dn;
+ char *filter;
+ int rc;
+
+ DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
+
+ filter = talloc_asprintf(tmp_ctx,
+ "(&(uid=%s)"
+ "(objectClass=%s)"
+ "(objectClass=%s))",
+ pdb_get_username(sam_acct),
+ LDAP_OBJ_POSIXACCOUNT,
+ LDAP_OBJ_SAMBASAMACCOUNT);
+
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result == 0) {
+ DEBUG(0,("ldapsam_delete_user: user not found!\n"));
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* it is just a posix account, retrieve the dn for later use */
+ dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
+ if (!dn) {
+ DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ rc = smbldap_delete(ldap_state->smbldap_state, dn);
+ if (rc != LDAP_SUCCESS) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ flush_pwnam_cache();
+
+ return NT_STATUS_OK;
+}
+
+/*
+ * ldapsam_create_group creates a new
+ * posixGroup and sambaGroupMapping object
+ * in the ldap groups subtree
+ *
+ * The gid is allocated by winbindd.
+ */
+
+static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
+ TALLOC_CTX *tmp_ctx,
+ const char *name,
+ uint32 *rid)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ NTSTATUS ret;
+ LDAPMessage *entry = NULL;
+ LDAPMessage *result = NULL;
+ uint32 num_result;
+ BOOL is_new_entry = False;
+ LDAPMod **mods = NULL;
+ char *filter;
+ char *groupsidstr;
+ char *groupname;
+ char *grouptype;
+ char *gidstr;
+ const char *dn = NULL;
+ DOM_SID group_sid;
+ gid_t gid = -1;
+ int rc;
+
+ groupname = escape_ldap_string_alloc(name);
+ filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
+ groupname, LDAP_OBJ_POSIXGROUP);
+ SAFE_FREE(groupname);
+
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ if (num_result == 1) {
+ char *tmp;
+ /* check if it is just a posix group.
+ * or if there is a sid attached to this entry
+ */
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
+ if (tmp) {
+ DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
+ return NT_STATUS_GROUP_EXISTS;
+ }
+
+ /* it is just a posix group, retrieve the gid and the dn for later use */
+ tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
+ if (!tmp) {
+ DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ gid = strtoul(tmp, NULL, 10);
+
+ dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
+ if (!dn) {
+ DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ if (num_result == 0) {
+ DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
+
+ is_new_entry = True;
+
+ /* lets allocate a new groupid for this group */
+ if (!winbind_allocate_gid(&gid)) {
+ DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
+ dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", name, lp_ldap_group_suffix());
+
+ if (!gidstr || !dn) {
+ DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+ }
+
+ if (!NT_STATUS_IS_OK((ret = ldapsam_get_new_rid(ldap_state, rid)))) {
+ DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
+ return ret;
+ }
+
+ sid_compose(&group_sid, get_global_sam_sid(), *rid);
+
+ groupsidstr = talloc_strdup(tmp_ctx, sid_string_static(&group_sid));
+ grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
+
+ if (!groupsidstr || !grouptype) {
+ DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
+ talloc_autofree_ldapmod(tmp_ctx, mods);
+
+ if (is_new_entry) {
+ rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
+#if 0
+ if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
+ /* This call may fail with rfc2307bis schema */
+ /* Retry adding a structural class */
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
+ rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
+ }
+#endif
+ } else {
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32 rid)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ int num_result;
+ const char *dn;
+ char *gidstr;
+ char *filter;
+ DOM_SID group_sid;
+ int rc;
+
+ /* get the group sid */
+ sid_compose(&group_sid, get_global_sam_sid(), rid);
+
+ filter = talloc_asprintf(tmp_ctx,
+ "(&(sambaSID=%s)"
+ "(objectClass=%s)"
+ "(objectClass=%s))",
+ sid_string_static(&group_sid),
+ LDAP_OBJ_POSIXGROUP,
+ LDAP_OBJ_GROUPMAP);
+
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result == 0) {
+ DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* here it is, retrieve the dn for later use */
+ dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
+ if (!dn) {
+ DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
+ if (!gidstr) {
+ DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ /* check no user have this group marked as primary group */
+ filter = talloc_asprintf(tmp_ctx,
+ "(&(gidNumber=%s)"
+ "(objectClass=%s)"
+ "(objectClass=%s))",
+ gidstr,
+ LDAP_OBJ_POSIXACCOUNT,
+ LDAP_OBJ_SAMBASAMACCOUNT);
+
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result != 0) {
+ DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
+ return NT_STATUS_MEMBERS_PRIMARY_GROUP;
+ }
+
+ rc = smbldap_delete(ldap_state->smbldap_state, dn);
+ if (rc != LDAP_SUCCESS) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
+ TALLOC_CTX *tmp_ctx,
+ uint32 group_rid,
+ uint32 member_rid,
+ int modop)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ LDAPMessage *entry = NULL;
+ LDAPMessage *result = NULL;
+ uint32 num_result;
+ LDAPMod **mods = NULL;
+ char *filter;
+ char *uidstr;
+ const char *dn = NULL;
+ DOM_SID group_sid;
+ DOM_SID member_sid;
+ int rc;
+
+ switch (modop) {
+ case LDAP_MOD_ADD:
+ DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)", member_rid, group_rid));
+ break;
+ case LDAP_MOD_DELETE:
+ DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)", member_rid, group_rid));
+ break;
+ default:
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* get member sid */
+ sid_compose(&member_sid, get_global_sam_sid(), member_rid);
+
+ /* get the group sid */
+ sid_compose(&group_sid, get_global_sam_sid(), group_rid);
+
+ filter = talloc_asprintf(tmp_ctx,
+ "(&(sambaSID=%s)"
+ "(objectClass=%s)"
+ "(objectClass=%s))",
+ sid_string_static(&member_sid),
+ LDAP_OBJ_POSIXACCOUNT,
+ LDAP_OBJ_SAMBASAMACCOUNT);
+
+ /* get the member uid */
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result == 0) {
+ DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
+ return NT_STATUS_NO_SUCH_MEMBER;
+ }
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (modop == LDAP_MOD_DELETE) {
+ /* check if we are trying to remove the member from his primary group */
+ char *gidstr;
+ gid_t user_gid, group_gid;
+
+ gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
+ if (!gidstr) {
+ DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ user_gid = strtoul(gidstr, NULL, 10);
+
+ if (!sid_to_gid(&group_sid, &group_gid)) {
+ DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (user_gid == group_gid) {
+ DEBUG (3, ("ldapsam_change_groupmem: can't remove user from it's own primary group!\n"));
+ return NT_STATUS_MEMBERS_PRIMARY_GROUP;
+ }
+ }
+
+ /* here it is, retrieve the uid for later use */
+ uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
+ if (!uidstr) {
+ DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ filter = talloc_asprintf(tmp_ctx,
+ "(&(sambaSID=%s)"
+ "(objectClass=%s)"
+ "(objectClass=%s))",
+ sid_string_static(&group_sid),
+ LDAP_OBJ_POSIXGROUP,
+ LDAP_OBJ_GROUPMAP);
+
+ /* get the group */
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(tmp_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result == 0) {
+ DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* here it is, retrieve the dn for later use */
+ dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
+ if (!dn) {
+ DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smbldap_set_mod(&mods, modop, "memberUid", uidstr);
+
+ talloc_autofree_ldapmod(tmp_ctx, mods);
+
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
+ if (rc != LDAP_SUCCESS) {
+ if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
+ DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
+ return NT_STATUS_MEMBER_IN_GROUP;
+ }
+ if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
+ DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
+ return NT_STATUS_MEMBER_NOT_IN_GROUP;
+ }
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
+ TALLOC_CTX *tmp_ctx,
+ uint32 group_rid,
+ uint32 member_rid)
+{
+ return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
+}
+static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
+ TALLOC_CTX *tmp_ctx,
+ uint32 group_rid,
+ uint32 member_rid)
+{
+ return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
+}
+
+static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
+ TALLOC_CTX *mem_ctx,
+ struct samu *sampass)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ LDAPMessage *entry = NULL;
+ LDAPMessage *result = NULL;
+ uint32 num_result;
+ LDAPMod **mods = NULL;
+ char *filter;
+ char *gidstr;
+ const char *dn = NULL;
+ gid_t gid;
+ int rc;
+
+ DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
+
+ if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
+ DEBUG(0,("ldapsam_set_primary_group: failed to retieve gid from user's group SID!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ gidstr = talloc_asprintf(mem_ctx, "%d", gid);
+ if (!gidstr) {
+ DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ filter = talloc_asprintf(mem_ctx,
+ "(&(uid=%s)"
+ "(objectClass=%s)"
+ "(objectClass=%s))",
+ pdb_get_username(sampass),
+ LDAP_OBJ_POSIXACCOUNT,
+ LDAP_OBJ_SAMBASAMACCOUNT);
+
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ talloc_autofree_ldapmsg(mem_ctx, result);
+
+ num_result = ldap_count_entries(priv2ld(ldap_state), result);
+
+ if (num_result == 0) {
+ DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (num_result > 1) {
+ DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ entry = ldap_first_entry(priv2ld(ldap_state), result);
+ if (!entry) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* retrieve the dn for later use */
+ dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
+ if (!dn) {
+ DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* remove the old one, and add the new one, this way we do not risk races */
+ smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
+
+ if (mods == NULL) {
+ return NT_STATUS_OK;
+ }
+
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
+ pdb_get_username(sampass), gidstr));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ flush_pwnam_cache();
+
+ return NT_STATUS_OK;
+}
+
/**********************************************************************
Housekeeping
*********************************************************************/
@@ -4256,17 +5351,17 @@ static void free_private_data(void **vp)
/* No need to free any further, as it is talloc()ed */
}
-/**********************************************************************
- Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
- *********************************************************************/
+/*********************************************************************
+ Intitalise the parts of the pdb_methods structure that are common to
+ all pdb_ldap modes
+*********************************************************************/
-static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
- const char *location)
+static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
{
NTSTATUS nt_status;
struct ldapsam_privates *ldap_state;
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
return nt_status;
}
@@ -4289,29 +5384,29 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
(*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
(*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
(*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
- (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
- (*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
- (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
(*pdb_method)->get_account_policy = ldapsam_get_account_policy;
(*pdb_method)->set_account_policy = ldapsam_set_account_policy;
(*pdb_method)->get_seq_num = ldapsam_get_seq_num;
+ (*pdb_method)->rid_algorithm = ldapsam_rid_algorithm;
+ (*pdb_method)->new_rid = ldapsam_new_rid;
+
/* TODO: Setup private data and free */
- ldap_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct ldapsam_privates);
- if (!ldap_state) {
+ if ( !(ldap_state = TALLOC_ZERO_P(*pdb_method, struct ldapsam_privates)) ) {
DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
return NT_STATUS_NO_MEMORY;
}
- if (!NT_STATUS_IS_OK(nt_status =
- smbldap_init(pdb_context->mem_ctx, location,
- &ldap_state->smbldap_state)));
+ nt_status = smbldap_init(*pdb_method, location, &ldap_state->smbldap_state);
+
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
+ return nt_status;
+ }
- ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
- if (!ldap_state->domain_name) {
+ if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
return NT_STATUS_NO_MEMORY;
}
@@ -4326,13 +5421,14 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
Initialise the 'compat' mode for pdb_ldap
*********************************************************************/
-NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+NTSTATUS pdb_init_ldapsam_compat(struct pdb_methods **pdb_method, const char *location)
{
NTSTATUS nt_status;
struct ldapsam_privates *ldap_state;
+ char *uri = talloc_strdup( NULL, location );
#ifdef WITH_LDAP_SAMCONFIG
- if (!location) {
+ if (!uri) {
int ldap_port = lp_ldap_port();
/* remap default port if not using SSL (ie clear or TLS) */
@@ -4340,17 +5436,23 @@ NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_met
ldap_port = 389;
}
- location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
- if (!location) {
+ uri = talloc_asprintf(NULL, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
+ if (!uri) {
return NT_STATUS_NO_MEMORY;
}
+ location = uri;
}
#endif
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common( pdb_method, uri ))) {
return nt_status;
}
+ /* the module itself stores a copy of the location so throw this one away */
+
+ if ( uri )
+ TALLOC_FREE( uri );
+
(*pdb_method)->name = "ldapsam_compat";
ldap_state = (*pdb_method)->private_data;
@@ -4365,7 +5467,7 @@ NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_met
Initialise the normal mode for pdb_ldap
*********************************************************************/
-NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
{
NTSTATUS nt_status;
struct ldapsam_privates *ldap_state;
@@ -4378,7 +5480,8 @@ NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co
pstring domain_sid_string;
char *dn;
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
+ nt_status = pdb_init_ldapsam_common(pdb_method, location);
+ if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
@@ -4392,27 +5495,51 @@ NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co
(*pdb_method)->search_groups = ldapsam_search_groups;
(*pdb_method)->search_aliases = ldapsam_search_aliases;
+ if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
+ (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
+ (*pdb_method)->enum_group_memberships =
+ ldapsam_enum_group_memberships;
+ (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
+ (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
+
+ if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
+ (*pdb_method)->create_user = ldapsam_create_user;
+ (*pdb_method)->delete_user = ldapsam_delete_user;
+ (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
+ (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
+ (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
+ (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
+ (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
+ }
+ }
+
ldap_state = (*pdb_method)->private_data;
ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
/* Try to setup the Domain Name, Domain SID, algorithmic rid base */
- nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result,
+ nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
+ &result,
ldap_state->domain_name, True);
if ( !NT_STATUS_IS_OK(nt_status) ) {
- DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
- DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
-and will risk BDCs having inconsistant SIDs\n"));
+ DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain "
+ "info, nor add one to the domain\n"));
+ DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, "
+ "will be unable to allocate new users/groups, "
+ "and will risk BDCs having inconsistant SIDs\n"));
sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
return NT_STATUS_OK;
}
- /* Given that the above might fail, everything below this must be optional */
+ /* Given that the above might fail, everything below this must be
+ * optional */
- entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
+ result);
if (!entry) {
- DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
+ DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
+ "entry\n"));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -4425,35 +5552,51 @@ and will risk BDCs having inconsistant SIDs\n"));
ldap_state->domain_dn = smb_xstrdup(dn);
ldap_memfree(dn);
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
- domain_sid_string)) {
+ if (smbldap_get_single_pstring(
+ ldap_state->smbldap_state->ldap_struct,
+ entry,
+ get_userattr_key2string(ldap_state->schema_ver,
+ LDAP_ATTR_USER_SID),
+ domain_sid_string)) {
BOOL found_sid;
if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
- DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string));
+ DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
+ "read as a valid SID\n", domain_sid_string));
return NT_STATUS_INVALID_PARAMETER;
}
- found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid);
- if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) {
+ found_sid = secrets_fetch_domain_sid(ldap_state->domain_name,
+ &secrets_domain_sid);
+ if (!found_sid || !sid_equal(&secrets_domain_sid,
+ &ldap_domain_sid)) {
fstring new_sid_str, old_sid_str;
- DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n",
- ldap_state->domain_name,
- sid_to_string(old_sid_str, &secrets_domain_sid),
- sid_to_string(new_sid_str, &ldap_domain_sid)));
+ DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
+ "%s based on pdb_ldap results %s -> %s\n",
+ ldap_state->domain_name,
+ sid_to_string(old_sid_str,
+ &secrets_domain_sid),
+ sid_to_string(new_sid_str,
+ &ldap_domain_sid)));
/* reset secrets.tdb sid */
- secrets_store_domain_sid(ldap_state->domain_name, &ldap_domain_sid);
- DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str, get_global_sam_sid())));
+ secrets_store_domain_sid(ldap_state->domain_name,
+ &ldap_domain_sid);
+ DEBUG(1, ("New global sam SID: %s\n",
+ sid_to_string(new_sid_str,
+ get_global_sam_sid())));
}
sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
}
- if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
- get_attr_key2string( dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE ),
- alg_rid_base_string)) {
+ if (smbldap_get_single_pstring(
+ ldap_state->smbldap_state->ldap_struct,
+ entry,
+ get_attr_key2string( dominfo_attr_list,
+ LDAP_ATTR_ALGORITHMIC_RID_BASE ),
+ alg_rid_base_string)) {
alg_rid_base = (uint32)atol(alg_rid_base_string);
if (alg_rid_base != algorithmic_rid_base()) {
- DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
+ DEBUG(0, ("The value of 'algorithmic RID base' has "
+ "changed since the LDAP\n"
"database was initialised. Aborting. \n"));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
diff --git a/source/passdb/pdb_mysql.c b/source/passdb/pdb_mysql.c
deleted file mode 100644
index 27675a9cd18..00000000000
--- a/source/passdb/pdb_mysql.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * MySQL password backend for samba
- * Copyright (C) Jelmer Vernooij 2002-2004
- *
- * 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 2 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, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include <mysql/mysql.h>
-
-#define CONFIG_HOST_DEFAULT "localhost"
-#define CONFIG_USER_DEFAULT "samba"
-#define CONFIG_PASS_DEFAULT ""
-#define CONFIG_PORT_DEFAULT "3306"
-#define CONFIG_DB_DEFAULT "samba"
-
-static int mysqlsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS mysqlsam_debug_level
-
-typedef struct pdb_mysql_data {
- MYSQL *handle;
- MYSQL_RES *pwent;
- const char *location;
-} pdb_mysql_data;
-
-#define SET_DATA(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return NT_STATUS_INVALID_PARAMETER; \
- } \
- data = (struct pdb_mysql_data *)methods->private_data; \
- if(!data || !(data->handle)){ \
- DEBUG(0, ("invalid handle!\n")); \
- return NT_STATUS_INVALID_HANDLE; \
- } \
-}
-
-#define config_value( data, name, default_value ) \
- lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value )
-
-static long xatol(const char *d)
-{
- if(!d) return 0;
- return atol(d);
-}
-
-static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
-{
- MYSQL_ROW row;
- pstring temp;
- unsigned int num_fields;
- DOM_SID sid;
-
- num_fields = mysql_num_fields(r);
- row = mysql_fetch_row(r);
- if (!row)
- return NT_STATUS_INVALID_PARAMETER;
-
- pdb_set_logon_time(u, xatol(row[0]), PDB_SET);
- pdb_set_logoff_time(u, xatol(row[1]), PDB_SET);
- pdb_set_kickoff_time(u, xatol(row[2]), PDB_SET);
- pdb_set_pass_last_set_time(u, xatol(row[3]), PDB_SET);
- pdb_set_pass_can_change_time(u, xatol(row[4]), PDB_SET);
- pdb_set_pass_must_change_time(u, xatol(row[5]), PDB_SET);
- pdb_set_username(u, row[6], PDB_SET);
- pdb_set_domain(u, row[7], PDB_SET);
- pdb_set_nt_username(u, row[8], PDB_SET);
- pdb_set_fullname(u, row[9], PDB_SET);
- pdb_set_homedir(u, row[10], PDB_SET);
- pdb_set_dir_drive(u, row[11], PDB_SET);
- pdb_set_logon_script(u, row[12], PDB_SET);
- pdb_set_profile_path(u, row[13], PDB_SET);
- pdb_set_acct_desc(u, row[14], PDB_SET);
- pdb_set_workstations(u, row[15], PDB_SET);
- pdb_set_unknown_str(u, row[16], PDB_SET);
- pdb_set_munged_dial(u, row[17], PDB_SET);
-
- if(!row[18] || !string_to_sid(&sid, row[18])) {
- DEBUG(0,("No user SID retrieved from database!\n"));
- } else {
- pdb_set_user_sid(u, &sid, PDB_SET);
- }
-
- if(row[19]) {
- string_to_sid(&sid, row[19]);
- pdb_set_group_sid(u, &sid, PDB_SET);
- }
-
- if (pdb_gethexpwd(row[20], temp))
- pdb_set_lanman_passwd(u, temp, PDB_SET);
- if (pdb_gethexpwd(row[21], temp))
- pdb_set_nt_passwd(u, temp, PDB_SET);
-
- /* Only use plaintext password storage when lanman and nt are
- * NOT used */
- if (!row[20] || !row[21])
- pdb_set_plaintext_passwd(u, row[22]);
-
- pdb_set_acct_ctrl(u, xatol(row[23]), PDB_SET);
- pdb_set_logon_divs(u, xatol(row[24]), PDB_SET);
- pdb_set_hours_len(u, xatol(row[25]), PDB_SET);
- pdb_set_bad_password_count(u, xatol(row[26]), PDB_SET);
- pdb_set_logon_count(u, xatol(row[27]), PDB_SET);
- pdb_set_unknown_6(u, xatol(row[28]), PDB_SET);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
-{
- struct pdb_mysql_data *data =
- (struct pdb_mysql_data *) methods->private_data;
- char *query;
- int ret;
-
- if (!data || !(data->handle)) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- query = sql_account_query_select(NULL, data->location, update, SQL_SEARCH_NONE, NULL);
-
- ret = mysql_query(data->handle, query);
- talloc_free(query);
-
- if (ret) {
- DEBUG(0,
- ("Error executing MySQL query %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- data->pwent = mysql_store_result(data->handle);
-
- if (data->pwent == NULL) {
- DEBUG(0,
- ("Error storing results: %s\n", mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5,
- ("mysqlsam_setsampwent succeeded(%llu results)!\n",
- mysql_num_rows(data->pwent)));
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void mysqlsam_endsampwent(struct pdb_methods *methods)
-{
- struct pdb_mysql_data *data =
- (struct pdb_mysql_data *) methods->private_data;
-
- if (data == NULL) {
- DEBUG(0, ("invalid handle!\n"));
- return;
- }
-
- if (data->pwent != NULL)
- mysql_free_result(data->pwent);
-
- data->pwent = NULL;
-
- DEBUG(5, ("mysql_endsampwent called\n"));
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS mysqlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * user)
-{
- struct pdb_mysql_data *data;
-
- SET_DATA(data, methods);
-
- if (data->pwent == NULL) {
- DEBUG(0, ("invalid pwent\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return row_to_sam_account(data->pwent, user);
-}
-
-static NTSTATUS mysqlsam_select_by_field(struct pdb_methods * methods, SAM_ACCOUNT * user,
- enum sql_search_field field, const char *sname)
-{
- char *esc_sname;
- char *query;
- NTSTATUS ret;
- MYSQL_RES *res;
- int mysql_ret;
- struct pdb_mysql_data *data;
- char *tmp_sname;
- TALLOC_CTX *mem_ctx = talloc_init("mysqlsam_select_by_field");
-
- SET_DATA(data, methods);
-
- esc_sname = talloc_array(mem_ctx, char, strlen(sname) * 2 + 1);
- if (!esc_sname) {
- talloc_free(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- tmp_sname = talloc_strdup(mem_ctx, sname);
-
- /* Escape sname */
- mysql_real_escape_string(data->handle, esc_sname, tmp_sname,
- strlen(tmp_sname));
-
- talloc_free(tmp_sname);
-
- if (user == NULL) {
- DEBUG(0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
- talloc_free(mem_ctx);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- query = sql_account_query_select(mem_ctx, data->location, True, field, esc_sname);
-
- talloc_free(esc_sname);
-
- DEBUG(5, ("Executing query %s\n", query));
-
- mysql_ret = mysql_query(data->handle, query);
-
- talloc_free(query);
-
- if (mysql_ret) {
- DEBUG(0,
- ("Error while executing MySQL query %s\n",
- mysql_error(data->handle)));
- talloc_free(mem_ctx);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- res = mysql_store_result(data->handle);
- if (res == NULL) {
- DEBUG(0,
- ("Error storing results: %s\n", mysql_error(data->handle)));
- talloc_free(mem_ctx);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = row_to_sam_account(res, user);
- mysql_free_result(res);
- talloc_free(mem_ctx);
-
- return ret;
-}
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS mysqlsam_getsampwnam(struct pdb_methods *methods, SAM_ACCOUNT * user,
- const char *sname)
-{
- struct pdb_mysql_data *data;
-
- SET_DATA(data, methods);
-
- if (!sname) {
- DEBUG(0, ("invalid name specified"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- return mysqlsam_select_by_field(methods, user,
- SQL_SEARCH_USER_NAME, sname);
-}
-
-
-/***************************************************************************
- Search by sid
- **************************************************************************/
-
-static NTSTATUS mysqlsam_getsampwsid(struct pdb_methods *methods, SAM_ACCOUNT * user,
- const DOM_SID * sid)
-{
- struct pdb_mysql_data *data;
- fstring sid_str;
-
- SET_DATA(data, methods);
-
- sid_to_string(sid_str, sid);
-
- return mysqlsam_select_by_field(methods, user, SQL_SEARCH_USER_SID, sid_str);
-}
-
-/***************************************************************************
- Delete a SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS mysqlsam_delete_sam_account(struct pdb_methods *methods,
- SAM_ACCOUNT * sam_pass)
-{
- const char *sname = pdb_get_username(sam_pass);
- char *esc;
- char *query;
- int ret;
- struct pdb_mysql_data *data;
- char *tmp_sname;
- TALLOC_CTX *mem_ctx;
- SET_DATA(data, methods);
-
- if (!methods) {
- DEBUG(0, ("invalid methods!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (struct pdb_mysql_data *) methods->private_data;
- if (!data || !(data->handle)) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- if (!sname) {
- DEBUG(0, ("invalid name specified\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- mem_ctx = talloc_init("mysqlsam_delete_sam_account");
-
- /* Escape sname */
- esc = talloc_array(mem_ctx, char, strlen(sname) * 2 + 1);
- if (!esc) {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- tmp_sname = talloc_strdup(mem_ctx, sname);
-
- mysql_real_escape_string(data->handle, esc, tmp_sname,
- strlen(tmp_sname));
-
- talloc_free(tmp_sname);
-
- query = sql_account_query_delete(mem_ctx, data->location, esc);
-
- talloc_free(esc);
-
- ret = mysql_query(data->handle, query);
-
- talloc_free(query);
-
- if (ret) {
- DEBUG(0,
- ("Error while executing query: %s\n",
- mysql_error(data->handle)));
- talloc_free(mem_ctx);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("User '%s' deleted\n", sname));
- talloc_free(mem_ctx);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_replace_sam_account(struct pdb_methods *methods,
- const SAM_ACCOUNT * newpwd, char isupdate)
-{
- struct pdb_mysql_data *data;
- char *query;
-
- if (!methods) {
- DEBUG(0, ("invalid methods!\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (struct pdb_mysql_data *) methods->private_data;
-
- if (data == NULL || data->handle == NULL) {
- DEBUG(0, ("invalid handle!\n"));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- query = sql_account_query_update(NULL, data->location, newpwd, isupdate);
- if ( query == NULL ) /* Nothing to update. */
- return NT_STATUS_OK;
-
- /* Execute the query */
- if (mysql_query(data->handle, query)) {
- DEBUG(0,
- ("Error executing %s, %s\n", query,
- mysql_error(data->handle)));
- talloc_free(query);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- talloc_free(query);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS mysqlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT * newpwd)
-{
- return mysqlsam_replace_sam_account(methods, newpwd, 0);
-}
-
-static NTSTATUS mysqlsam_update_sam_account(struct pdb_methods *methods,
- SAM_ACCOUNT * newpwd)
-{
- return mysqlsam_replace_sam_account(methods, newpwd, 1);
-}
-
-static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_methods ** pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- struct pdb_mysql_data *data;
-
- mysqlsam_debug_level = debug_add_class("mysqlsam");
- if (mysqlsam_debug_level == -1) {
- mysqlsam_debug_level = DBGC_ALL;
- DEBUG(0,
- ("mysqlsam: Couldn't register custom debugging class!\n"));
- }
-
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_methods specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "mysqlsam";
-
- (*pdb_method)->setsampwent = mysqlsam_setsampwent;
- (*pdb_method)->endsampwent = mysqlsam_endsampwent;
- (*pdb_method)->getsampwent = mysqlsam_getsampwent;
- (*pdb_method)->getsampwnam = mysqlsam_getsampwnam;
- (*pdb_method)->getsampwsid = mysqlsam_getsampwsid;
- (*pdb_method)->add_sam_account = mysqlsam_add_sam_account;
- (*pdb_method)->update_sam_account = mysqlsam_update_sam_account;
- (*pdb_method)->delete_sam_account = mysqlsam_delete_sam_account;
-
- data = talloc(pdb_context->mem_ctx, struct pdb_mysql_data);
- (*pdb_method)->private_data = data;
- data->handle = NULL;
- data->pwent = NULL;
-
- if (!location) {
- DEBUG(0, ("No identifier specified. Check the Samba HOWTO Collection for details\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data->location = smb_xstrdup(location);
-
- DEBUG(1,
- ("Connecting to database server, host: %s, user: %s, database: %s, port: %ld\n",
- config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
- config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql database", CONFIG_DB_DEFAULT),
- xatol(config_value(data, "mysql port", CONFIG_PORT_DEFAULT))));
-
- /* Do the mysql initialization */
- data->handle = mysql_init(NULL);
- if (!data->handle) {
- DEBUG(0, ("Failed to connect to server\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if(!sql_account_config_valid(data->location)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Process correct entry in $HOME/.my.conf */
- if (!mysql_real_connect(data->handle,
- config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
- config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql password", CONFIG_PASS_DEFAULT),
- config_value(data, "mysql database", CONFIG_DB_DEFAULT),
- xatol(config_value (data, "mysql port", CONFIG_PORT_DEFAULT)),
- NULL, 0)) {
- DEBUG(0,
- ("Failed to connect to mysql database: error: %s\n",
- mysql_error(data->handle)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- DEBUG(5, ("Connected to mysql db\n"));
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_mysql_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "mysql", mysqlsam_init);
-}
diff --git a/source/passdb/pdb_nds.c b/source/passdb/pdb_nds.c
index cf2d1d7c8a8..a82f4e48d4e 100644
--- a/source/passdb/pdb_nds.c
+++ b/source/passdb/pdb_nds.c
@@ -741,7 +741,7 @@ int pdb_nds_set_password(
*********************************************************************/
static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
- SAM_ACCOUNT *sam_acct, BOOL success)
+ struct samu *sam_acct, BOOL success)
{
struct ldapsam_privates *ldap_state;
@@ -771,13 +771,16 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
result = pdb_get_backend_private_data(sam_acct, methods);
if (!result) {
- attr_list = get_userattr_list(ldap_state->schema_ver);
+ attr_list = get_userattr_list(NULL,
+ ldap_state->schema_ver);
rc = ldapsam_search_suffix_by_name(ldap_state, username, &result, attr_list );
- free_attr_list( attr_list );
+ TALLOC_FREE( attr_list );
if (rc != LDAP_SUCCESS) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- pdb_set_backend_private_data(sam_acct, result, private_data_free_fn, methods, PDB_CHANGED);
+ pdb_set_backend_private_data(sam_acct, result, NULL,
+ methods, PDB_CHANGED);
+ talloc_autofree_ldapmsg(sam_acct, result);
}
if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
@@ -816,7 +819,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
rc = ldap_simple_bind_s(ld, dn, clear_text_pw);
if (rc == LDAP_SUCCESS) {
DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Successful for %s\n", username));
- ldap_unbind_ext(ld, NULL, NULL);
+ ldap_unbind(ld);
} else {
NTSTATUS nt_status = NT_STATUS_ACCOUNT_RESTRICTION;
DEBUG(5,("pdb_nds_update_login_attempts: ldap_simple_bind_s Failed for %s\n", username));
@@ -845,10 +848,11 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
}
/**********************************************************************
- Intitalise the parts of the pdb_context that are common to NDS_ldapsam modes
+ Intitalise the parts of the pdb_methods structuire that are common
+ to NDS_ldapsam modes
*********************************************************************/
-static NTSTATUS pdb_init_NDS_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+static NTSTATUS pdb_init_NDS_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
{
struct ldapsam_privates *ldap_state = (*pdb_method)->private_data;
@@ -869,13 +873,13 @@ static NTSTATUS pdb_init_NDS_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHOD
Initialise the 'nds compat' mode for pdb_ldap
*********************************************************************/
-static NTSTATUS pdb_init_NDS_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+static NTSTATUS pdb_init_NDS_ldapsam_compat(struct pdb_methods **pdb_method, const char *location)
{
- NTSTATUS nt_status = pdb_init_ldapsam_compat(pdb_context, pdb_method, location);
+ NTSTATUS nt_status = pdb_init_ldapsam_compat(pdb_method, location);
(*pdb_method)->name = "NDS_ldapsam_compat";
- pdb_init_NDS_ldapsam_common(pdb_context, pdb_method, location);
+ pdb_init_NDS_ldapsam_common(pdb_method, location);
return nt_status;
}
@@ -885,13 +889,13 @@ static NTSTATUS pdb_init_NDS_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHOD
Initialise the 'nds' normal mode for pdb_ldap
*********************************************************************/
-static NTSTATUS pdb_init_NDS_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+static NTSTATUS pdb_init_NDS_ldapsam(struct pdb_methods **pdb_method, const char *location)
{
- NTSTATUS nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location);
+ NTSTATUS nt_status = pdb_init_ldapsam(pdb_method, location);
(*pdb_method)->name = "NDS_ldapsam";
- pdb_init_NDS_ldapsam_common(pdb_context, pdb_method, location);
+ pdb_init_NDS_ldapsam_common(pdb_method, location);
return nt_status;
}
diff --git a/source/passdb/pdb_pgsql.c b/source/passdb/pdb_pgsql.c
deleted file mode 100644
index 196fe8f855d..00000000000
--- a/source/passdb/pdb_pgsql.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * PostgresSQL password backend for samba
- * Copyright (C) Hamish Friedlander 2003
- * Copyright (C) Jelmer Vernooij 2004
- *
- * 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 2 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, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include <libpq-fe.h>
-
-#define CONFIG_HOST_DEFAULT "localhost"
-#define CONFIG_USER_DEFAULT "samba"
-#define CONFIG_PASS_DEFAULT ""
-#define CONFIG_PORT_DEFAULT "5432"
-#define CONFIG_DB_DEFAULT "samba"
-
-/* handles for doing db transactions */
-typedef struct pdb_pgsql_data {
- PGconn *master_handle ;
- PGconn *handle ;
-
- PGresult *pwent ;
- long currow ;
- const char *db ;
- const char *host ;
- const char *port ;
- const char *user ;
- const char *pass ;
-
- const char *location ;
-} pdb_pgsql_data ;
-
-struct pdb_context *the_pdb_context;
-
-#define SET_DATA(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return NT_STATUS_INVALID_PARAMETER; \
- } \
- data = (struct pdb_pgsql_data *)methods->private_data; \
-}
-
-
-#define SET_DATA_QUIET(data,methods) { \
- if(!methods){ \
- DEBUG(0, ("invalid methods!\n")); \
- return ; \
- } \
- data = (struct pdb_pgsql_data *)methods->private_data; \
-}
-
-
-#define config_value( data, name, default_value ) \
- lp_parm_const_string( GLOBAL_SECTION_SNUM, (data)->location, name, default_value )
-
-static PGconn *pgsqlsam_connect( struct pdb_pgsql_data *data )
-{
- PGconn *handle;
-
- DEBUG
- (
- 1,
- (
- "Connecting to database server, host: %s, user: %s, password: XXXXXX, database: %s, port: %s\n",
- data->host, data->user, data->db, data->port
- )
- ) ;
-
- /* Do the pgsql initialization */
- handle = PQsetdbLogin(
- data->host,
- data->port,
- NULL,
- NULL,
- data->db,
- data->user,
- data->pass
- ) ;
-
- if ( handle != NULL && PQstatus( handle ) != CONNECTION_OK )
- {
- DEBUG( 0, ("Failed to connect to pgsql database: error: %s\n",
- (handle != NULL ? PQerrorMessage( handle ) : "")) ) ;
- return NULL;
- }
-
- DEBUG( 5, ("Connected to pgsql database\n") ) ;
- return handle;
-}
-
-/* The assumption here is that the master process will get connection 0,
- * and all the renaining ones just one connection for their etire life span.
- */
-static PGconn *choose_connection( struct pdb_pgsql_data *data )
-{
- if ( data->master_handle == NULL )
- {
- data->master_handle = pgsqlsam_connect( data );
- return data->master_handle ;
- }
-
- /* Master connection != NULL, so we are just another process. */
-
- /* If we didn't connect yet, do it now. */
- if ( data->handle == NULL )
- {
- data->handle = pgsqlsam_connect( data );
- }
-
- return data->handle ;
-}
-
-static long PQgetlong( PGresult *r, long row, long col )
-{
- if ( PQgetisnull( r, row, col ) ) return 0 ;
-
- return atol( PQgetvalue( r, row, col ) ) ;
-}
-
-static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
-{
- pstring temp ;
- DOM_SID sid ;
- unsigned char *hours ;
- size_t hours_len = 0 ;
-
- if ( row >= PQntuples( r ) ) return NT_STATUS_INVALID_PARAMETER ;
-
- pdb_set_logon_time ( u, PQgetlong ( r, row, 0 ), PDB_SET ) ;
- pdb_set_logoff_time ( u, PQgetlong ( r, row, 1 ), PDB_SET ) ;
- pdb_set_kickoff_time ( u, PQgetlong ( r, row, 2 ), PDB_SET ) ;
- pdb_set_pass_last_set_time ( u, PQgetlong ( r, row, 3 ), PDB_SET ) ;
- pdb_set_pass_can_change_time ( u, PQgetlong ( r, row, 4 ), PDB_SET ) ;
- pdb_set_pass_must_change_time( u, PQgetlong ( r, row, 5 ), PDB_SET ) ;
- pdb_set_username ( u, PQgetvalue( r, row, 6 ), PDB_SET ) ;
- pdb_set_domain ( u, PQgetvalue( r, row, 7 ), PDB_SET ) ;
- pdb_set_nt_username ( u, PQgetvalue( r, row, 8 ), PDB_SET ) ;
- pdb_set_fullname ( u, PQgetvalue( r, row, 9 ), PDB_SET ) ;
- pdb_set_homedir ( u, PQgetvalue( r, row, 10 ), PDB_SET ) ;
- pdb_set_dir_drive ( u, PQgetvalue( r, row, 11 ), PDB_SET ) ;
- pdb_set_logon_script ( u, PQgetvalue( r, row, 12 ), PDB_SET ) ;
- pdb_set_profile_path ( u, PQgetvalue( r, row, 13 ), PDB_SET ) ;
- pdb_set_acct_desc ( u, PQgetvalue( r, row, 14 ), PDB_SET ) ;
- pdb_set_workstations ( u, PQgetvalue( r, row, 15 ), PDB_SET ) ;
- pdb_set_unknown_str ( u, PQgetvalue( r, row, 16 ), PDB_SET ) ;
- pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ;
-
- pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ;
- pdb_set_logon_divs ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ;
- pdb_set_hours_len ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
- pdb_set_bad_password_count ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ;
- pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ;
- pdb_set_unknown_6 ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ;
- hours = PQgetvalue ( r, row, 29 );
- if ( hours != NULL ) {
- hours = PQunescapeBytea ( hours, &hours_len ) ;
- if ( hours_len > 0 )
- pdb_set_hours ( u, hours, PDB_SET ) ;
- free ( hours );
- }
-
- if ( !PQgetisnull( r, row, 18 ) ) {
- string_to_sid( &sid, PQgetvalue( r, row, 18 ) ) ;
- pdb_set_user_sid ( u, &sid, PDB_SET ) ;
- }
-
- if ( !PQgetisnull( r, row, 19 ) ) {
- string_to_sid( &sid, PQgetvalue( r, row, 19 ) ) ;
- pdb_set_group_sid( u, &sid, PDB_SET ) ;
- }
-
- if ( pdb_gethexpwd( PQgetvalue( r, row, 20 ), temp ), PDB_SET ) pdb_set_lanman_passwd( u, temp, PDB_SET ) ;
- if ( pdb_gethexpwd( PQgetvalue( r, row, 21 ), temp ), PDB_SET ) pdb_set_nt_passwd ( u, temp, PDB_SET ) ;
-
- /* Only use plaintext password storage when lanman and nt are NOT used */
- if ( PQgetisnull( r, row, 20 ) || PQgetisnull( r, row, 21 ) ) pdb_set_plaintext_passwd( u, PQgetvalue( r, row, 22 ) ) ;
-
- return NT_STATUS_OK ;
-}
-
-static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
-{
- struct pdb_pgsql_data *data ;
- PGconn *handle ;
- char *query ;
- NTSTATUS retval ;
-
- SET_DATA( data, methods ) ;
-
- /* Connect to the DB. */
- handle = choose_connection( data );
- if ( handle == NULL )
- return NT_STATUS_UNSUCCESSFUL ;
- DEBUG( 5, ("CONNECTING pgsqlsam_setsampwent\n") ) ;
-
- query = sql_account_query_select(NULL, data->location, update, SQL_SEARCH_NONE, NULL);
-
- /* Do it */
- DEBUG( 5, ("Executing query %s\n", query) ) ;
- data->pwent = PQexec( handle, query ) ;
- data->currow = 0 ;
-
- /* Result? */
- if ( data->pwent == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( handle ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else if ( PQresultStatus( data->pwent ) != PGRES_TUPLES_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( data->pwent ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else
- {
- DEBUG( 5, ("pgsqlsam_setsampwent succeeded(%d results)!\n", PQntuples(data->pwent)) ) ;
- retval = NT_STATUS_OK ;
- }
-
- talloc_free(query);
- return retval ;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void pgsqlsam_endsampwent(struct pdb_methods *methods)
-{
- struct pdb_pgsql_data *data ;
-
- SET_DATA_QUIET( data, methods ) ;
-
- if (data->pwent != NULL)
- {
- PQclear( data->pwent ) ;
- }
-
- data->pwent = NULL ;
- data->currow = 0 ;
-
- DEBUG( 5, ("pgsql_endsampwent called\n") ) ;
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS pgsqlsam_getsampwent( struct pdb_methods *methods, SAM_ACCOUNT *user )
-{
- struct pdb_pgsql_data *data;
- NTSTATUS retval ;
-
- SET_DATA( data, methods ) ;
-
- if ( data->pwent == NULL )
- {
- DEBUG( 0, ("invalid pwent\n") ) ;
- return NT_STATUS_INVALID_PARAMETER ;
- }
-
- retval = row_to_sam_account( data->pwent, data->currow, user ) ;
- data->currow++ ;
-
- return retval ;
-}
-
-static NTSTATUS pgsqlsam_select_by_field ( struct pdb_methods *methods, SAM_ACCOUNT *user, enum sql_search_field field, const char *sname )
-{
- struct pdb_pgsql_data *data ;
- PGconn *handle ;
-
- char *esc ;
- char *query ;
-
- PGresult *result ;
- NTSTATUS retval ;
-
- SET_DATA(data, methods);
-
- if ( user == NULL )
- {
- DEBUG( 0, ("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n") ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG( 5, ("pgsqlsam_select_by_field: getting data where %d = %s(nonescaped)\n", field, sname) ) ;
-
- /* Escape sname */
- esc = talloc_array(NULL, char, strlen(sname) * 2 + 1);
- if ( !esc )
- {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- //tmp_sname = smb_xstrdup(sname);
- PQescapeString( esc, sname, strlen(sname) ) ;
-
- /* Connect to the DB. */
- handle = choose_connection( data );
- if ( handle == NULL )
- return NT_STATUS_UNSUCCESSFUL ;
-
- query = sql_account_query_select(NULL, data->location, True, field, esc);
-
- /* Do it */
- DEBUG( 5, ("Executing query %s\n", query) ) ;
- result = PQexec( handle, query ) ;
-
- /* Result? */
- if ( result == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( handle ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else if ( PQresultStatus( result ) != PGRES_TUPLES_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else
- {
- retval = row_to_sam_account( result, 0, user ) ;
- }
-
- talloc_free( esc ) ;
- talloc_free( query ) ;
-
- if ( result != NULL )
- PQclear( result ) ;
-
- return retval ;
-}
-
-/******************************************************************
- Lookup a name in the SAM database
- ******************************************************************/
-
-static NTSTATUS pgsqlsam_getsampwnam ( struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname )
-{
- struct pdb_pgsql_data *data;
- size_t i, l;
- char *lowercasename;
- NTSTATUS result;
-
- SET_DATA(data, methods);
-
- if ( !sname )
- {
- DEBUG( 0, ("invalid name specified") ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- lowercasename = smb_xstrdup(sname);
- l = strlen(lowercasename);
- for(i = 0; i < l; i++) {
- lowercasename[i] = tolower_ascii(lowercasename[i]);
- }
-
- result = pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_NAME, lowercasename ) ;
-
- SAFE_FREE( lowercasename ) ;
-
- return result;
-}
-
-
-/***************************************************************************
- Search by sid
- **************************************************************************/
-
-static NTSTATUS pgsqlsam_getsampwsid ( struct pdb_methods *methods, SAM_ACCOUNT *user, const DOM_SID *sid )
-{
- struct pdb_pgsql_data *data;
- fstring sid_str;
-
- SET_DATA( data, methods ) ;
-
- sid_to_string( sid_str, sid ) ;
-
- return pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_SID, sid_str ) ;
-}
-
-/***************************************************************************
- Delete a SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS pgsqlsam_delete_sam_account( struct pdb_methods *methods, SAM_ACCOUNT *sam_pass )
-{
- struct pdb_pgsql_data *data ;
- PGconn *handle ;
-
- const char *sname = pdb_get_username( sam_pass ) ;
- char *esc ;
- char *query ;
-
- PGresult *result ;
- NTSTATUS retval ;
-
- SET_DATA(data, methods);
-
- if ( !sname )
- {
- DEBUG( 0, ("invalid name specified\n") ) ;
- return NT_STATUS_INVALID_PARAMETER ;
- }
-
- /* Escape sname */
- esc = talloc_array(NULL, char, strlen(sname) * 2 + 1);
- if ( !esc )
- {
- DEBUG(0, ("Can't allocate memory to store escaped name\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- PQescapeString( esc, sname, strlen(sname) ) ;
-
- /* Connect to the DB. */
- handle = choose_connection( data );
- if ( handle == NULL )
- return NT_STATUS_UNSUCCESSFUL ;
-
- query = sql_account_query_delete(NULL, data->location, esc);
-
- /* Do it */
- result = PQexec( handle, query ) ;
-
- if ( result == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( handle ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else if ( PQresultStatus( result ) != PGRES_COMMAND_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ;
- retval = NT_STATUS_UNSUCCESSFUL ;
- }
- else
- {
- DEBUG( 5, ("User '%s' deleted\n", sname) ) ;
- retval = NT_STATUS_OK ;
- }
-
- if ( result != NULL )
- PQclear( result ) ;
- talloc_free( esc ) ;
- talloc_free( query ) ;
-
- return retval ;
-}
-
-static NTSTATUS pgsqlsam_replace_sam_account( struct pdb_methods *methods, const SAM_ACCOUNT *newpwd, char isupdate )
-{
- struct pdb_pgsql_data *data ;
- PGconn *handle ;
- char *query;
- PGresult *result ;
- NTSTATUS retval ;
-
- if ( !methods )
- {
- DEBUG( 0, ("invalid methods!\n") ) ;
- return NT_STATUS_INVALID_PARAMETER ;
- }
-
- data = (struct pdb_pgsql_data *) methods->private_data ;
-
- if ( data == NULL || handle == NULL )
- {
- DEBUG( 0, ("invalid handle!\n") ) ;
- return NT_STATUS_INVALID_HANDLE ;
- }
-
- query = sql_account_query_update(NULL, data->location, newpwd, isupdate);
- if ( query == NULL ) /* Nothing to update. */
- return NT_STATUS_OK;
-
- /* Connect to the DB. */
- handle = choose_connection( data );
- if ( handle == NULL )
- return NT_STATUS_UNSUCCESSFUL ;
-
- result = PQexec( handle, query ) ;
-
- /* Execute the query */
- if ( result == NULL )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQerrorMessage( handle ) ) ) ;
- retval = NT_STATUS_INVALID_PARAMETER;
- }
- else if ( PQresultStatus( result ) != PGRES_COMMAND_OK )
- {
- DEBUG( 0, ("Error executing %s, %s\n", query, PQresultErrorMessage( result ) ) ) ;
- retval = NT_STATUS_INVALID_PARAMETER;
- }
- else
- {
- retval = NT_STATUS_OK;
- }
- if ( result != NULL )
- PQclear( result ) ;
- talloc_free(query);
-
- return retval;
-}
-
-static NTSTATUS pgsqlsam_add_sam_account ( struct pdb_methods *methods, SAM_ACCOUNT *newpwd )
-{
- return pgsqlsam_replace_sam_account( methods, newpwd, 0 ) ;
-}
-
-static NTSTATUS pgsqlsam_update_sam_account ( struct pdb_methods *methods, SAM_ACCOUNT *newpwd )
-{
- return pgsqlsam_replace_sam_account( methods, newpwd, 1 ) ;
-}
-
-static NTSTATUS pgsqlsam_init ( struct pdb_context *pdb_context, struct pdb_methods **pdb_method, const char *location )
-{
- NTSTATUS nt_status ;
- struct pdb_pgsql_data *data ;
-
- if ( !pdb_context )
- {
- DEBUG( 0, ("invalid pdb_methods specified\n") ) ;
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- the_pdb_context = pdb_context;
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "pgsqlsam" ;
-
- (*pdb_method)->setsampwent = pgsqlsam_setsampwent ;
- (*pdb_method)->endsampwent = pgsqlsam_endsampwent ;
- (*pdb_method)->getsampwent = pgsqlsam_getsampwent ;
- (*pdb_method)->getsampwnam = pgsqlsam_getsampwnam ;
- (*pdb_method)->getsampwsid = pgsqlsam_getsampwsid ;
- (*pdb_method)->add_sam_account = pgsqlsam_add_sam_account ;
- (*pdb_method)->update_sam_account = pgsqlsam_update_sam_account ;
- (*pdb_method)->delete_sam_account = pgsqlsam_delete_sam_account ;
-
- data = talloc( pdb_context->mem_ctx, struct pdb_pgsql_data ) ;
- (*pdb_method)->private_data = data ;
-
- data->master_handle = NULL;
- data->handle = NULL;
- data->pwent = NULL ;
-
- if ( !location )
- {
- DEBUG( 0, ("No identifier specified. Check the Samba HOWTO Collection for details\n") ) ;
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data->location = smb_xstrdup( location ) ;
-
- if(!sql_account_config_valid(data->location)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG
- (
- 1,
- (
- "Database server parameters: host: %s, user: %s, password: XXXX, database: %s, port: %s\n",
- config_value( data, "pgsql host" , CONFIG_HOST_DEFAULT ),
- config_value( data, "pgsql user" , CONFIG_USER_DEFAULT ),
- config_value( data, "pgsql database", CONFIG_DB_DEFAULT ),
- config_value( data, "pgsql port" , CONFIG_PORT_DEFAULT )
- )
- ) ;
-
- /* Save the parameters. */
- data->db = config_value( data, "pgsql database", CONFIG_DB_DEFAULT );
- data->host = config_value( data, "pgsql host" , CONFIG_HOST_DEFAULT );
- data->port = config_value( data, "pgsql port" , CONFIG_PORT_DEFAULT );
- data->user = config_value( data, "pgsql user" , CONFIG_USER_DEFAULT );
- data->pass = config_value( data, "pgsql password", CONFIG_PASS_DEFAULT );
-
- DEBUG( 5, ("Pgsql module intialized\n") ) ;
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_pgsql_init(void)
-{
- return smb_register_passdb( PASSDB_INTERFACE_VERSION, "pgsql", pgsqlsam_init ) ;
-}
diff --git a/source/passdb/pdb_plugin.c b/source/passdb/pdb_plugin.c
index 027cd0b5d33..9d835a48ad3 100644
--- a/source/passdb/pdb_plugin.c
+++ b/source/passdb/pdb_plugin.c
@@ -24,7 +24,7 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
-NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+NTSTATUS pdb_init_plugin(struct pdb_methods **pdb_method, const char *location)
{
void * dl_handle;
char *plugin_location, *plugin_name, *p;
@@ -76,5 +76,5 @@ NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
}
DEBUG(5, ("Starting sam plugin %s with location %s\n", plugin_name, plugin_location));
- return plugin_init(pdb_context, pdb_method, plugin_location);
+ return plugin_init(pdb_method, plugin_location);
}
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 487df96e953..b976595008a 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -594,7 +594,6 @@ static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, str
size_t new_entry_length;
char *new_entry;
SMB_OFF_T offpos;
- uint32 max_found_uid = 0;
/* Open the smbpassword file - for update. */
fp = startsmbfilepwent(pfile, PWF_UPDATE, &smbpasswd_state->pw_file_lock_depth);
@@ -619,11 +618,6 @@ static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, str
endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);
return False;
}
-
- /* Look for a free uid for use in non-unix accounts */
- if (pwd->smb_userid > max_found_uid) {
- max_found_uid = pwd->smb_userid;
- }
}
/* Ok - entry doesn't exist. We can add it */
@@ -1143,12 +1137,12 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
}
/*********************************************************************
- Create a smb_passwd struct from a SAM_ACCOUNT.
+ Create a smb_passwd struct from a struct samu.
We will not allocate any new memory. The smb_passwd struct
- should only stay around as long as the SAM_ACCOUNT does.
+ should only stay around as long as the struct samu does.
********************************************************************/
-static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass)
+static BOOL build_smb_pass (struct smb_passwd *smb_pw, const struct samu *sampass)
{
uint32 rid;
@@ -1161,14 +1155,13 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
/* If the user specified a RID, make sure its able to be both stored and retreived */
if (rid == DOMAIN_USER_RID_GUEST) {
- struct passwd *passwd = getpwnam_alloc(lp_guestaccount());
+ struct passwd *passwd = getpwnam_alloc(NULL, lp_guestaccount());
if (!passwd) {
DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount()));
return False;
}
smb_pw->smb_userid=passwd->pw_uid;
- passwd_free(&passwd);
-
+ TALLOC_FREE(passwd);
} else if (algorithmic_pdb_rid_is_user(rid)) {
smb_pw->smb_userid=algorithmic_pdb_user_rid_to_uid(rid);
} else {
@@ -1189,31 +1182,31 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
}
/*********************************************************************
- Create a SAM_ACCOUNT from a smb_passwd struct
+ Create a struct samu from a smb_passwd struct
********************************************************************/
static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
- SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
+ struct samu *sam_pass, const struct smb_passwd *pw_buf)
{
struct passwd *pwfile;
- if (sam_pass==NULL) {
- DEBUG(5,("build_sam_account: SAM_ACCOUNT is NULL\n"));
+ if ( !sam_pass ) {
+ DEBUG(5,("build_sam_account: struct samu is NULL\n"));
return False;
}
/* verify the user account exists */
- if ( !(pwfile = getpwnam_alloc(pw_buf->smb_name)) ) {
+ if ( !(pwfile = getpwnam_alloc(NULL, pw_buf->smb_name)) ) {
DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s with uid "
"%u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
return False;
}
- if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile)))
+ if ( !NT_STATUS_IS_OK( samu_set_unix(sam_pass, pwfile )) )
return False;
- passwd_free(&pwfile);
+ TALLOC_FREE(pwfile);
/* set remaining fields */
@@ -1230,7 +1223,7 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
Functions to be implemented by the new passdb API
****************************************************************/
-static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
+static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
@@ -1270,19 +1263,17 @@ static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
/*****************************************************************
****************************************************************/
-static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, struct samu *user)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *pw_buf=NULL;
BOOL done = False;
+
DEBUG(5,("pdb_getsampwent\n"));
- if (user==NULL) {
+ if ( !user ) {
DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n");
-#endif
return nt_status;
}
@@ -1292,7 +1283,7 @@ static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUN
if (pw_buf == NULL)
return nt_status;
- /* build the SAM_ACCOUNT entry from the smb_passwd struct.
+ /* build the struct samu entry from the smb_passwd struct.
We loop in case the user in the pdb does not exist in
the local system password file */
if (build_sam_account(smbpasswd_state, user, pw_buf))
@@ -1312,7 +1303,7 @@ static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUN
***************************************************************/
static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods,
- SAM_ACCOUNT *sam_acct, const char *username)
+ struct samu *sam_acct, const char *username)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
@@ -1344,14 +1335,11 @@ static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods,
DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
- DEBUG(10,("getsampwnam (smbpasswd): SAM_ACCOUNT is NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to pdb_getsampwnam\n");
-#endif
+ DEBUG(10,("getsampwnam (smbpasswd): struct samu is NULL\n"));
return nt_status;
}
- /* now build the SAM_ACCOUNT */
+ /* now build the struct samu */
if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
return nt_status;
@@ -1359,7 +1347,7 @@ static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods,
return NT_STATUS_OK;
}
-static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
+static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, struct samu *sam_acct, const DOM_SID *sid)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
@@ -1404,14 +1392,11 @@ static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUN
DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
if (!sam_acct) {
- DEBUG(10,("getsampwrid: (smbpasswd) SAM_ACCOUNT is NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to pdb_getsampwrid\n");
-#endif
+ DEBUG(10,("getsampwrid: (smbpasswd) struct samu is NULL\n"));
return nt_status;
}
- /* now build the SAM_ACCOUNT */
+ /* now build the struct samu */
if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))
return nt_status;
@@ -1427,12 +1412,12 @@ static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUN
return NT_STATUS_OK;
}
-static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, struct samu *sampass)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
- /* convert the SAM_ACCOUNT */
+ /* convert the struct samu */
if (!build_smb_pass(&smb_pw, sampass)) {
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1445,12 +1430,12 @@ static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_AC
return NT_STATUS_OK;
}
-static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, struct samu *sampass)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
- /* convert the SAM_ACCOUNT */
+ /* convert the struct samu */
if (!build_smb_pass(&smb_pw, sampass)) {
DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));
return NT_STATUS_UNSUCCESSFUL;
@@ -1465,7 +1450,7 @@ static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM
return NT_STATUS_OK;
}
-static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, struct samu *sampass)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
@@ -1478,21 +1463,27 @@ static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SA
}
static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods,
- SAM_ACCOUNT *old_acct,
+ struct samu *old_acct,
const char *newname)
{
pstring rename_script;
- SAM_ACCOUNT *new_acct = NULL;
+ struct samu *new_acct = NULL;
BOOL interim_account = False;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
if (!*(lp_renameuser_script()))
goto done;
- if (!pdb_copy_sam_account(old_acct, &new_acct) ||
- !pdb_set_username(new_acct, newname, PDB_CHANGED))
+ if ( !(new_acct = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if ( !pdb_copy_sam_account( new_acct, old_acct )
+ || !pdb_set_username(new_acct, newname, PDB_CHANGED))
+ {
goto done;
-
+ }
+
ret = smbpasswd_add_sam_account(my_methods, new_acct);
if (!NT_STATUS_IS_OK(ret))
goto done;
@@ -1505,9 +1496,11 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods,
if (*rename_script) {
int rename_ret;
- pstring_sub(rename_script, "%unew", newname);
- pstring_sub(rename_script, "%uold",
- pdb_get_username(old_acct));
+ string_sub2(rename_script, "%unew", newname, sizeof(pstring),
+ True, False, True);
+ string_sub2(rename_script, "%uold", pdb_get_username(old_acct),
+ sizeof(pstring), True, False, True);
+
rename_ret = smbrun(rename_script, NULL);
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
@@ -1527,11 +1520,16 @@ done:
smbpasswd_delete_sam_account(my_methods, new_acct);
if (new_acct)
- pdb_free_sam(&new_acct);
+ TALLOC_FREE(new_acct);
return (ret);
}
+static BOOL smbpasswd_rid_algorithm(struct pdb_methods *methods)
+{
+ return True;
+}
+
static void free_private_data(void **vp)
{
struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp;
@@ -1542,12 +1540,12 @@ static void free_private_data(void **vp)
/* No need to free any further, as it is talloc()ed */
}
-static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+static NTSTATUS pdb_init_smbpasswd( struct pdb_methods **pdb_method, const char *location )
{
NTSTATUS nt_status;
struct smbpasswd_privates *privates;
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ if ( !NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method )) ) {
return nt_status;
}
@@ -1563,11 +1561,11 @@ static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_m
(*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
(*pdb_method)->rename_sam_account = smbpasswd_rename_sam_account;
- /* Setup private data and free function */
+ (*pdb_method)->rid_algorithm = smbpasswd_rid_algorithm;
- privates = TALLOC_ZERO_P(pdb_context->mem_ctx, struct smbpasswd_privates);
+ /* Setup private data and free function */
- if (!privates) {
+ if ( !(privates = TALLOC_ZERO_P( *pdb_method, struct smbpasswd_privates )) ) {
DEBUG(0, ("talloc() failed for smbpasswd private_data!\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -1575,9 +1573,9 @@ static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_m
/* Store some config details */
if (location) {
- privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, location);
+ privates->smbpasswd_file = talloc_strdup(*pdb_method, location);
} else {
- privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, lp_smb_passwd_file());
+ privates->smbpasswd_file = talloc_strdup(*pdb_method, lp_smb_passwd_file());
}
if (!privates->smbpasswd_file) {
diff --git a/source/passdb/pdb_sql.c b/source/passdb/pdb_sql.c
deleted file mode 100644
index f4f6e0112ae..00000000000
--- a/source/passdb/pdb_sql.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Common PDB SQL backend functions
- * Copyright (C) Jelmer Vernooij 2003-2004
- *
- * 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 2 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, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-#define CONFIG_TABLE_DEFAULT "user"
-#define CONFIG_LOGON_TIME_DEFAULT "logon_time"
-#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time"
-#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time"
-#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time"
-#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time"
-#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time"
-#define CONFIG_USERNAME_DEFAULT "username"
-#define CONFIG_DOMAIN_DEFAULT "domain"
-#define CONFIG_NT_USERNAME_DEFAULT "nt_username"
-#define CONFIG_FULLNAME_DEFAULT "nt_fullname"
-#define CONFIG_HOME_DIR_DEFAULT "home_dir"
-#define CONFIG_DIR_DRIVE_DEFAULT "dir_drive"
-#define CONFIG_LOGON_SCRIPT_DEFAULT "logon_script"
-#define CONFIG_PROFILE_PATH_DEFAULT "profile_path"
-#define CONFIG_ACCT_DESC_DEFAULT "acct_desc"
-#define CONFIG_WORKSTATIONS_DEFAULT "workstations"
-#define CONFIG_UNKNOWN_STR_DEFAULT "unknown_str"
-#define CONFIG_MUNGED_DIAL_DEFAULT "munged_dial"
-#define CONFIG_USER_SID_DEFAULT "user_sid"
-#define CONFIG_GROUP_SID_DEFAULT "group_sid"
-#define CONFIG_LM_PW_DEFAULT "lm_pw"
-#define CONFIG_NT_PW_DEFAULT "nt_pw"
-#define CONFIG_PLAIN_PW_DEFAULT "NULL"
-#define CONFIG_ACCT_CTRL_DEFAULT "acct_ctrl"
-#define CONFIG_LOGON_DIVS_DEFAULT "logon_divs"
-#define CONFIG_HOURS_LEN_DEFAULT "hours_len"
-#define CONFIG_BAD_PASSWORD_COUNT_DEFAULT "bad_password_count"
-#define CONFIG_LOGON_COUNT_DEFAULT "logon_count"
-#define CONFIG_UNKNOWN_6_DEFAULT "unknown_6"
-#define CONFIG_LOGON_HOURS "logon_hours"
-
-/* Used to construct insert and update queries */
-
-typedef struct pdb_sql_query {
- char update;
- char *part1;
- char *part2;
-} pdb_sql_query;
-
-static void pdb_sql_int_field(struct pdb_sql_query *q, const char *name, int value)
-{
- if (!name || strchr(name, '\''))
- return; /* This field shouldn't be set by us */
-
- if (q->update) {
- q->part1 =
- talloc_asprintf_append(q->part1,
- "%s = %d,", name, value);
- } else {
- q->part1 =
- talloc_asprintf_append(q->part1, "%s,", name);
- q->part2 =
- talloc_asprintf_append(q->part2, "%d,", value);
- }
-}
-
-char *sql_escape_string(TALLOC_CTX *mem_ctx, const char *unesc)
-{
- char *esc = talloc_array(mem_ctx, char, strlen(unesc) * 2 + 3);
- size_t pos_unesc = 0, pos_esc = 0;
-
- for(pos_unesc = 0; unesc[pos_unesc]; pos_unesc++) {
- switch(unesc[pos_unesc]) {
- case '\\':
- case '\'':
- case '"':
- esc[pos_esc] = '\\'; pos_esc++;
- default:
- esc[pos_esc] = unesc[pos_unesc]; pos_esc++;
- break;
- }
- }
-
- esc[pos_esc] = '\0';
-
- return esc;
-}
-
-static NTSTATUS pdb_sql_string_field(struct pdb_sql_query *q,
- const char *name, const char *value)
-{
- char *esc_value;
-
- if (!name || !value || !strcmp(value, "") || strchr(name, '\''))
- return NT_STATUS_INVALID_PARAMETER; /* This field shouldn't be set by module */
-
- esc_value = sql_escape_string(q, value);
-
- if (q->update) {
- q->part1 =
- talloc_asprintf_append(q->part1,
- "%s = '%s',", name, esc_value);
- } else {
- q->part1 =
- talloc_asprintf_append(q->part1, "%s,", name);
- q->part2 =
- talloc_asprintf_append(q->part2, "'%s',",
- esc_value);
- }
-
- talloc_free(esc_value);
-
- return NT_STATUS_OK;
-}
-
-#define config_value(data,name,default_value) \
- lp_parm_const_string(GLOBAL_SECTION_SNUM, data, name, default_value)
-
-static const char * config_value_write(const char *location, const char *name, const char *default_value)
-{
- char const *v = NULL;
- char const *swrite = NULL;
-
- v = lp_parm_const_string(GLOBAL_SECTION_SNUM, location, name, default_value);
-
- if (!v)
- return NULL;
-
- swrite = strrchr(v, ':');
-
- /* Default to the same field as read field */
- if (!swrite) {
-
- /* Updating NULL does not make much sense */
- if (!strcmp(v, "NULL"))
- return NULL;
-
- return v;
- }
-
- swrite++;
-
- /* If the field is 0 chars long, we shouldn't write to it */
- if (!strlen(swrite) || !strcmp(swrite, "NULL"))
- return NULL;
-
- /* Otherwise, use the additionally specified */
- return swrite;
-}
-
-static const char * config_value_read(const char *location, const char *name, const char *default_value)
-{
- char *v = NULL;
- char *swrite;
-
- v = lp_parm_talloc_string(GLOBAL_SECTION_SNUM, location, name, default_value);
-
- if (!v)
- return "NULL";
-
- swrite = strrchr(v, ':');
-
- /* If no write is specified, there are no problems */
- if (!swrite) {
- if (strlen(v) == 0)
- return "NULL";
- return (const char *)v;
- }
-
- /* Otherwise, we have to cut the ':write_part' */
- *swrite = '\0';
- if (strlen(v) == 0)
- return "NULL";
-
- return (const char *)v;
-}
-
-char *sql_account_query_select(TALLOC_CTX *mem_ctx, const char *data, BOOL update, enum sql_search_field field, const char *value)
-{
- const char *field_string;
- char *query;
-
- switch(field) {
- case SQL_SEARCH_NONE:
- field_string = "'1'";
- value = "1";
- break;
-
- case SQL_SEARCH_USER_SID:
- field_string = config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT);
- break;
-
- case SQL_SEARCH_USER_NAME:
- field_string = config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT);
- break;
- default:
- field_string = "unknown";
- break;
- }
-
- query = talloc_asprintf(mem_ctx,
- "SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s WHERE %s = '%s'",
- config_value_read(data, "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- config_value_read(data, "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- config_value_read(data, "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- config_value_read(data, "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- config_value_read(data, "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- config_value_read(data, "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT),
- config_value_read(data, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- config_value_read(data, "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- config_value_read(data, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- config_value_read(data, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- config_value_read(data, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- config_value_read(data, "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- config_value_read(data, "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- config_value_read(data, "acct desc column",
- CONFIG_ACCT_DESC_DEFAULT),
- config_value_read(data, "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- config_value_read(data, "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- config_value_read(data, "munged dial column",
- CONFIG_MUNGED_DIAL_DEFAULT),
- config_value_read(data, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- config_value_read(data, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- config_value_read(data, "lanman pass column",
- CONFIG_LM_PW_DEFAULT),
- config_value_read(data, "nt pass column",
- CONFIG_NT_PW_DEFAULT),
- config_value_read(data, "plain pass column",
- CONFIG_PLAIN_PW_DEFAULT),
- config_value_read(data, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- config_value_read(data, "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- config_value_read(data, "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- config_value_read(data, "bad password count column",
- CONFIG_BAD_PASSWORD_COUNT_DEFAULT),
- config_value_read(data, "logon count column",
- CONFIG_LOGON_COUNT_DEFAULT),
- config_value_read(data, "unknown 6 column",
- CONFIG_UNKNOWN_6_DEFAULT),
- config_value_read(data, "logon hours column",
- CONFIG_LOGON_HOURS),
- config_value(data, "table", CONFIG_TABLE_DEFAULT),
- field_string, value
- );
- return query;
-}
-
-char *sql_account_query_delete(TALLOC_CTX *mem_ctx, const char *data, const char *esc)
-{
- char *query;
-
- query = talloc_asprintf(mem_ctx, "DELETE FROM %s WHERE %s = '%s'",
- config_value(data, "table", CONFIG_TABLE_DEFAULT),
- config_value_read(data, "username column",
- CONFIG_USERNAME_DEFAULT), esc);
- return query;
-}
-
-char *sql_account_query_update(TALLOC_CTX *mem_ctx, const char *location, const SAM_ACCOUNT *newpwd, char isupdate)
-{
- char *ret;
- pstring temp;
- fstring sid_str;
- pdb_sql_query *query;
- int some_field_affected = 0;
-
- query = talloc(mem_ctx, pdb_sql_query);
- query->update = isupdate;
-
- /* I know this is somewhat overkill but only the talloc
- * functions have asprint_append and the 'normal' asprintf
- * is a GNU extension */
- query->part2 = talloc_asprintf(query, "%s", "");
- if (query->update) {
- query->part1 =
- talloc_asprintf(query, "UPDATE %s SET ",
- config_value(location, "table",
- CONFIG_TABLE_DEFAULT));
- } else {
- query->part1 =
- talloc_asprintf(query, "INSERT INTO %s (",
- config_value(location, "table",
- CONFIG_TABLE_DEFAULT));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_ACCTCTRL)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location, "acct ctrl column",
- CONFIG_ACCT_CTRL_DEFAULT),
- pdb_get_acct_ctrl(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_LOGONTIME)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "logon time column",
- CONFIG_LOGON_TIME_DEFAULT),
- pdb_get_logon_time(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_LOGOFFTIME)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "logoff time column",
- CONFIG_LOGOFF_TIME_DEFAULT),
- pdb_get_logoff_time(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_KICKOFFTIME)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "kickoff time column",
- CONFIG_KICKOFF_TIME_DEFAULT),
- pdb_get_kickoff_time(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_CANCHANGETIME)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "pass can change time column",
- CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT),
- pdb_get_pass_can_change_time(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_MUSTCHANGETIME)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "pass must change time column",
- CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT),
- pdb_get_pass_must_change_time(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_PASSLASTSET)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "pass last set time column",
- CONFIG_PASS_LAST_SET_TIME_DEFAULT),
- pdb_get_pass_last_set_time(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_HOURSLEN)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "hours len column",
- CONFIG_HOURS_LEN_DEFAULT),
- pdb_get_hours_len(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_LOGONDIVS)) {
- some_field_affected = 1;
- pdb_sql_int_field(query,
- config_value_write(location,
- "logon divs column",
- CONFIG_LOGON_DIVS_DEFAULT),
- pdb_get_logon_divs(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_USERSID)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "user sid column",
- CONFIG_USER_SID_DEFAULT),
- sid_to_string(sid_str,
- pdb_get_user_sid(newpwd)));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_GROUPSID)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "group sid column",
- CONFIG_GROUP_SID_DEFAULT),
- sid_to_string(sid_str,
- pdb_get_group_sid(newpwd)));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_USERNAME)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "username column",
- CONFIG_USERNAME_DEFAULT),
- pdb_get_username(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_DOMAIN)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "domain column",
- CONFIG_DOMAIN_DEFAULT),
- pdb_get_domain(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_USERNAME)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location,
- "nt username column",
- CONFIG_NT_USERNAME_DEFAULT),
- pdb_get_nt_username(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_FULLNAME)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "fullname column",
- CONFIG_FULLNAME_DEFAULT),
- pdb_get_fullname(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_LOGONSCRIPT)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location,
- "logon script column",
- CONFIG_LOGON_SCRIPT_DEFAULT),
- pdb_get_logon_script(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_PROFILE)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location,
- "profile path column",
- CONFIG_PROFILE_PATH_DEFAULT),
- pdb_get_profile_path(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_DRIVE)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "dir drive column",
- CONFIG_DIR_DRIVE_DEFAULT),
- pdb_get_dir_drive(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_SMBHOME)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location, "home dir column",
- CONFIG_HOME_DIR_DEFAULT),
- pdb_get_homedir(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_WORKSTATIONS)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location,
- "workstations column",
- CONFIG_WORKSTATIONS_DEFAULT),
- pdb_get_workstations(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_UNKNOWNSTR)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location,
- "unknown string column",
- CONFIG_UNKNOWN_STR_DEFAULT),
- pdb_get_workstations(newpwd));
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_LMPASSWD)) {
- some_field_affected = 1;
- pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd),
- pdb_get_acct_ctrl(newpwd));
- pdb_sql_string_field(query,
- config_value_write(location,
- "lanman pass column",
- CONFIG_LM_PW_DEFAULT), temp);
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_NTPASSWD)) {
- some_field_affected = 1;
- pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd),
- pdb_get_acct_ctrl(newpwd));
- pdb_sql_string_field(query,
- config_value_write(location, "nt pass column",
- CONFIG_NT_PW_DEFAULT), temp);
- }
-
- if (!isupdate || IS_SAM_CHANGED(newpwd, PDB_HOURS)) {
- some_field_affected = 1;
- pdb_sql_string_field(query,
- config_value_write(location,
- "logon hours column",
- CONFIG_LOGON_HOURS),
- (const char *)pdb_get_hours(newpwd));
- }
-
- if (!some_field_affected) {
- talloc_free(query);
- return NULL;
- }
-
- if (query->update) {
- query->part1[strlen(query->part1) - 1] = '\0';
- query->part1 = talloc_asprintf(
- mem_ctx, "%s WHERE %s = '%s'", query->part1,
- config_value_read(location,
- "user sid column",
- CONFIG_USER_SID_DEFAULT),
- sid_to_string(sid_str, pdb_get_user_sid (newpwd)));
- } else {
- query->part2[strlen(query->part2) - 1] = ')';
- query->part1[strlen(query->part1) - 1] = ')';
- query->part1 =
- talloc_asprintf_append(query->part1,
- " VALUES (%s", query->part2);
- }
-
- ret = talloc_strdup(mem_ctx, query->part1);
- talloc_free(query);
- return ret;
-}
-
-BOOL sql_account_config_valid(const char *data)
-{
- const char *sid_column, *username_column;
-
- sid_column = config_value_read(data, "user sid column", CONFIG_USER_SID_DEFAULT);
- username_column = config_value_read(data, "username column", CONFIG_USERNAME_DEFAULT);
-
- if(!strcmp(sid_column,"NULL") || !strcmp(username_column, "NULL")) {
- DEBUG(0,("Please specify both a valid 'user sid column' and a valid 'username column' in smb.conf\n"));
- return False;
- }
-
- return True;
-}
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index de79b4096a6..ba8124d3923 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -3,7 +3,7 @@
* SMB parameters and setup
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Simo Sorce 2000-2003
- * Copyright (C) Gerald Carter 2000
+ * Copyright (C) Gerald Carter 2000-2006
* Copyright (C) Jeremy Allison 2001
* Copyright (C) Andrew Bartlett 2002
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
@@ -38,60 +38,666 @@ static int tdbsam_debug_level = DBGC_ALL;
#endif
-#define TDBSAM_VERSION 2 /* Most recent TDBSAM version */
+#define TDBSAM_VERSION 3 /* Most recent TDBSAM version */
#define TDBSAM_VERSION_STRING "INFO/version"
#define PASSDB_FILE_NAME "passdb.tdb"
#define USERPREFIX "USER_"
#define RIDPREFIX "RID_"
#define PRIVPREFIX "PRIV_"
-#define tdbsamver_t int32
-
-struct tdbsam_privates {
- TDB_CONTEXT *passwd_tdb;
-
- /* retrive-once info */
- const char *tdbsam_location;
-};
struct pwent_list {
struct pwent_list *prev, *next;
TDB_DATA key;
};
static struct pwent_list *tdbsam_pwent_list;
+static BOOL pwent_initialized;
+
+/* GLOBAL TDB SAM CONTEXT */
+
+static TDB_CONTEXT *tdbsam;
+static int ref_count = 0;
+static pstring tdbsam_filename;
+
+/**********************************************************************
+ Marshall/unmarshall struct samu structs.
+ *********************************************************************/
+#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
+#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
+#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
-/**
- * Convert old TDBSAM to the latest version.
- * @param pdb_tdb A pointer to the opened TDBSAM file which must be converted.
- * This file must be opened with read/write access.
- * @param from Current version of the TDBSAM file.
- * @return True if the conversion has been successful, false otherwise.
- **/
+/*********************************************************************
+*********************************************************************/
-static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
+static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buflen)
{
- const char * vstring = TDBSAM_VERSION_STRING;
- SAM_ACCOUNT *user = NULL;
- const char *prefix = USERPREFIX;
- TDB_DATA data, key, old_key;
- uint8 *buf = NULL;
- BOOL ret;
- if (pdb_tdb == NULL) {
- DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n"));
+ /* times are stored as 32bit integer
+ take care on system with 64bit wide time_t
+ --SSS */
+ uint32 logon_time,
+ logoff_time,
+ kickoff_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time;
+ char *username = NULL;
+ char *domain = NULL;
+ char *nt_username = NULL;
+ char *dir_drive = NULL;
+ char *unknown_str = NULL;
+ char *munged_dial = NULL;
+ char *fullname = NULL;
+ char *homedir = NULL;
+ char *logon_script = NULL;
+ char *profile_path = NULL;
+ char *acct_desc = NULL;
+ char *workstations = NULL;
+ uint32 username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
+ uint16 acct_ctrl, logon_divs;
+ uint16 bad_password_count, logon_count;
+ uint8 *hours = NULL;
+ uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
+ uint32 len = 0;
+ uint32 lm_pw_len, nt_pw_len, hourslen;
+ BOOL ret = True;
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
return False;
}
- /* handle a Samba upgrade */
- tdb_lock_bystring(pdb_tdb, vstring, 0);
+/* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
+
+ /* unpack the buffer into variables */
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
+ &logon_time, /* d */
+ &logoff_time, /* d */
+ &kickoff_time, /* d */
+ &pass_last_set_time, /* d */
+ &pass_can_change_time, /* d */
+ &pass_must_change_time, /* d */
+ &username_len, &username, /* B */
+ &domain_len, &domain, /* B */
+ &nt_username_len, &nt_username, /* B */
+ &fullname_len, &fullname, /* B */
+ &homedir_len, &homedir, /* B */
+ &dir_drive_len, &dir_drive, /* B */
+ &logon_script_len, &logon_script, /* B */
+ &profile_path_len, &profile_path, /* B */
+ &acct_desc_len, &acct_desc, /* B */
+ &workstations_len, &workstations, /* B */
+ &unknown_str_len, &unknown_str, /* B */
+ &munged_dial_len, &munged_dial, /* B */
+ &user_rid, /* d */
+ &group_rid, /* d */
+ &lm_pw_len, &lm_pw_ptr, /* B */
+ &nt_pw_len, &nt_pw_ptr, /* B */
+ &acct_ctrl, /* w */
+ &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
+ &logon_divs, /* w */
+ &hours_len, /* d */
+ &hourslen, &hours, /* B */
+ &bad_password_count, /* w */
+ &logon_count, /* w */
+ &unknown_6); /* d */
+
+ if (len == (uint32) -1) {
+ ret = False;
+ goto done;
+ }
+
+ pdb_set_logon_time(sampass, logon_time, PDB_SET);
+ pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
+ pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
+
+ pdb_set_username(sampass, username, PDB_SET);
+ pdb_set_domain(sampass, domain, PDB_SET);
+ pdb_set_nt_username(sampass, nt_username, PDB_SET);
+ pdb_set_fullname(sampass, fullname, PDB_SET);
+
+ if (homedir) {
+ pdb_set_homedir(sampass, homedir, PDB_SET);
+ }
+ else {
+ pdb_set_homedir(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_home()),
+ PDB_DEFAULT);
+ }
+
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
+ else {
+ pdb_set_dir_drive(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_drive()),
+ PDB_DEFAULT);
+ }
+
+ if (logon_script)
+ pdb_set_logon_script(sampass, logon_script, PDB_SET);
+ else {
+ pdb_set_logon_script(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_script()),
+ PDB_DEFAULT);
+ }
+
+ if (profile_path) {
+ pdb_set_profile_path(sampass, profile_path, PDB_SET);
+ } else {
+ pdb_set_profile_path(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_path()),
+ PDB_DEFAULT);
+ }
+
+ pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
+ pdb_set_workstations(sampass, workstations, PDB_SET);
+ pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+
+ if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
+
+ if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
+
+ pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
+ pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
+ pdb_set_hours_len(sampass, hours_len, PDB_SET);
+ pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
+ pdb_set_logon_count(sampass, logon_count, PDB_SET);
+ pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
+ pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
+ pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
+ pdb_set_hours(sampass, hours, PDB_SET);
+
+done:
+
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(nt_username);
+ SAFE_FREE(fullname);
+ SAFE_FREE(homedir);
+ SAFE_FREE(dir_drive);
+ SAFE_FREE(logon_script);
+ SAFE_FREE(profile_path);
+ SAFE_FREE(acct_desc);
+ SAFE_FREE(workstations);
+ SAFE_FREE(munged_dial);
+ SAFE_FREE(unknown_str);
+ SAFE_FREE(lm_pw_ptr);
+ SAFE_FREE(nt_pw_ptr);
+ SAFE_FREE(hours);
+
+ return ret;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buflen)
+{
+
+ /* times are stored as 32bit integer
+ take care on system with 64bit wide time_t
+ --SSS */
+ uint32 logon_time,
+ logoff_time,
+ kickoff_time,
+ bad_password_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time;
+ char *username = NULL;
+ char *domain = NULL;
+ char *nt_username = NULL;
+ char *dir_drive = NULL;
+ char *unknown_str = NULL;
+ char *munged_dial = NULL;
+ char *fullname = NULL;
+ char *homedir = NULL;
+ char *logon_script = NULL;
+ char *profile_path = NULL;
+ char *acct_desc = NULL;
+ char *workstations = NULL;
+ uint32 username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
+ uint16 acct_ctrl, logon_divs;
+ uint16 bad_password_count, logon_count;
+ uint8 *hours = NULL;
+ uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
+ uint32 len = 0;
+ uint32 lm_pw_len, nt_pw_len, hourslen;
+ BOOL ret = True;
- if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
- DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n"));
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
return False;
}
+/* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
+
+ /* unpack the buffer into variables */
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
+ &logon_time, /* d */
+ &logoff_time, /* d */
+ &kickoff_time, /* d */
+ /* Change from V0 is addition of bad_password_time field. */
+ &bad_password_time, /* d */
+ &pass_last_set_time, /* d */
+ &pass_can_change_time, /* d */
+ &pass_must_change_time, /* d */
+ &username_len, &username, /* B */
+ &domain_len, &domain, /* B */
+ &nt_username_len, &nt_username, /* B */
+ &fullname_len, &fullname, /* B */
+ &homedir_len, &homedir, /* B */
+ &dir_drive_len, &dir_drive, /* B */
+ &logon_script_len, &logon_script, /* B */
+ &profile_path_len, &profile_path, /* B */
+ &acct_desc_len, &acct_desc, /* B */
+ &workstations_len, &workstations, /* B */
+ &unknown_str_len, &unknown_str, /* B */
+ &munged_dial_len, &munged_dial, /* B */
+ &user_rid, /* d */
+ &group_rid, /* d */
+ &lm_pw_len, &lm_pw_ptr, /* B */
+ &nt_pw_len, &nt_pw_ptr, /* B */
+ &acct_ctrl, /* w */
+ &remove_me, /* d */
+ &logon_divs, /* w */
+ &hours_len, /* d */
+ &hourslen, &hours, /* B */
+ &bad_password_count, /* w */
+ &logon_count, /* w */
+ &unknown_6); /* d */
+
+ if (len == (uint32) -1) {
+ ret = False;
+ goto done;
+ }
+
+ pdb_set_logon_time(sampass, logon_time, PDB_SET);
+ pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
+ pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
+
+ /* Change from V0 is addition of bad_password_time field. */
+ pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
+
+ pdb_set_username(sampass, username, PDB_SET);
+ pdb_set_domain(sampass, domain, PDB_SET);
+ pdb_set_nt_username(sampass, nt_username, PDB_SET);
+ pdb_set_fullname(sampass, fullname, PDB_SET);
+
+ if (homedir) {
+ pdb_set_homedir(sampass, homedir, PDB_SET);
+ }
+ else {
+ pdb_set_homedir(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_home()),
+ PDB_DEFAULT);
+ }
+
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
+ else {
+ pdb_set_dir_drive(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_drive()),
+ PDB_DEFAULT);
+ }
+
+ if (logon_script)
+ pdb_set_logon_script(sampass, logon_script, PDB_SET);
+ else {
+ pdb_set_logon_script(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_script()),
+ PDB_DEFAULT);
+ }
+
+ if (profile_path) {
+ pdb_set_profile_path(sampass, profile_path, PDB_SET);
+ } else {
+ pdb_set_profile_path(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_path()),
+ PDB_DEFAULT);
+ }
+
+ pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
+ pdb_set_workstations(sampass, workstations, PDB_SET);
+ pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+
+ if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
+
+ if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
+
+ pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
+
+ pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
+ pdb_set_hours_len(sampass, hours_len, PDB_SET);
+ pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
+ pdb_set_logon_count(sampass, logon_count, PDB_SET);
+ pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
+ pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
+ pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
+ pdb_set_hours(sampass, hours, PDB_SET);
+
+done:
+
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(nt_username);
+ SAFE_FREE(fullname);
+ SAFE_FREE(homedir);
+ SAFE_FREE(dir_drive);
+ SAFE_FREE(logon_script);
+ SAFE_FREE(profile_path);
+ SAFE_FREE(acct_desc);
+ SAFE_FREE(workstations);
+ SAFE_FREE(munged_dial);
+ SAFE_FREE(unknown_str);
+ SAFE_FREE(lm_pw_ptr);
+ SAFE_FREE(nt_pw_ptr);
+ SAFE_FREE(hours);
+
+ return ret;
+}
+
+BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
+{
+
+ /* times are stored as 32bit integer
+ take care on system with 64bit wide time_t
+ --SSS */
+ uint32 logon_time,
+ logoff_time,
+ kickoff_time,
+ bad_password_time,
+ pass_last_set_time,
+ pass_can_change_time,
+ pass_must_change_time;
+ char *username = NULL;
+ char *domain = NULL;
+ char *nt_username = NULL;
+ char *dir_drive = NULL;
+ char *unknown_str = NULL;
+ char *munged_dial = NULL;
+ char *fullname = NULL;
+ char *homedir = NULL;
+ char *logon_script = NULL;
+ char *profile_path = NULL;
+ char *acct_desc = NULL;
+ char *workstations = NULL;
+ uint32 username_len, domain_len, nt_username_len,
+ dir_drive_len, unknown_str_len, munged_dial_len,
+ fullname_len, homedir_len, logon_script_len,
+ profile_path_len, acct_desc_len, workstations_len;
+
+ uint32 user_rid, group_rid, hours_len, unknown_6;
+ uint16 acct_ctrl, logon_divs;
+ uint16 bad_password_count, logon_count;
+ uint8 *hours = NULL;
+ uint8 *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
+ uint32 len = 0;
+ uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
+ uint32 pwHistLen = 0;
+ BOOL ret = True;
+ fstring tmpstring;
+ BOOL expand_explicit = lp_passdb_expand_explicit();
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
+ return False;
+ }
+
+/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
+
+ /* unpack the buffer into variables */
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
+ &logon_time, /* d */
+ &logoff_time, /* d */
+ &kickoff_time, /* d */
+ &bad_password_time, /* d */
+ &pass_last_set_time, /* d */
+ &pass_can_change_time, /* d */
+ &pass_must_change_time, /* d */
+ &username_len, &username, /* B */
+ &domain_len, &domain, /* B */
+ &nt_username_len, &nt_username, /* B */
+ &fullname_len, &fullname, /* B */
+ &homedir_len, &homedir, /* B */
+ &dir_drive_len, &dir_drive, /* B */
+ &logon_script_len, &logon_script, /* B */
+ &profile_path_len, &profile_path, /* B */
+ &acct_desc_len, &acct_desc, /* B */
+ &workstations_len, &workstations, /* B */
+ &unknown_str_len, &unknown_str, /* B */
+ &munged_dial_len, &munged_dial, /* B */
+ &user_rid, /* d */
+ &group_rid, /* d */
+ &lm_pw_len, &lm_pw_ptr, /* B */
+ &nt_pw_len, &nt_pw_ptr, /* B */
+ /* Change from V1 is addition of password history field. */
+ &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
+ &acct_ctrl, /* w */
+ /* Also "remove_me" field was removed. */
+ &logon_divs, /* w */
+ &hours_len, /* d */
+ &hourslen, &hours, /* B */
+ &bad_password_count, /* w */
+ &logon_count, /* w */
+ &unknown_6); /* d */
+
+ if (len == (uint32) -1) {
+ ret = False;
+ goto done;
+ }
+
+ pdb_set_logon_time(sampass, logon_time, PDB_SET);
+ pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
+ pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
+ pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
+
+ pdb_set_username(sampass, username, PDB_SET);
+ pdb_set_domain(sampass, domain, PDB_SET);
+ pdb_set_nt_username(sampass, nt_username, PDB_SET);
+ pdb_set_fullname(sampass, fullname, PDB_SET);
+
+ if (homedir) {
+ fstrcpy( tmpstring, homedir );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
+ pdb_set_homedir(sampass, tmpstring, PDB_SET);
+ }
+ else {
+ pdb_set_homedir(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_home()),
+ PDB_DEFAULT);
+ }
+
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
+ else
+ pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
+
+ if (logon_script) {
+ fstrcpy( tmpstring, logon_script );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
+ pdb_set_logon_script(sampass, tmpstring, PDB_SET);
+ }
+ else {
+ pdb_set_logon_script(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_script()),
+ PDB_DEFAULT);
+ }
+
+ if (profile_path) {
+ fstrcpy( tmpstring, profile_path );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
+ pdb_set_profile_path(sampass, tmpstring, PDB_SET);
+ }
+ else {
+ pdb_set_profile_path(sampass,
+ talloc_sub_basic(sampass, username, lp_logon_path()),
+ PDB_DEFAULT);
+ }
+
+ pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
+ pdb_set_workstations(sampass, workstations, PDB_SET);
+ pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+
+ if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
+
+ if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
+
+ /* Change from V1 is addition of password history field. */
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ if (pwHistLen) {
+ uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
+ if (!pw_hist) {
+ ret = False;
+ goto done;
+ }
+ memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
+ if (nt_pw_hist_ptr && nt_pw_hist_len) {
+ int i;
+ SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
+ nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
+ for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
+ memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
+ &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
+ PW_HISTORY_ENTRY_LEN);
+ }
+ }
+ if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
+ SAFE_FREE(pw_hist);
+ ret = False;
+ goto done;
+ }
+ SAFE_FREE(pw_hist);
+ } else {
+ pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
+ }
+
+ pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
+ pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
+ pdb_set_hours_len(sampass, hours_len, PDB_SET);
+ pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
+ pdb_set_logon_count(sampass, logon_count, PDB_SET);
+ pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
+ pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
+ pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
+ pdb_set_hours(sampass, hours, PDB_SET);
+
+done:
+
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(nt_username);
+ SAFE_FREE(fullname);
+ SAFE_FREE(homedir);
+ SAFE_FREE(dir_drive);
+ SAFE_FREE(logon_script);
+ SAFE_FREE(profile_path);
+ SAFE_FREE(acct_desc);
+ SAFE_FREE(workstations);
+ SAFE_FREE(munged_dial);
+ SAFE_FREE(unknown_str);
+ SAFE_FREE(lm_pw_ptr);
+ SAFE_FREE(nt_pw_ptr);
+ SAFE_FREE(nt_pw_hist_ptr);
+ SAFE_FREE(hours);
+
+ return ret;
+}
+
+
+/**********************************************************************
+ Intialize a struct samu struct from a BYTE buffer of size len
+ *********************************************************************/
+
+static BOOL init_sam_from_buffer(struct samu *sampass, uint8 *buf, uint32 buflen)
+{
+ return init_sam_from_buffer_v3(sampass, buf, buflen);
+}
+
+/**********************************************************************
+ Intialize a BYTE buffer from a struct samu struct
+ *********************************************************************/
+
+static uint32 init_buffer_from_sam (uint8 **buf, struct samu *sampass, BOOL size_only)
+{
+ return init_buffer_from_sam_v3(buf, sampass, size_only);
+}
+
+/**********************************************************************
+ Intialize a BYTE buffer from a struct samu struct
+ *********************************************************************/
+
+static BOOL tdbsam_convert(int32 from)
+{
+ const char *vstring = TDBSAM_VERSION_STRING;
+ const char *prefix = USERPREFIX;
+ TDB_DATA data, key, old_key;
+ uint8 *buf = NULL;
+ BOOL ret;
+
+ /* handle a Samba upgrade */
+ tdb_lock_bystring(tdbsam, vstring);
+
/* Enumerate all records and convert them */
- key = tdb_firstkey(pdb_tdb);
+ key = tdb_firstkey(tdbsam);
while (key.dptr) {
@@ -99,26 +705,26 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) {
old_key = key;
/* increment to next in line */
- key = tdb_nextkey(pdb_tdb, key);
+ key = tdb_nextkey(tdbsam, key);
SAFE_FREE(old_key.dptr);
}
if (key.dptr) {
-
+ struct samu *user = NULL;
+
/* read from tdbsam */
- data = tdb_fetch(pdb_tdb, key);
+ data = tdb_fetch(tdbsam, key);
if (!data.dptr) {
DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr));
return False;
}
- if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) {
- DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n"));
- SAFE_FREE(data.dptr);
+ /* unpack the buffer from the former format */
+ if ( !(user = samu_new( NULL )) ) {
+ DEBUG(0,("tdbsam_convert: samu_new() failed!\n"));
+ SAFE_FREE( data.dptr );
return False;
}
-
- /* unpack the buffer from the former format */
DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from));
switch (from) {
case 0:
@@ -130,13 +736,17 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
case 2:
ret = init_sam_from_buffer_v2(user, (uint8 *)data.dptr, data.dsize);
break;
+ case 3:
+ ret = init_sam_from_buffer_v3(user, (uint8 *)data.dptr, data.dsize);
+ break;
default:
/* unknown tdbsam version */
ret = False;
}
if (!ret) {
- DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
+ DEBUG(0,("tdbsam_convert: Bad struct samu entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
SAFE_FREE(data.dptr);
+ TALLOC_FREE(user );
return False;
}
@@ -144,17 +754,20 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
SAFE_FREE(data.dptr);
/* pack from the buffer into the new format */
+
DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
- if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) {
- DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n"));
- SAFE_FREE(data.dptr);
+ data.dsize = init_buffer_from_sam (&buf, user, False);
+ TALLOC_FREE(user );
+
+ if ( data.dsize == -1 ) {
+ DEBUG(0,("tdbsam_convert: cannot pack the struct samu into the new format\n"));
return False;
}
data.dptr = (char *)buf;
/* Store the buffer inside the TDBSAM */
- if (tdb_store(pdb_tdb, key, data, TDB_MODIFY) != TDB_SUCCESS) {
- DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key.dptr));
+ if (tdb_store(tdbsam, key, data, TDB_MODIFY) != TDB_SUCCESS) {
+ DEBUG(0,("tdbsam_convert: cannot store the struct samu (key:%s) in new format\n",key.dptr));
SAFE_FREE(data.dptr);
return False;
}
@@ -163,99 +776,106 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
/* increment to next in line */
old_key = key;
- key = tdb_nextkey(pdb_tdb, key);
+ key = tdb_nextkey(tdbsam, key);
SAFE_FREE(old_key.dptr);
}
}
- pdb_free_sam(&user);
/* upgrade finished */
- tdb_store_int32(pdb_tdb, vstring, TDBSAM_VERSION);
- tdb_unlock_bystring(pdb_tdb, vstring);
+ tdb_store_int32(tdbsam, vstring, TDBSAM_VERSION);
+ tdb_unlock_bystring(tdbsam, vstring);
return(True);
}
-/**
- * Open the TDB passwd database, check version and convert it if needed.
- * @param name filename of the tdbsam file.
- * @param open_flags file access mode.
- * @return a TDB_CONTEXT handle on the tdbsam file.
- **/
+/*********************************************************************
+ Open the tdbsam file based on the absolute path specified.
+ Uses a reference count to allow multiple open calls.
+*********************************************************************/
-static TDB_CONTEXT * tdbsam_tdbopen (const char *name, int open_flags)
+static BOOL tdbsam_open( const char *name )
{
- TDB_CONTEXT *pdb_tdb;
- tdbsamver_t version;
+ int32 version;
- /* Try to open tdb passwd */
- if (!(pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT,
- open_flags, 0600))) {
- DEBUG(0, ("Unable to open/create TDB passwd\n"));
- return NULL;
+ /* check if we are already open */
+
+ if ( tdbsam ) {
+ ref_count++;
+ DEBUG(8,("tdbsam_open: Incrementing open reference count. Ref count is now %d\n",
+ ref_count));
+ return True;
+ }
+
+ SMB_ASSERT( ref_count == 0 );
+
+ /* Try to open tdb passwd. Create a new one if necessary */
+
+ if (!(tdbsam = tdb_open_log(name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600))) {
+ DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd [%s]\n", name));
+ return False;
}
+ /* set the initial reference count - must be done before tdbsam_convert
+ as that calls tdbsam_open()/tdbsam_close(). */
+
+ ref_count = 1;
+
/* Check the version */
- version = (tdbsamver_t) tdb_fetch_int32(pdb_tdb,
- TDBSAM_VERSION_STRING);
- if (version == -1)
+ version = tdb_fetch_int32( tdbsam, TDBSAM_VERSION_STRING );
+
+ if (version == -1) {
version = 0; /* Version not found, assume version 0 */
+ }
/* Compare the version */
if (version > TDBSAM_VERSION) {
/* Version more recent than the latest known */
- DEBUG(0, ("TDBSAM version unknown: %d\n", version));
- tdb_close(pdb_tdb);
- pdb_tdb = NULL;
+ DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
+ tdb_close( tdbsam );
+ ref_count = 0;
+ return False;
}
- else if (version < TDBSAM_VERSION) {
- /* Older version, must be converted */
- DEBUG(1, ("TDBSAM version too old (%d), trying to convert it.\n", version));
-
- /* Reopen the pdb file with read-write access if needed */
- if (!(open_flags & O_RDWR)) {
- DEBUG(10, ("tdbsam_tdbopen: TDB file opened with read only access, reopen it with read-write access.\n"));
- tdb_close(pdb_tdb);
- pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, (open_flags & 07777770) | O_RDWR, 0600);
- }
+
+
+ if ( version < TDBSAM_VERSION ) {
+ DEBUG(1, ("tdbsam_open: Converting version %d database to version %d.\n",
+ version, TDBSAM_VERSION));
- /* Convert */
- if (!tdbsam_convert(pdb_tdb, version)){
- DEBUG(0, ("tdbsam_tdbopen: Error when trying to convert tdbsam: %s\n",name));
- tdb_close(pdb_tdb);
- pdb_tdb = NULL;
- } else {
- DEBUG(1, ("TDBSAM converted successfully.\n"));
- }
-
- /* Reopen the pdb file as it must be */
- if (!(open_flags & O_RDWR)) {
- tdb_close(pdb_tdb);
- pdb_tdb = tdb_open_log(name, 0, TDB_DEFAULT, open_flags, 0600);
+ if ( !tdbsam_convert(version) ) {
+ DEBUG(0, ("tdbsam_open: Error when trying to convert tdbsam [%s]\n",name));
+ tdb_close(tdbsam);
+ ref_count = 0;
+ return False;
}
+
+ DEBUG(3, ("TDBSAM converted successfully.\n"));
}
- return pdb_tdb;
+ DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));
+
+ return True;
}
-/*****************************************************************************
- Utility functions to close the tdb sam database
- ****************************************************************************/
+/****************************************************************************
+ wrapper atound tdb_close() to handle the reference count
+****************************************************************************/
-static void tdbsam_tdbclose ( struct tdbsam_privates *state )
+void tdbsam_close( void )
{
- if ( !state )
- return;
-
- if ( state->passwd_tdb ) {
- tdb_close( state->passwd_tdb );
- state->passwd_tdb = NULL;
+ ref_count--;
+
+ DEBUG(8,("tdbsam_close: Reference count is now %d.\n", ref_count));
+
+ SMB_ASSERT(ref_count >= 0 );
+
+ if ( ref_count == 0 ) {
+ tdb_close( tdbsam );
+ tdbsam = NULL;
}
return;
-
}
/****************************************************************************
@@ -295,17 +915,16 @@ static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data,
Save a list of user keys for iteration.
****************************************************************/
-static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
+static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint32 acb_mask)
{
- uint32 flags = update ? (O_RDWR|O_CREAT) : O_RDONLY;
-
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
-
- if ( !(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, flags )) )
- return NT_STATUS_UNSUCCESSFUL;
+ if ( !tdbsam_open( tdbsam_filename ) ) {
+ DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ tdb_traverse( tdbsam, tdbsam_traverse_setpwent, NULL );
+ pwent_initialized = True;
- tdb_traverse( tdb_state->passwd_tdb, tdbsam_traverse_setpwent, NULL );
-
return NT_STATUS_OK;
}
@@ -316,10 +935,14 @@ static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update,
static void tdbsam_endsampwent(struct pdb_methods *my_methods)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
struct pwent_list *ptr, *ptr_next;
- tdbsam_tdbclose( tdb_state );
+ /* close the tdb only if we have a valid pwent state */
+
+ if ( pwent_initialized ) {
+ DEBUG(7, ("endtdbpwent: closed sam database.\n"));
+ tdbsam_close();
+ }
/* clear out any remaining entries in the list */
@@ -328,59 +951,51 @@ static void tdbsam_endsampwent(struct pdb_methods *my_methods)
DLIST_REMOVE( tdbsam_pwent_list, ptr );
SAFE_FREE( ptr->key.dptr);
SAFE_FREE( ptr );
- }
+ }
- DEBUG(7, ("endtdbpwent: closed sam database.\n"));
+ pwent_initialized = False;
}
/*****************************************************************
- Get one SAM_ACCOUNT from the TDB (next in line)
+ Get one struct samu from the TDB (next in line)
*****************************************************************/
-static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, struct samu *user)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_DATA data;
struct pwent_list *pkey;
if ( !user ) {
- DEBUG(0,("tdbsam_getsampwent: SAM_ACCOUNT is NULL.\n"));
+ DEBUG(0,("tdbsam_getsampwent: struct samu is NULL.\n"));
return nt_status;
}
if ( !tdbsam_pwent_list ) {
DEBUG(4,("tdbsam_getsampwent: end of list\n"));
- tdbsam_tdbclose( tdb_state );
return nt_status;
}
- if ( !tdb_state->passwd_tdb ) {
- if ( !(tdb_state->passwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY)) )
- return nt_status;
- }
-
/* pull the next entry */
pkey = tdbsam_pwent_list;
DLIST_REMOVE( tdbsam_pwent_list, pkey );
- data = tdb_fetch(tdb_state->passwd_tdb, pkey->key);
+ data = tdb_fetch(tdbsam, pkey->key);
SAFE_FREE( pkey->key.dptr);
SAFE_FREE( pkey);
- if (!data.dptr) {
+ if ( !data.dptr ) {
DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
return nt_status;
}
- if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
- DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
+ if ( !init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize) ) {
+ DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
}
SAFE_FREE( data.dptr );
-
return NT_STATUS_OK;
}
@@ -389,18 +1004,15 @@ static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *
Lookup a name in the SAM TDB
******************************************************************/
-static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
+static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, struct samu *user, const char *sname)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
fstring name;
if ( !user ) {
- DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
- return nt_status;
+ DEBUG(0,("pdb_getsampwnam: struct samu is NULL.\n"));
+ return NT_STATUS_NO_MEMORY;
}
/* Data is stored in all lower-case */
@@ -412,52 +1024,37 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
- /* open the accounts TDB */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) {
-
- if (errno == ENOENT) {
- /*
- * TDB file doesn't exist, so try to create new one. This is useful to avoid
- * confusing error msg when adding user account first time
- */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_CREAT ))) {
- DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) did not exist. File successfully created.\n",
- tdb_state->tdbsam_location));
- tdb_close(pwd_tdb);
- } else {
- DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) does not exist. Couldn't create new one. Error was: %s\n",
- tdb_state->tdbsam_location, strerror(errno)));
- }
-
- /* requested user isn't there anyway */
- nt_status = NT_STATUS_NO_SUCH_USER;
- return nt_status;
- }
- DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
- return nt_status;
+ /* open the database */
+
+ if ( !tdbsam_open( tdbsam_filename ) ) {
+ DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
+ return NT_STATUS_ACCESS_DENIED;
}
-
+
/* get the record */
- data = tdb_fetch(pwd_tdb, key);
+
+ data = tdb_fetch(tdbsam, key);
if (!data.dptr) {
DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
DEBUGADD(5, (" Key: %s\n", keystr));
- tdb_close(pwd_tdb);
- return nt_status;
+ tdbsam_close();
+ return NT_STATUS_NO_SUCH_USER;
}
/* unpack the buffer */
+
if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
- DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
+ DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
- tdb_close(pwd_tdb);
- return nt_status;
+ tdbsam_close();
+ return NT_STATUS_NO_MEMORY;
}
+
+ /* success */
+
SAFE_FREE(data.dptr);
-
- /* no further use for database, close it now */
- tdb_close(pwd_tdb);
+ tdbsam_close();
return NT_STATUS_OK;
}
@@ -466,60 +1063,65 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT
Search by rid
**************************************************************************/
-static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
+static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, struct samu *user, uint32 rid)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
TDB_DATA data, key;
fstring keystr;
fstring name;
-
- if (user==NULL) {
- DEBUG(0,("pdb_getsampwrid: SAM_ACCOUNT is NULL.\n"));
+
+ if ( !user ) {
+ DEBUG(0,("pdb_getsampwrid: struct samu is NULL.\n"));
return nt_status;
}
-
+
/* set search key */
+
slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
- /* open the accounts TDB */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDONLY))) {
- DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
- return nt_status;
+ /* open the database */
+
+ if ( !tdbsam_open( tdbsam_filename ) ) {
+ DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
+ return NT_STATUS_ACCESS_DENIED;
}
/* get the record */
- data = tdb_fetch (pwd_tdb, key);
+
+ data = tdb_fetch (tdbsam, key);
if (!data.dptr) {
DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close (pwd_tdb);
- return nt_status;
+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
-
fstrcpy(name, data.dptr);
SAFE_FREE(data.dptr);
- tdb_close (pwd_tdb);
+ nt_status = tdbsam_getsampwnam (my_methods, user, name);
+
+ done:
+ /* cleanup */
- return tdbsam_getsampwnam (my_methods, user, name);
+ tdbsam_close();
+
+ return nt_status;
}
-static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
{
uint32 rid;
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
+
+ if ( !sid_peek_check_rid(get_global_sam_sid(), sid, &rid) )
return NT_STATUS_UNSUCCESSFUL;
+
return tdbsam_getsampwrid(my_methods, user, rid);
}
-static BOOL tdb_delete_samacct_only(TDB_CONTEXT *pwd_tdb,
- struct pdb_methods *my_methods,
- SAM_ACCOUNT *sam_pass)
+static BOOL tdb_delete_samacct_only( struct samu *sam_pass )
{
TDB_DATA key;
fstring keystr;
@@ -529,44 +1131,47 @@ static BOOL tdb_delete_samacct_only(TDB_CONTEXT *pwd_tdb,
strlower_m(name);
/* set the search key */
+
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* it's outaa here! 8^) */
- if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
+
+ if (tdb_delete(tdbsam, key) != TDB_SUCCESS) {
DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close(pwd_tdb);
+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
return False;
}
+
return True;
}
/***************************************************************************
- Delete a SAM_ACCOUNT
+ Delete a struct samu records for the username and RID key
****************************************************************************/
-static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass)
+static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, struct samu *sam_pass)
{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
TDB_DATA key;
fstring keystr;
uint32 rid;
fstring name;
+ /* open the database */
+
+ if ( !tdbsam_open( tdbsam_filename ) ) {
+ DEBUG(0,("tdbsam_delete_sam_account: failed to open %s!\n",
+ tdbsam_filename));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
fstrcpy(name, pdb_get_username(sam_pass));
strlower_m(name);
- /* open the TDB */
- if (!(pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR))) {
- DEBUG(0, ("Unable to open TDB passwd!"));
- return nt_status;
- }
-
/* set the search key */
+
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
@@ -574,40 +1179,43 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC
rid = pdb_get_user_rid(sam_pass);
/* it's outaa here! 8^) */
- if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
- DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close(pwd_tdb);
- return nt_status;
- }
- /* delete also the RID key */
+ if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
+ DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
/* set the search key */
+
slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* it's outaa here! 8^) */
- if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
+
+ if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
- DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close(pwd_tdb);
- return nt_status;
+ DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
+
+ nt_status = NT_STATUS_OK;
- tdb_close(pwd_tdb);
+ done:
+ tdbsam_close();
- return NT_STATUS_OK;
+ return nt_status;
}
/***************************************************************************
Update the TDB SAM account record only
+ Assumes that the tdbsam is already open
****************************************************************************/
-static BOOL tdb_update_samacct_only(TDB_CONTEXT *pwd_tdb,
- struct pdb_methods *my_methods,
- SAM_ACCOUNT* newpwd, int flag)
+static BOOL tdb_update_samacct_only( struct samu* newpwd, int flag )
{
TDB_DATA key, data;
uint8 *buf = NULL;
@@ -615,9 +1223,10 @@ static BOOL tdb_update_samacct_only(TDB_CONTEXT *pwd_tdb,
fstring name;
BOOL ret = True;
- /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
- if ((data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1) {
- DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
+ /* copy the struct samu struct into a BYTE buffer for storage */
+
+ if ( (data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1 ) {
+ DEBUG(0,("tdb_update_sam: ERROR - Unable to copy struct samu info BYTE buffer!\n"));
ret = False;
goto done;
}
@@ -636,9 +1245,10 @@ static BOOL tdb_update_samacct_only(TDB_CONTEXT *pwd_tdb,
key.dsize = strlen(keystr) + 1;
/* add the account */
- if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
+
+ if ( tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS ) {
DEBUG(0, ("Unable to modify passwd TDB!"));
- DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(0, (" Error: %s", tdb_errorstr(tdbsam)));
DEBUGADD(0, (" occured while storing the main record (%s)\n",
keystr));
ret = False;
@@ -649,15 +1259,14 @@ done:
/* cleanup */
SAFE_FREE(buf);
- return (ret);
+ return ret;
}
/***************************************************************************
Update the TDB SAM RID record only
+ Assumes that the tdbsam is already open
****************************************************************************/
-static BOOL tdb_update_ridrec_only(TDB_CONTEXT *pwd_tdb,
- struct pdb_methods *my_methods,
- SAM_ACCOUNT* newpwd, int flag)
+static BOOL tdb_update_ridrec_only( struct samu* newpwd, int flag )
{
TDB_DATA key, data;
fstring keystr;
@@ -671,15 +1280,14 @@ static BOOL tdb_update_ridrec_only(TDB_CONTEXT *pwd_tdb,
data.dptr = name;
/* setup the RID index key */
- slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX,
- pdb_get_user_rid(newpwd));
+ slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
/* add the reference */
- if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
+ if (tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify TDB passwd !"));
- DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+ DEBUGADD(0, (" Error: %s\n", tdb_errorstr(tdbsam)));
DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
return False;
}
@@ -692,82 +1300,72 @@ static BOOL tdb_update_ridrec_only(TDB_CONTEXT *pwd_tdb,
Update the TDB SAM
****************************************************************************/
-static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag)
+static BOOL tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd, int flag)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb = NULL;
- BOOL ret = True;
uint32 user_rid;
+ BOOL result = True;
/* invalidate the existing TDB iterator if it is open */
- if (tdb_state->passwd_tdb) {
- tdb_close(tdb_state->passwd_tdb);
- tdb_state->passwd_tdb = NULL;
- }
-
- /* open the account TDB passwd*/
-
- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
+ tdbsam_endsampwent( my_methods );
- if (!pwd_tdb) {
- DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n",
- tdb_state->tdbsam_location));
+#if 0
+ if ( !pdb_get_group_rid(newpwd) ) {
+ DEBUG (0,("tdb_update_sam: Failing to store a struct samu for [%s] "
+ "without a primary group RID\n", pdb_get_username(newpwd)));
return False;
}
-
- if (!pdb_get_group_rid(newpwd)) {
- DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",
- pdb_get_username(newpwd)));
- ret = False;
- goto done;
- }
+#endif
if ( !(user_rid = pdb_get_user_rid(newpwd)) ) {
- DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd)));
- ret = False;
- goto done;
+ DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n", pdb_get_username(newpwd)));
+ return False;
}
- if (!tdb_update_samacct_only(pwd_tdb, my_methods, newpwd, flag) ||
- !tdb_update_ridrec_only(pwd_tdb, my_methods, newpwd, flag)) {
- ret = False;
- goto done;
+ /* open the database */
+
+ if ( !tdbsam_open( tdbsam_filename ) ) {
+ DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
+ return False;
+ }
+
+ if ( !tdb_update_samacct_only(newpwd, flag) || !tdb_update_ridrec_only(newpwd, flag)) {
+ result = False;
}
-done:
/* cleanup */
- tdb_close (pwd_tdb);
+
+ tdbsam_close();
- return (ret);
+ return result;
}
/***************************************************************************
- Modifies an existing SAM_ACCOUNT
+ Modifies an existing struct samu
****************************************************************************/
-static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
{
- if (tdb_update_sam(my_methods, newpwd, TDB_MODIFY))
- return NT_STATUS_OK;
- else
+ if ( !tdb_update_sam(my_methods, newpwd, TDB_MODIFY) )
return NT_STATUS_UNSUCCESSFUL;
+
+ return NT_STATUS_OK;
}
/***************************************************************************
- Adds an existing SAM_ACCOUNT
+ Adds an existing struct samu
****************************************************************************/
-static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
{
- if (tdb_update_sam(my_methods, newpwd, TDB_INSERT))
- return NT_STATUS_OK;
- else
+ if ( !tdb_update_sam(my_methods, newpwd, TDB_INSERT) )
return NT_STATUS_UNSUCCESSFUL;
+
+ return NT_STATUS_OK;
}
/***************************************************************************
- Renames a SAM_ACCOUNT
+ Renames a struct samu
- check for the posix user/rename user script
- Add and lock the new user record
- rename the posix user
@@ -776,123 +1374,202 @@ static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCO
- unlock the new user record
***************************************************************************/
static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
- SAM_ACCOUNT *old_acct,
+ struct samu *old_acct,
const char *newname)
{
- struct tdbsam_privates *tdb_state =
- (struct tdbsam_privates *)my_methods->private_data;
- SAM_ACCOUNT *new_acct = NULL;
- pstring rename_script;
- TDB_CONTEXT *pwd_tdb = NULL;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- BOOL interim_account = False;
-
- if (!*(lp_renameuser_script()))
- goto done;
+ struct samu *new_acct = NULL;
+ pstring rename_script;
+ BOOL interim_account = False;
+ int rename_ret;
- if (!pdb_copy_sam_account(old_acct, &new_acct) ||
- !pdb_set_username(new_acct, newname, PDB_CHANGED))
- goto done;
-
- /* invalidate the existing TDB iterator if it is open */
+ /* can't do anything without an external script */
- if (tdb_state->passwd_tdb) {
- tdb_close(tdb_state->passwd_tdb);
- tdb_state->passwd_tdb = NULL;
+ pstrcpy(rename_script, lp_renameuser_script() );
+ if ( ! *rename_script ) {
+ return NT_STATUS_ACCESS_DENIED;
}
- /* open the account TDB passwd */
+ /* invalidate the existing TDB iterator if it is open */
- pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT);
+ tdbsam_endsampwent( my_methods );
+
+ if ( !(new_acct = samu_new( NULL )) ) {
+ return NT_STATUS_NO_MEMORY;
+ }
- if (!pwd_tdb) {
- DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n",
- tdb_state->tdbsam_location));
- goto done;
+ if ( !pdb_copy_sam_account(new_acct, old_acct)
+ || !pdb_set_username(new_acct, newname, PDB_CHANGED))
+ {
+ TALLOC_FREE(new_acct );
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* open the database */
+
+ if ( !tdbsam_open( tdbsam_filename ) ) {
+ DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
+ TALLOC_FREE(new_acct );
+ return NT_STATUS_ACCESS_DENIED;
}
/* add the new account and lock it */
- if (!tdb_update_samacct_only(pwd_tdb, my_methods, new_acct,
- TDB_INSERT))
+
+ if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) {
goto done;
+ }
+
interim_account = True;
- if (tdb_lock_bystring(pwd_tdb, newname, 30) == -1) {
+ if ( tdb_lock_bystring_with_timeout(tdbsam, newname, 30) == -1 ) {
goto done;
}
/* rename the posix user */
- pstrcpy(rename_script, lp_renameuser_script());
-
- if (*rename_script) {
- int rename_ret;
-
- pstring_sub(rename_script, "%unew", newname);
- pstring_sub(rename_script, "%uold",
- pdb_get_username(old_acct));
- rename_ret = smbrun(rename_script, NULL);
+ string_sub2(rename_script, "%unew", newname, sizeof(pstring),
+ True, False, True);
+ string_sub2(rename_script, "%uold", pdb_get_username(old_acct),
+ sizeof(pstring), True, False, True);
+ rename_ret = smbrun(rename_script, NULL);
- DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
+ DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
- if (rename_ret)
- goto done;
- } else {
- goto done;
+ if (rename_ret) {
+ goto done;
}
/* rewrite the rid->username record */
- if (!tdb_update_ridrec_only(pwd_tdb, my_methods, new_acct, TDB_MODIFY))
+
+ if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) {
goto done;
+ }
interim_account = False;
- tdb_unlock_bystring(pwd_tdb, newname);
-
- tdb_delete_samacct_only(pwd_tdb, my_methods, old_acct);
-
- ret = NT_STATUS_OK;
+ tdb_unlock_bystring( tdbsam, newname );
+ tdb_delete_samacct_only( old_acct );
+
+ tdbsam_close();
+
+ TALLOC_FREE(new_acct );
+ return NT_STATUS_OK;
done:
/* cleanup */
if (interim_account) {
- tdb_unlock_bystring(pwd_tdb, newname);
- tdb_delete_samacct_only(pwd_tdb, my_methods, new_acct);
+ tdb_unlock_bystring(tdbsam, newname);
+ tdb_delete_samacct_only(new_acct);
}
- if (pwd_tdb)
- tdb_close (pwd_tdb);
+
+ tdbsam_close();
+
if (new_acct)
- pdb_free_sam(&new_acct);
+ TALLOC_FREE(new_acct);
- return (ret);
+ return NT_STATUS_ACCESS_DENIED;
}
-
-static void free_private_data(void **vp)
+
+static BOOL tdbsam_rid_algorithm(struct pdb_methods *methods)
{
- struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp;
- tdbsam_tdbclose(*tdb_state);
- *tdb_state = NULL;
+ return False;
+}
+
+/*
+ * Historically, winbind was responsible for allocating RIDs, so the next RID
+ * value was stored in winbindd_idmap.tdb. It has been moved to passdb now,
+ * but for compatibility reasons we still keep the the next RID counter in
+ * winbindd_idmap.tdb.
+ */
+
+/*****************************************************************************
+ Initialise idmap database. For now (Dec 2005) this is a copy of the code in
+ sam/idmap_tdb.c. Maybe at a later stage we can remove that capability from
+ winbind completely and store the RID counter in passdb.tdb.
- /* No need to free any further, as it is talloc()ed */
+ Dont' fully initialize with the HWM values, if it's new, we're only
+ interested in the RID counter.
+*****************************************************************************/
+
+static BOOL init_idmap_tdb(TDB_CONTEXT *tdb)
+{
+ int32 version;
+
+ if (tdb_lock_bystring(tdb, "IDMAP_VERSION") != 0) {
+ DEBUG(0, ("Could not lock IDMAP_VERSION\n"));
+ return False;
+ }
+
+ version = tdb_fetch_int32(tdb, "IDMAP_VERSION");
+
+ if (version == -1) {
+ /* No key found, must be a new db */
+ if (tdb_store_int32(tdb, "IDMAP_VERSION",
+ IDMAP_VERSION) != 0) {
+ DEBUG(0, ("Could not store IDMAP_VERSION\n"));
+ tdb_unlock_bystring(tdb, "IDMAP_VERSION");
+ return False;
+ }
+ version = IDMAP_VERSION;
+ }
+
+ if (version != IDMAP_VERSION) {
+ DEBUG(0, ("Expected IDMAP_VERSION=%d, found %d. Please "
+ "start winbind once\n", IDMAP_VERSION, version));
+ tdb_unlock_bystring(tdb, "IDMAP_VERSION");
+ return False;
+ }
+
+ tdb_unlock_bystring(tdb, "IDMAP_VERSION");
+ return True;
}
+static BOOL tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
+{
+ TDB_CONTEXT *tdb;
+ uint32 rid;
+ BOOL ret = False;
+
+ tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
+ TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
+ if (tdb == NULL) {
+ DEBUG(1, ("Could not open idmap: %s\n", strerror(errno)));
+ goto done;
+ }
+ if (!init_idmap_tdb(tdb)) {
+ DEBUG(1, ("Could not init idmap\n"));
+ goto done;
+ }
-/**
- * Init tdbsam backend
- *
- * @param pdb_context initialised passdb context
- * @param pdb_method backend methods structure to be filled with function pointers
- * @param location the backend tdb file location
- *
- * @return nt_status code
- **/
+ rid = BASE_RID; /* Default if not set */
-static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+ if (!tdb_change_uint32_atomic(tdb, "RID_COUNTER", &rid, 1)) {
+ DEBUG(3, ("tdbsam_new_rid: Failed to increase RID_COUNTER\n"));
+ goto done;
+ }
+
+ *prid = rid;
+ ret = True;
+
+ done:
+ if ((tdb != NULL) && (tdb_close(tdb) != 0)) {
+ smb_panic("tdb_close(idmap_tdb) failed\n");
+ }
+
+ return ret;
+}
+
+/*********************************************************************
+ Initialize the tdb sam backend. Setup the dispath table of methods,
+ open the tdb, etc...
+*********************************************************************/
+
+static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *location)
{
NTSTATUS nt_status;
- struct tdbsam_privates *tdb_state;
+ pstring tdbfile;
+ const char *pfile = location;
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
return nt_status;
}
@@ -908,26 +1585,21 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth
(*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
(*pdb_method)->rename_sam_account = tdbsam_rename_sam_account;
- tdb_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct tdbsam_privates);
-
- if (!tdb_state) {
- DEBUG(0, ("talloc() failed for tdbsam private_data!\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ (*pdb_method)->rid_algorithm = tdbsam_rid_algorithm;
+ (*pdb_method)->new_rid = tdbsam_new_rid;
- if (location) {
- tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, location);
- } else {
- pstring tdbfile;
- get_private_directory(tdbfile);
- pstrcat(tdbfile, "/");
- pstrcat(tdbfile, PASSDB_FILE_NAME);
- tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile);
+ /* save the path for later */
+
+ if ( !location ) {
+ pstr_sprintf( tdbfile, "%s/%s", lp_private_dir(), PASSDB_FILE_NAME );
+ pfile = tdbfile;
}
+ pstrcpy( tdbsam_filename, pfile );
- (*pdb_method)->private_data = tdb_state;
-
- (*pdb_method)->free_private_data = free_private_data;
+ /* no private data */
+
+ (*pdb_method)->private_data = NULL;
+ (*pdb_method)->free_private_data = NULL;
return NT_STATUS_OK;
}
diff --git a/source/passdb/pdb_xml.c b/source/passdb/pdb_xml.c
deleted file mode 100644
index d40a5731a43..00000000000
--- a/source/passdb/pdb_xml.c
+++ /dev/null
@@ -1,580 +0,0 @@
-
-/*
- * XML password backend for samba
- * Copyright (C) Jelmer Vernooij 2002
- * Some parts based on the libxml gjobread example by Daniel Veillard
- *
- * 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 2 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, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* FIXME:
- * - Support stdin input by using '-'
- * - Be faster. Don't rewrite the whole file when adding a user, but store it in the memory and save it when exiting. Requires changes to samba source.
- * - Gives the ability to read/write to standard input/output
- * - Do locking!
- * - Better names!
- */
-
-
-#define XML_URL "http://samba.org/samba/DTD/passdb"
-
-#include "includes.h"
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-
-static int xmlsam_debug_level = DBGC_ALL;
-
-#undef DBGC_CLASS
-#define DBGC_CLASS xmlsam_debug_level
-
-
-/* Helper utilities for charset conversion */
-static xmlNodePtr smbXmlNewChild(xmlNodePtr prnt, xmlNsPtr ns, const xmlChar *name, const char *content)
-{
- char *string_utf8;
- xmlNodePtr ret;
-
- if(!content) return xmlNewChild(prnt, ns, name, NULL);
-
-
- if(push_utf8_allocate(&string_utf8,content) == (size_t)-1)
- return NULL;
-
- ret = xmlNewTextChild(prnt, ns, name, string_utf8);
-
- SAFE_FREE(string_utf8);
-
- return ret;
-}
-
-
-static char * iota(int a) {
- static char tmp[10];
-
- snprintf(tmp, 9, "%d", a);
- return tmp;
-}
-
-static BOOL parsePass(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * u)
-{
- pstring temp;
-
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if (strcmp(cur->name, "crypt"))
- DEBUG(0, ("Unknown element %s\n", cur->name));
- else {
- if (!strcmp(xmlGetProp(cur, "type"), "nt")
- &&
- pdb_gethexpwd(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1), temp))
- pdb_set_nt_passwd(u, temp, PDB_SET);
- else if (!strcmp(xmlGetProp(cur, "type"), "lanman")
- &&
- pdb_gethexpwd(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1), temp))
- pdb_set_lanman_passwd(u, temp, PDB_SET);
- else
- DEBUG(0,
- ("Unknown crypt type: %s\n",
- xmlGetProp(cur, "type")));
- }
- cur = cur->next;
- }
- return True;
-}
-
-static BOOL parseUser(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur, SAM_ACCOUNT * u)
-{
- char *tmp;
- DOM_SID sid;
-
- tmp = xmlGetProp(cur, "sid");
- if (tmp){
- string_to_sid(&sid, tmp);
- pdb_set_user_sid(u, &sid, PDB_SET);
- }
- pdb_set_username(u, xmlGetProp(cur, "name"), PDB_SET);
- /* We don't care what the top level element name is */
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- if ((!strcmp(cur->name, "group")) && (cur->ns == ns)) {
- tmp = xmlGetProp(cur, "sid");
- if (tmp){
- string_to_sid(&sid, tmp);
- pdb_set_group_sid(u, &sid, PDB_SET);
- }
- }
-
- else if ((!strcmp(cur->name, "domain")) && (cur->ns == ns))
- pdb_set_domain(u,
- xmlNodeListGetString(doc, cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "fullname") && cur->ns == ns)
- pdb_set_fullname(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "nt_username") && cur->ns == ns)
- pdb_set_nt_username(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_script") && cur->ns == ns)
- pdb_set_logon_script(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "profile_path") && cur->ns == ns)
- pdb_set_profile_path(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_time") && cur->ns == ns)
- pdb_set_logon_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "logoff_time") && cur->ns == ns)
- pdb_set_logoff_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)),
- PDB_SET);
-
- else if (!strcmp(cur->name, "kickoff_time") && cur->ns == ns)
- pdb_set_kickoff_time(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)),
- PDB_SET);
-
- else if (!strcmp(cur->name, "logon_divs") && cur->ns == ns)
- pdb_set_logon_divs(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "hours_len") && cur->ns == ns)
- pdb_set_hours_len(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "bad_password_count") && cur->ns == ns)
- pdb_set_bad_password_count(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "logon_count") && cur->ns == ns)
- pdb_set_logon_count(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_6") && cur->ns == ns)
- pdb_set_unknown_6(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "homedir") && cur->ns == ns)
- pdb_set_homedir(u,
- xmlNodeListGetString(doc, cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "unknown_str") && cur->ns == ns)
- pdb_set_unknown_str(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "dir_drive") && cur->ns == ns)
- pdb_set_dir_drive(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "munged_dial") && cur->ns == ns)
- pdb_set_munged_dial(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "acct_desc") && cur->ns == ns)
- pdb_set_acct_desc(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if (!strcmp(cur->name, "acct_ctrl") && cur->ns == ns)
- pdb_set_acct_ctrl(u,
- atol(xmlNodeListGetString
- (doc, cur->xmlChildrenNode, 1)), PDB_SET);
-
- else if (!strcmp(cur->name, "workstations") && cur->ns == ns)
- pdb_set_workstations(u,
- xmlNodeListGetString(doc,
- cur->xmlChildrenNode,
- 1), PDB_SET);
-
- else if ((!strcmp(cur->name, "password")) && (cur->ns == ns)) {
- tmp = xmlGetProp(cur, "last_set");
- if (tmp)
- pdb_set_pass_last_set_time(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "must_change");
- if (tmp)
- pdb_set_pass_must_change_time(u, atol(tmp), PDB_SET);
- tmp = xmlGetProp(cur, "can_change");
- if (tmp)
- pdb_set_pass_can_change_time(u, atol(tmp), PDB_SET);
- parsePass(doc, ns, cur, u);
- }
-
- else
- DEBUG(0, ("Unknown element %s\n", cur->name));
- cur = cur->next;
- }
-
- return True;
-}
-
-typedef struct pdb_xml {
- char *location;
- char written;
- xmlDocPtr doc;
- xmlNodePtr users;
- xmlNodePtr pwent;
- xmlNsPtr ns;
-} pdb_xml;
-
-static xmlNodePtr parseSambaXMLFile(struct pdb_xml *data)
-{
- xmlNodePtr cur;
-
- data->doc = xmlParseFile(data->location);
- if (data->doc == NULL)
- return NULL;
-
- cur = xmlDocGetRootElement(data->doc);
- if (!cur) {
- DEBUG(0, ("empty document\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- data->ns = xmlSearchNsByHref(data->doc, cur, XML_URL);
- if (!data->ns) {
- DEBUG(0,
- ("document of the wrong type, samba user namespace not found\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- if (strcmp(cur->name, "samba")) {
- DEBUG(0, ("document of the wrong type, root node != samba"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
-
- cur = cur->xmlChildrenNode;
- while (cur && xmlIsBlankNode(cur)) {
- cur = cur->next;
- }
- if (!cur)
- return NULL;
- if ((strcmp(cur->name, "users")) || (cur->ns != data->ns)) {
- DEBUG(0, ("document of the wrong type, was '%s', users expected",
- cur->name));
- DEBUG(0, ("xmlDocDump follows\n"));
- xmlDocDump(stderr, data->doc);
- DEBUG(0, ("xmlDocDump finished\n"));
- xmlFreeDoc(data->doc);
- return NULL;
- }
- data->users = cur;
- cur = cur->xmlChildrenNode;
- return cur;
-}
-
-static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data = (pdb_xml *) methods->private_data;
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data->pwent = parseSambaXMLFile(data);
- if (!data->pwent)
- return NT_STATUS_UNSUCCESSFUL;
-
- return NT_STATUS_OK;
-}
-
-/***************************************************************
- End enumeration of the passwd list.
- ****************************************************************/
-
-static void xmlsam_endsampwent(struct pdb_methods *methods)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return;
- }
-
- data = (pdb_xml *) methods->private_data;
-
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return;
- }
-
- xmlFreeDoc(data->doc);
- data->doc = NULL;
- data->pwent = NULL;
-}
-
-/*****************************************************************
- Get one SAM_ACCOUNT from the list (next in line)
- *****************************************************************/
-
-static NTSTATUS xmlsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT * user)
-{
- pdb_xml *data;
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
- data = (pdb_xml *) methods->private_data;
-
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- while (data->pwent) {
- if ((!strcmp(data->pwent->name, "user")) &&
- (data->pwent->ns == data->ns)) {
-
- parseUser(data->doc, data->ns, data->pwent, user);
- data->pwent = data->pwent->next;
- return NT_STATUS_OK;
- }
- data->pwent = data->pwent->next;
- }
- return NT_STATUS_UNSUCCESSFUL;
-}
-
-/***************************************************************************
- Adds an existing SAM_ACCOUNT
- ****************************************************************************/
-
-static NTSTATUS xmlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT * u)
-{
- pstring temp;
- fstring sid_str;
- xmlNodePtr cur, user, pass, root;
- pdb_xml *data;
-
- DEBUG(10, ("xmlsam_add_sam_account called!\n"));
-
- if (!methods) {
- DEBUG(0, ("Invalid methods\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- data = (pdb_xml *) methods->private_data;
- if (!data) {
- DEBUG(0, ("Invalid pdb_xml_data\n"));
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Create a new document if we can't open the current one */
- if (!parseSambaXMLFile(data)) {
- DEBUG(0, ("Can't load current XML file, creating a new one\n"));
- data->doc = xmlNewDoc(XML_DEFAULT_VERSION);
- root = xmlNewDocNode(data->doc, NULL, "samba", NULL);
- cur = xmlDocSetRootElement(data->doc, root);
- data->ns = xmlNewNs(root, XML_URL, "samba");
- data->users = smbXmlNewChild(root, data->ns, "users", NULL);
- }
-
- user = smbXmlNewChild(data->users, data->ns, "user", NULL);
- xmlNewProp(user, "sid",
- sid_to_string(sid_str, pdb_get_user_sid(u)));
-
- if (pdb_get_username(u) && strcmp(pdb_get_username(u), ""))
- xmlNewProp(user, "name", pdb_get_username(u));
-
- cur = smbXmlNewChild(user, data->ns, "group", NULL);
-
- xmlNewProp(cur, "sid",
- sid_to_string(sid_str, pdb_get_group_sid(u)));
-
- if (pdb_get_init_flags(u, PDB_LOGONTIME) != PDB_DEFAULT)
- smbXmlNewChild(user, data->ns, "logon_time",
- iota(pdb_get_logon_time(u)));
-
- if (pdb_get_init_flags(u, PDB_LOGOFFTIME) != PDB_DEFAULT)
- smbXmlNewChild(user, data->ns, "logoff_time",
- iota(pdb_get_logoff_time(u)));
-
- if (pdb_get_init_flags(u, PDB_KICKOFFTIME) != PDB_DEFAULT)
- smbXmlNewChild(user, data->ns, "kickoff_time",
- iota(pdb_get_kickoff_time(u)));
-
- if (pdb_get_domain(u) && strcmp(pdb_get_domain(u), ""))
- smbXmlNewChild(user, data->ns, "domain", pdb_get_domain(u));
-
- if (pdb_get_nt_username(u) && strcmp(pdb_get_nt_username(u), ""))
- smbXmlNewChild(user, data->ns, "nt_username", pdb_get_nt_username(u));
-
- if (pdb_get_fullname(u) && strcmp(pdb_get_fullname(u), ""))
- smbXmlNewChild(user, data->ns, "fullname", pdb_get_fullname(u));
-
- if (pdb_get_homedir(u) && strcmp(pdb_get_homedir(u), ""))
- smbXmlNewChild(user, data->ns, "homedir", pdb_get_homedir(u));
-
- if (pdb_get_dir_drive(u) && strcmp(pdb_get_dir_drive(u), ""))
- smbXmlNewChild(user, data->ns, "dir_drive", pdb_get_dir_drive(u));
-
- if (pdb_get_logon_script(u) && strcmp(pdb_get_logon_script(u), ""))
- smbXmlNewChild(user, data->ns, "logon_script",
- pdb_get_logon_script(u));
-
- if (pdb_get_profile_path(u) && strcmp(pdb_get_profile_path(u), ""))
- smbXmlNewChild(user, data->ns, "profile_path",
- pdb_get_profile_path(u));
-
- if (pdb_get_acct_desc(u) && strcmp(pdb_get_acct_desc(u), ""))
- smbXmlNewChild(user, data->ns, "acct_desc", pdb_get_acct_desc(u));
-
- if (pdb_get_workstations(u) && strcmp(pdb_get_workstations(u), ""))
- smbXmlNewChild(user, data->ns, "workstations",
- pdb_get_workstations(u));
-
- if (pdb_get_unknown_str(u) && strcmp(pdb_get_unknown_str(u), ""))
- smbXmlNewChild(user, data->ns, "unknown_str", pdb_get_unknown_str(u));
-
- if (pdb_get_munged_dial(u) && strcmp(pdb_get_munged_dial(u), ""))
- smbXmlNewChild(user, data->ns, "munged_dial", pdb_get_munged_dial(u));
-
-
- /* Password stuff */
- pass = smbXmlNewChild(user, data->ns, "password", NULL);
- if (pdb_get_pass_last_set_time(u))
- xmlNewProp(pass, "last_set", iota(pdb_get_pass_last_set_time(u)));
- if (pdb_get_init_flags(u, PDB_CANCHANGETIME) != PDB_DEFAULT)
- xmlNewProp(pass, "can_change",
- iota(pdb_get_pass_can_change_time(u)));
-
- if (pdb_get_init_flags(u, PDB_MUSTCHANGETIME) != PDB_DEFAULT)
- xmlNewProp(pass, "must_change",
- iota(pdb_get_pass_must_change_time(u)));
-
-
- if (pdb_get_lanman_passwd(u)) {
- pdb_sethexpwd(temp, pdb_get_lanman_passwd(u),
- pdb_get_acct_ctrl(u));
- cur = smbXmlNewChild(pass, data->ns, "crypt", temp);
- xmlNewProp(cur, "type", "lanman");
- }
-
- if (pdb_get_nt_passwd(u)) {
- pdb_sethexpwd(temp, pdb_get_nt_passwd(u), pdb_get_acct_ctrl(u));
- cur = smbXmlNewChild(pass, data->ns, "crypt", temp);
- xmlNewProp(cur, "type", "nt");
- }
-
- smbXmlNewChild(user, data->ns, "acct_ctrl", iota(pdb_get_acct_ctrl(u)));
-
- if (pdb_get_logon_divs(u))
- smbXmlNewChild(user, data->ns, "logon_divs",
- iota(pdb_get_logon_divs(u)));
-
- if (pdb_get_hours_len(u))
- smbXmlNewChild(user, data->ns, "hours_len",
- iota(pdb_get_hours_len(u)));
-
- smbXmlNewChild(user, data->ns, "bad_password_count", iota(pdb_get_bad_password_count(u)));
- smbXmlNewChild(user, data->ns, "logon_count", iota(pdb_get_logon_count(u)));
- smbXmlNewChild(user, data->ns, "unknown_6", iota(pdb_get_unknown_6(u)));
- xmlSaveFile(data->location, data->doc);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
- const char *location)
-{
- NTSTATUS nt_status;
- pdb_xml *data;
-
- xmlsam_debug_level = debug_add_class("xmlsam");
- if (xmlsam_debug_level == -1) {
- xmlsam_debug_level = DBGC_ALL;
- DEBUG(0, ("xmlsam: Couldn't register custom debugging class!\n"));
- }
-
- if (!pdb_context) {
- DEBUG(0, ("invalid pdb_methods specified\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!NT_STATUS_IS_OK
- (nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "xmlsam";
-
- (*pdb_method)->setsampwent = xmlsam_setsampwent;
- (*pdb_method)->endsampwent = xmlsam_endsampwent;
- (*pdb_method)->getsampwent = xmlsam_getsampwent;
- (*pdb_method)->add_sam_account = xmlsam_add_sam_account;
- (*pdb_method)->getsampwnam = NULL;
- (*pdb_method)->getsampwsid = NULL;
- (*pdb_method)->update_sam_account = NULL;
- (*pdb_method)->delete_sam_account = NULL;
- (*pdb_method)->getgrsid = NULL;
- (*pdb_method)->getgrgid = NULL;
- (*pdb_method)->getgrnam = NULL;
- (*pdb_method)->add_group_mapping_entry = NULL;
- (*pdb_method)->update_group_mapping_entry = NULL;
- (*pdb_method)->delete_group_mapping_entry = NULL;
- (*pdb_method)->enum_group_mapping = NULL;
-
- data = _talloc(pdb_context->mem_ctx, sizeof(pdb_xml));
- data->location = talloc_strdup(pdb_context->mem_ctx, (location ? location : "passdb.xml"));
- data->pwent = NULL;
- data->written = 0;
- (*pdb_method)->private_data = data;
-
- LIBXML_TEST_VERSION xmlKeepBlanksDefault(0);
-
- return NT_STATUS_OK;
-}
-
-NTSTATUS pdb_xml_init(void)
-{
- return smb_register_passdb(PASSDB_INTERFACE_VERSION, "xml", xmlsam_init);
-}
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 14896a33400..32793dea586 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -177,13 +177,16 @@ BOOL secrets_fetch_domain_guid(const char *domain, struct uuid *guid)
strupper_m(key);
dyn_guid = (struct uuid *)secrets_fetch(key, &size);
- if ((!dyn_guid) && (lp_server_role() == ROLE_DOMAIN_PDC)) {
- smb_uuid_generate_random(&new_guid);
- if (!secrets_store_domain_guid(domain, &new_guid))
- return False;
- dyn_guid = (struct uuid *)secrets_fetch(key, &size);
- if (dyn_guid == NULL)
+ if (!dyn_guid) {
+ if (lp_server_role() == ROLE_DOMAIN_PDC) {
+ smb_uuid_generate_random(&new_guid);
+ if (!secrets_store_domain_guid(domain, &new_guid))
+ return False;
+ dyn_guid = (struct uuid *)secrets_fetch(key, &size);
+ }
+ if (dyn_guid == NULL) {
return False;
+ }
}
if (size != sizeof(struct uuid)) {
@@ -242,7 +245,7 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
return False;
if (dolock)
- return (tdb_lock_bystring(tdb, trust_keystr(domain),0) == 0);
+ return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
else
tdb_unlock_bystring(tdb, trust_keystr(domain));
return True;
@@ -388,10 +391,11 @@ BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
* @return true if succeeded
**/
-BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_dom_name,
- size_t uni_name_len, const char* pwd,
- DOM_SID sid)
-{
+BOOL secrets_store_trusted_domain_password(const char* domain, const char* pwd,
+ const DOM_SID *sid)
+{
+ smb_ucs2_t *uni_dom_name;
+
/* packing structures */
pstring pass_buf;
int pass_len = 0;
@@ -399,13 +403,16 @@ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_d
struct trusted_dom_pass pass;
ZERO_STRUCT(pass);
-
- /* unicode domain name and its length */
- if (!uni_dom_name)
+
+ if (push_ucs2_allocate(&uni_dom_name, domain) < 0) {
+ DEBUG(0, ("Could not convert domain name %s to unicode\n",
+ domain));
return False;
-
+ }
+
strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
- pass.uni_name_len = uni_name_len;
+ pass.uni_name_len = strlen_w(uni_dom_name)+1;
+ SAFE_FREE(uni_dom_name);
/* last change time */
pass.mod_time = time(NULL);
@@ -415,7 +422,7 @@ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_d
fstrcpy(pass.pass, pwd);
/* domain sid */
- sid_copy(&pass.domain_sid, &sid);
+ sid_copy(&pass.domain_sid, sid);
pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass);
@@ -658,138 +665,101 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
/**
* Get trusted domains info from secrets.tdb.
- *
- * The linked list is allocated on the supplied talloc context, caller gets to destroy
- * when done.
- *
- * @param ctx Allocation context
- * @param enum_ctx Starting index, eg. we can start fetching at third
- * or sixth trusted domain entry. Zero is the first index.
- * Value it is set to is the enum context for the next enumeration.
- * @param num_domains Number of domain entries to fetch at one call
- * @param domains Pointer to array of trusted domain structs to be filled up
- *
- * @return nt status code of rpc response
**/
-NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned int max_num_domains,
- int *num_domains, TRUSTDOM ***domains)
+NTSTATUS secrets_trusted_domains(TALLOC_CTX *mem_ctx, uint32 *num_domains,
+ struct trustdom_info ***domains)
{
TDB_LIST_NODE *keys, *k;
- TRUSTDOM *dom = NULL;
char *pattern;
- unsigned int start_idx;
- uint32 idx = 0;
- size_t size = 0, packed_size = 0;
- fstring dom_name;
- char *packed_pass;
- struct trusted_dom_pass *pass = TALLOC_ZERO_P(ctx, struct trusted_dom_pass);
- NTSTATUS status;
if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
- if (!pass) {
- DEBUG(0, ("talloc_zero failed!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
- *num_domains = 0;
- start_idx = *enum_ctx;
-
/* generate searching pattern */
- if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) {
- DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n"));
+ pattern = talloc_asprintf(mem_ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS);
+ if (pattern == NULL) {
+ DEBUG(0, ("secrets_trusted_domains: talloc_asprintf() "
+ "failed!\n"));
return NT_STATUS_NO_MEMORY;
}
- DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n",
- max_num_domains, *enum_ctx));
-
- *domains = TALLOC_ZERO_ARRAY(ctx, TRUSTDOM *, max_num_domains);
+ *domains = NULL;
+ *num_domains = 0;
/* fetching trusted domains' data and collecting them in a list */
keys = tdb_search_keys(tdb, pattern);
- /*
- * if there's no keys returned ie. no trusted domain,
- * return "no more entries" code
- */
- status = NT_STATUS_NO_MORE_ENTRIES;
-
/* searching for keys in secrets db -- way to go ... */
for (k = keys; k; k = k->next) {
+ char *packed_pass;
+ size_t size = 0, packed_size = 0;
+ struct trusted_dom_pass pass;
char *secrets_key;
+ struct trustdom_info *dom_info;
/* important: ensure null-termination of the key string */
- secrets_key = SMB_STRNDUP(k->node_key.dptr, k->node_key.dsize);
+ secrets_key = talloc_strndup(mem_ctx,
+ k->node_key.dptr,
+ k->node_key.dsize);
if (!secrets_key) {
DEBUG(0, ("strndup failed!\n"));
+ tdb_search_list_free(keys);
return NT_STATUS_NO_MEMORY;
}
packed_pass = secrets_fetch(secrets_key, &size);
- packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass);
+ packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size,
+ &pass);
/* packed representation isn't needed anymore */
SAFE_FREE(packed_pass);
if (size != packed_size) {
- DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key));
+ DEBUG(2, ("Secrets record %s is invalid!\n",
+ secrets_key));
continue;
}
-
- pull_ucs2_fstring(dom_name, pass->uni_name);
- DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
- idx, dom_name, sid_string_static(&pass->domain_sid)));
-
- SAFE_FREE(secrets_key);
-
- if (idx >= start_idx && idx < start_idx + max_num_domains) {
- dom = TALLOC_ZERO_P(ctx, TRUSTDOM);
- if (!dom) {
- /* free returned tdb record */
- return NT_STATUS_NO_MEMORY;
- }
-
- /* copy domain sid */
- SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid));
- memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid));
-
- /* copy unicode domain name */
- dom->name = TALLOC_MEMDUP(ctx, pass->uni_name,
- (strlen_w(pass->uni_name) + 1) * sizeof(smb_ucs2_t));
-
- (*domains)[idx - start_idx] = dom;
-
- DEBUG(18, ("Secret record is in required range.\n \
- start_idx = %d, max_num_domains = %d. Added to returned array.\n",
- start_idx, max_num_domains));
- *enum_ctx = idx + 1;
- (*num_domains)++;
-
- /* set proper status code to return */
- if (k->next) {
- /* there are yet some entries to enumerate */
- status = STATUS_MORE_ENTRIES;
- } else {
- /* this is the last entry in the whole enumeration */
- status = NT_STATUS_OK;
- }
- } else {
- DEBUG(18, ("Secret is outside the required range.\n \
- start_idx = %d, max_num_domains = %d. Not added to returned array\n",
- start_idx, max_num_domains));
+ if (pass.domain_sid.num_auths != 4) {
+ DEBUG(0, ("SID %s is not a domain sid, has %d "
+ "auths instead of 4\n",
+ sid_string_static(&pass.domain_sid),
+ pass.domain_sid.num_auths));
+ continue;
}
-
- idx++;
+
+ dom_info = TALLOC_P(mem_ctx, struct trustdom_info);
+ if (dom_info == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ tdb_search_list_free(keys);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (pull_ucs2_talloc(mem_ctx, &dom_info->name,
+ pass.uni_name) < 0) {
+ DEBUG(2, ("pull_ucs2_talloc failed\n"));
+ tdb_search_list_free(keys);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ sid_copy(&dom_info->sid, &pass.domain_sid);
+
+ ADD_TO_ARRAY(mem_ctx, struct trustdom_info *, dom_info,
+ domains, num_domains);
+
+ if (*domains == NULL) {
+ tdb_search_list_free(keys);
+ return NT_STATUS_NO_MEMORY;
+ }
+ talloc_steal(*domains, dom_info);
}
- DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
+ DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n",
+ *num_domains));
/* free the results of searching the keys */
tdb_search_list_free(keys);
- return status;
+ return NT_STATUS_OK;
}
/*******************************************************************************
@@ -804,7 +774,7 @@ BOOL secrets_named_mutex(const char *name, unsigned int timeout)
if (!secrets_init())
return False;
- ret = tdb_lock_bystring(tdb, name, timeout);
+ ret = tdb_lock_bystring_with_timeout(tdb, name, timeout);
if (ret == 0)
DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
@@ -821,35 +791,6 @@ void secrets_named_mutex_release(const char *name)
DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
}
-/*********************************************************
- Check to see if we must talk to the PDC to avoid sam
- sync delays
- ********************************************************/
-
-BOOL must_use_pdc( const char *domain )
-{
- time_t now = time(NULL);
- time_t last_change_time;
- unsigned char passwd[16];
-
- if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) )
- return False;
-
- /*
- * If the time the machine password has changed
- * was less than about 15 minutes then we need to contact
- * the PDC only, as we cannot be sure domain replication
- * has yet taken place. Bug found by Gerald (way to go
- * Gerald !). JRA.
- */
-
- if ( now - last_change_time < SAM_SYNC_WINDOW )
- return True;
-
- return False;
-
-}
-
/*******************************************************************************
Store a complete AFS keyfile into secrets.tdb.
*******************************************************************************/
@@ -959,7 +900,7 @@ static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
if (!tdb_sc) {
DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname));
- talloc_free(fname);
+ TALLOC_FREE(fname);
return NULL;
}
@@ -987,7 +928,7 @@ static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
}
SAFE_FREE(vers.dptr);
- talloc_free(fname);
+ TALLOC_FREE(fname);
return tdb_sc;
}
@@ -997,13 +938,15 @@ static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx)
Note we must be root here.
*******************************************************************************/
-BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinfo *pdc)
+BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx,
+ const char *remote_machine,
+ const struct dcinfo *pdc)
{
TDB_CONTEXT *tdb_sc = NULL;
TDB_DATA value;
BOOL ret;
char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
- pdc->remote_machine);
+ remote_machine);
if (!keystr) {
return False;
}
@@ -1016,7 +959,7 @@ BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinf
8, pdc->seed_chal.data,
8, pdc->clnt_chal.data,
8, pdc->srv_chal.data,
- 8, pdc->sess_key,
+ 16, pdc->sess_key,
16, pdc->mach_pw,
pdc->mach_acct,
pdc->remote_machine,
@@ -1024,7 +967,7 @@ BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinf
value.dptr = TALLOC(mem_ctx, value.dsize);
if (!value.dptr) {
- talloc_free(keystr);
+ TALLOC_FREE(keystr);
return False;
}
@@ -1033,7 +976,7 @@ BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinf
8, pdc->seed_chal.data,
8, pdc->clnt_chal.data,
8, pdc->srv_chal.data,
- 8, pdc->sess_key,
+ 16, pdc->sess_key,
16, pdc->mach_pw,
pdc->mach_acct,
pdc->remote_machine,
@@ -1041,8 +984,8 @@ BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinf
tdb_sc = open_schannel_session_store(mem_ctx);
if (!tdb_sc) {
- talloc_free(keystr);
- talloc_free(value.dptr);
+ TALLOC_FREE(keystr);
+ TALLOC_FREE(value.dptr);
return False;
}
@@ -1052,8 +995,8 @@ BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinf
keystr ));
tdb_close(tdb_sc);
- talloc_free(keystr);
- talloc_free(value.dptr);
+ TALLOC_FREE(keystr);
+ TALLOC_FREE(value.dptr);
return ret;
}
@@ -1064,7 +1007,7 @@ BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinf
BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
const char *remote_machine,
- struct dcinfo *pdc)
+ struct dcinfo **ppdc)
{
TDB_CONTEXT *tdb_sc = NULL;
TDB_DATA value;
@@ -1075,10 +1018,11 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
unsigned char *pmach_pw = NULL;
uint32 l1, l2, l3, l4, l5;
int ret;
+ struct dcinfo *pdc = NULL;
char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE,
remote_machine);
- ZERO_STRUCTP(pdc);
+ *ppdc = NULL;
if (!keystr) {
return False;
@@ -1088,7 +1032,7 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
tdb_sc = open_schannel_session_store(mem_ctx);
if (!tdb_sc) {
- talloc_free(keystr);
+ TALLOC_FREE(keystr);
return False;
}
@@ -1102,6 +1046,8 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
tdb_close(tdb_sc);
+ pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
+
/* Retrieve the record. */
ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff",
&pdc->sequence,
@@ -1114,29 +1060,31 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
&pdc->remote_machine,
&pdc->domain);
- if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 8 || l5 != 16) {
- talloc_free(keystr);
+ if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) {
+ /* Bad record - delete it. */
+ tdb_delete_bystring(tdb_sc, keystr);
+ TALLOC_FREE(keystr);
+ TALLOC_FREE(pdc);
SAFE_FREE(pseed_chal);
SAFE_FREE(pclnt_chal);
SAFE_FREE(psrv_chal);
SAFE_FREE(psess_key);
SAFE_FREE(pmach_pw);
SAFE_FREE(value.dptr);
- ZERO_STRUCTP(pdc);
return False;
}
memcpy(pdc->seed_chal.data, pseed_chal, 8);
memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
memcpy(pdc->srv_chal.data, psrv_chal, 8);
- memcpy(pdc->sess_key, psess_key, 8);
+ memcpy(pdc->sess_key, psess_key, 16);
memcpy(pdc->mach_pw, pmach_pw, 16);
/* We know these are true so didn't bother to store them. */
pdc->challenge_sent = True;
pdc->authenticated = True;
- DEBUG(3,("secrets_store_schannel_session_info: restored schannel info key %s\n",
+ DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n",
keystr ));
SAFE_FREE(pseed_chal);
@@ -1145,7 +1093,10 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
SAFE_FREE(psess_key);
SAFE_FREE(pmach_pw);
- talloc_free(keystr);
+ TALLOC_FREE(keystr);
SAFE_FREE(value.dptr);
+
+ *ppdc = pdc;
+
return True;
}
diff --git a/source/passdb/util_builtin.c b/source/passdb/util_builtin.c
index 1f810ac37a1..9c59df1f687 100644
--- a/source/passdb/util_builtin.c
+++ b/source/passdb/util_builtin.c
@@ -20,6 +20,61 @@
#include "includes.h"
+struct rid_name_map {
+ uint32 rid;
+ const char *name;
+};
+
+static const struct rid_name_map builtin_aliases[] = {
+ { BUILTIN_ALIAS_RID_ADMINS, "Administrators" },
+ { BUILTIN_ALIAS_RID_USERS, "Users" },
+ { BUILTIN_ALIAS_RID_GUESTS, "Guests" },
+ { BUILTIN_ALIAS_RID_POWER_USERS, "Power Users" },
+ { BUILTIN_ALIAS_RID_ACCOUNT_OPS, "Account Operators" },
+ { BUILTIN_ALIAS_RID_SYSTEM_OPS, "Server Operators" },
+ { BUILTIN_ALIAS_RID_PRINT_OPS, "Print Operators" },
+ { BUILTIN_ALIAS_RID_BACKUP_OPS, "Backup Operators" },
+ { BUILTIN_ALIAS_RID_REPLICATOR, "Replicator" },
+ { BUILTIN_ALIAS_RID_RAS_SERVERS, "RAS Servers" },
+ { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, "Pre-Windows 2000 Compatible Access" },
+ { 0, NULL}};
+
+/*******************************************************************
+ Look up a rid in the BUILTIN domain
+ ********************************************************************/
+BOOL lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name)
+{
+ const struct rid_name_map *aliases = builtin_aliases;
+
+ while (aliases->name != NULL) {
+ if (rid == aliases->rid) {
+ *name = talloc_strdup(mem_ctx, aliases->name);
+ return True;
+ }
+ aliases++;
+ }
+
+ return False;
+}
+
+/*******************************************************************
+ Look up a name in the BUILTIN domain
+ ********************************************************************/
+BOOL lookup_builtin_name(const char *name, uint32 *rid)
+{
+ const struct rid_name_map *aliases = builtin_aliases;
+
+ while (aliases->name != NULL) {
+ if (strequal(name, aliases->name)) {
+ *rid = aliases->rid;
+ return True;
+ }
+ aliases++;
+ }
+
+ return False;
+}
+
/*****************************************************************
Return the name of the BUILTIN domain
*****************************************************************/
@@ -29,3 +84,27 @@ const char *builtin_domain_name(void)
return "BUILTIN";
}
+/*****************************************************************
+ Check if the SID is the builtin SID (S-1-5-32).
+*****************************************************************/
+
+BOOL sid_check_is_builtin(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sid_Builtin);
+}
+
+/*****************************************************************
+ Check if the SID is one of the builtin SIDs (S-1-5-32-a).
+*****************************************************************/
+
+BOOL sid_check_is_in_builtin(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_check_is_builtin(&dom_sid);
+}
+
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
deleted file mode 100644
index 822b7f6a349..00000000000
--- a/source/passdb/util_sam_sid.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
- Copyright (C) Jeremy Allison 1999
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-#define MAX_SID_NAMES 7
-
-typedef struct _known_sid_users {
- uint32 rid;
- enum SID_NAME_USE sid_name_use;
- const char *known_user_name;
-} known_sid_users;
-
-struct sid_name_map_info
-{
- const DOM_SID *sid;
- const char *name;
- const known_sid_users *known_users;
-};
-
-static const known_sid_users everyone_users[] = {
- { 0, SID_NAME_WKN_GRP, "Everyone" },
- {0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users creator_owner_users[] = {
- { 0, SID_NAME_WKN_GRP, "Creator Owner" },
- { 1, SID_NAME_WKN_GRP, "Creator Group" },
- {0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users nt_authority_users[] = {
- { 1, SID_NAME_WKN_GRP, "Dialup" },
- { 2, SID_NAME_WKN_GRP, "Network"},
- { 3, SID_NAME_WKN_GRP, "Batch"},
- { 4, SID_NAME_WKN_GRP, "Interactive"},
- { 6, SID_NAME_WKN_GRP, "Service"},
- { 7, SID_NAME_WKN_GRP, "AnonymousLogon"},
- { 8, SID_NAME_WKN_GRP, "Proxy"},
- { 9, SID_NAME_WKN_GRP, "ServerLogon"},
- { 10, SID_NAME_WKN_GRP, "Self"},
- { 11, SID_NAME_WKN_GRP, "Authenticated Users"},
- { 12, SID_NAME_WKN_GRP, "Restricted"},
- { 13, SID_NAME_WKN_GRP, "Terminal Server User"},
- { 14, SID_NAME_WKN_GRP, "Remote Interactive Logon"},
- { 15, SID_NAME_WKN_GRP, "This Organization"},
- { 18, SID_NAME_WKN_GRP, "SYSTEM"},
- { 19, SID_NAME_WKN_GRP, "Local Service"},
- { 20, SID_NAME_WKN_GRP, "Network Service"},
- { 0, (enum SID_NAME_USE)0, NULL}};
-
-static const known_sid_users builtin_groups[] = {
- { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" },
- { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" },
- { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" },
- { BUILTIN_ALIAS_RID_POWER_USERS, SID_NAME_ALIAS, "Power Users" },
- { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" },
- { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
- { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
- { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
- { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" },
- { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" },
- { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" },
- { 0, (enum SID_NAME_USE)0, NULL}};
-
-static struct sid_name_map_info special_domains[] = {
- { &global_sid_Builtin, "BUILTIN", builtin_groups },
- { &global_sid_World_Domain, "", everyone_users },
- { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
- { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
- { NULL, NULL, NULL }};
-
-/**************************************************************************
- Turns a domain SID into a name, returned in the nt_domain argument.
-***************************************************************************/
-
-BOOL map_domain_sid_to_name(const DOM_SID *sid, fstring nt_domain)
-{
- fstring sid_str;
- int i = 0;
-
- sid_to_string(sid_str, sid);
-
- DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
-
- while (special_domains[i].sid != NULL) {
- DEBUG(5,("map_domain_sid_to_name: compare: %s\n",
- sid_string_static(special_domains[i].sid)));
- if (sid_equal(special_domains[i].sid, sid)) {
- fstrcpy(nt_domain, special_domains[i].name);
- DEBUG(5,("map_domain_sid_to_name: found '%s'\n",
- nt_domain));
- return True;
- }
- i++;
- }
-
- DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n",
- sid_string_static(sid)));
-
- return False;
-}
-
-/**************************************************************************
- Looks up a known username from one of the known domains.
-***************************************************************************/
-
-BOOL lookup_special_sid(const DOM_SID *sid, const char **domain,
- const char **name, enum SID_NAME_USE *type)
-{
- int i;
- DOM_SID dom_sid;
- uint32 rid;
- const known_sid_users *users = NULL;
-
- sid_copy(&dom_sid, sid);
- if (!sid_split_rid(&dom_sid, &rid)) {
- DEBUG(2, ("Could not split rid from SID\n"));
- return False;
- }
-
- for (i=0; special_domains[i].sid != NULL; i++) {
- if (sid_equal(&dom_sid, special_domains[i].sid)) {
- *domain = special_domains[i].name;
- users = special_domains[i].known_users;
- break;
- }
- }
-
- if (users == NULL) {
- DEBUG(10, ("SID %s is no special sid\n",
- sid_string_static(sid)));
- return False;
- }
-
- for (i=0; users[i].known_user_name != NULL; i++) {
- if (rid == users[i].rid) {
- *name = users[i].known_user_name;
- *type = users[i].sid_name_use;
- return True;
- }
- }
-
- DEBUG(10, ("RID of special SID %s not found\n",
- sid_string_static(sid)));
-
- return False;
-}
-
-/*******************************************************************
- Look up a rid in the BUILTIN domain
- ********************************************************************/
-BOOL lookup_builtin_rid(uint32 rid, fstring name)
-{
- const known_sid_users *aliases = builtin_groups;
- int i;
-
- for (i=0; aliases[i].known_user_name != NULL; i++) {
- if (rid == aliases[i].rid) {
- fstrcpy(name, aliases[i].known_user_name);
- return True;
- }
- }
-
- return False;
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/
-
-BOOL sid_check_is_domain(const DOM_SID *sid)
-{
- return sid_equal(sid, get_global_sam_sid());
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/
-
-BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
-{
- DOM_SID dom_sid;
- uint32 rid;
-
- sid_copy(&dom_sid, sid);
- sid_split_rid(&dom_sid, &rid);
-
- return sid_equal(&dom_sid, get_global_sam_sid());
-}
-
-/**************************************************************************
- Try and map a name to one of the well known SIDs.
-***************************************************************************/
-
-BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name)
-{
- int i, j;
-
- DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
-
- for (i=0; special_domains[i].sid != NULL; i++) {
- const known_sid_users *users = special_domains[i].known_users;
-
- if (users == NULL)
- continue;
-
- for (j=0; users[j].known_user_name != NULL; j++) {
- if ( strequal(users[j].known_user_name, name) ) {
- sid_copy(sid, special_domains[i].sid);
- sid_append_rid(sid, users[j].rid);
- *use = users[j].sid_name_use;
- return True;
- }
- }
- }
-
- return False;
-}
-
-
diff --git a/source/passdb/util_unixsids.c b/source/passdb/util_unixsids.c
new file mode 100644
index 00000000000..2a4818e3aec
--- /dev/null
+++ b/source/passdb/util_unixsids.c
@@ -0,0 +1,94 @@
+/*
+ Unix SMB/CIFS implementation.
+ Translate unix-defined names to SIDs and vice versa
+ Copyright (C) Volker Lendecke 2005
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+BOOL sid_check_is_unix_users(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sid_Unix_Users);
+}
+
+BOOL sid_check_is_in_unix_users(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_check_is_unix_users(&dom_sid);
+}
+
+const char *unix_users_domain_name(void)
+{
+ return "Unix User";
+}
+
+BOOL lookup_unix_user_name(const char *name, DOM_SID *sid)
+{
+ struct passwd *pwd;
+
+ pwd = getpwnam_alloc(NULL, name);
+ if (pwd == NULL) {
+ return False;
+ }
+
+ sid_copy(sid, &global_sid_Unix_Users);
+ sid_append_rid(sid, pwd->pw_uid); /* For 64-bit uid's we have enough
+ * space ... */
+ TALLOC_FREE(pwd);
+ return True;
+}
+
+BOOL sid_check_is_unix_groups(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sid_Unix_Groups);
+}
+
+BOOL sid_check_is_in_unix_groups(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_check_is_unix_groups(&dom_sid);
+}
+
+const char *unix_groups_domain_name(void)
+{
+ return "Unix Group";
+}
+
+BOOL lookup_unix_group_name(const char *name, DOM_SID *sid)
+{
+ struct group *grp;
+
+ grp = getgrnam(name);
+ if (grp == NULL) {
+ return False;
+ }
+
+ sid_copy(sid, &global_sid_Unix_Groups);
+ sid_append_rid(sid, grp->gr_gid); /* For 64-bit uid's we have enough
+ * space ... */
+ return True;
+}
diff --git a/source/passdb/util_wellknown.c b/source/passdb/util_wellknown.c
new file mode 100644
index 00000000000..9a6fa7def52
--- /dev/null
+++ b/source/passdb/util_wellknown.c
@@ -0,0 +1,175 @@
+/*
+ Unix SMB/CIFS implementation.
+ Lookup routines for well-known SIDs
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
+ Copyright (C) Jeremy Allison 1999
+ Copyright (C) Volker Lendecke 2005
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+struct rid_name_map {
+ uint32 rid;
+ const char *name;
+};
+
+struct sid_name_map_info
+{
+ const DOM_SID *sid;
+ const char *name;
+ const struct rid_name_map *known_users;
+};
+
+static const struct rid_name_map everyone_users[] = {
+ { 0, "Everyone" },
+ { 0, NULL}};
+
+static const struct rid_name_map creator_owner_users[] = {
+ { 0, "Creator Owner" },
+ { 1, "Creator Group" },
+ { 0, NULL}};
+
+static const struct rid_name_map nt_authority_users[] = {
+ { 1, "Dialup" },
+ { 2, "Network"},
+ { 3, "Batch"},
+ { 4, "Interactive"},
+ { 6, "Service"},
+ { 7, "AnonymousLogon"},
+ { 8, "Proxy"},
+ { 9, "ServerLogon"},
+ { 10, "Self"},
+ { 11, "Authenticated Users"},
+ { 12, "Restricted"},
+ { 13, "Terminal Server User"},
+ { 14, "Remote Interactive Logon"},
+ { 15, "This Organization"},
+ { 18, "SYSTEM"},
+ { 19, "Local Service"},
+ { 20, "Network Service"},
+ { 0, NULL}};
+
+static struct sid_name_map_info special_domains[] = {
+ { &global_sid_World_Domain, "", everyone_users },
+ { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
+ { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
+ { NULL, NULL, NULL }};
+
+BOOL sid_check_is_wellknown_domain(const DOM_SID *sid, const char **name)
+{
+ int i;
+
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ if (sid_equal(sid, special_domains[i].sid)) {
+ if (name != NULL) {
+ *name = special_domains[i].name;
+ }
+ return True;
+ }
+ }
+ return False;
+}
+
+BOOL sid_check_is_in_wellknown_domain(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_check_is_wellknown_domain(&dom_sid, NULL);
+}
+
+/**************************************************************************
+ Looks up a known username from one of the known domains.
+***************************************************************************/
+
+BOOL lookup_wellknown_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ const char **domain, const char **name)
+{
+ int i;
+ DOM_SID dom_sid;
+ uint32 rid;
+ const struct rid_name_map *users = NULL;
+
+ sid_copy(&dom_sid, sid);
+ if (!sid_split_rid(&dom_sid, &rid)) {
+ DEBUG(2, ("Could not split rid from SID\n"));
+ return False;
+ }
+
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ if (sid_equal(&dom_sid, special_domains[i].sid)) {
+ *domain = talloc_strdup(mem_ctx,
+ special_domains[i].name);
+ users = special_domains[i].known_users;
+ break;
+ }
+ }
+
+ if (users == NULL) {
+ DEBUG(10, ("SID %s is no special sid\n",
+ sid_string_static(sid)));
+ return False;
+ }
+
+ for (i=0; users[i].name != NULL; i++) {
+ if (rid == users[i].rid) {
+ *name = talloc_strdup(mem_ctx, users[i].name);
+ return True;
+ }
+ }
+
+ DEBUG(10, ("RID of special SID %s not found\n",
+ sid_string_static(sid)));
+
+ return False;
+}
+
+/**************************************************************************
+ Try and map a name to one of the well known SIDs.
+***************************************************************************/
+
+BOOL lookup_wellknown_name(TALLOC_CTX *mem_ctx, const char *name,
+ DOM_SID *sid, const char **domain)
+{
+ int i, j;
+
+ DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
+
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ const struct rid_name_map *users =
+ special_domains[i].known_users;
+
+ if (users == NULL)
+ continue;
+
+ for (j=0; users[j].name != NULL; j++) {
+ if ( strequal(users[j].name, name) ) {
+ sid_copy(sid, special_domains[i].sid);
+ sid_append_rid(sid, users[j].rid);
+ *domain = talloc_strdup(
+ mem_ctx, special_domains[i].name);
+ return True;
+ }
+ }
+ }
+
+ return False;
+}