summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2001-12-03 11:11:14 +0000
committerAndrew Tridgell <tridge@samba.org>2001-12-03 11:11:14 +0000
commit6f907af4e73b53c3ddab934ba954788a2134b913 (patch)
tree03298800cbb068993d1650813e7d54db610780ab
parentc868fe502bb9ea2b5c5452a49f89ec19ab58f2ba (diff)
downloadsamba-6f907af4e73b53c3ddab934ba954788a2134b913.tar.gz
samba-6f907af4e73b53c3ddab934ba954788a2134b913.tar.bz2
samba-6f907af4e73b53c3ddab934ba954788a2134b913.zip
put sid_to_name behind the winbindd backend interface
I spent quite a while trying to work out how to make this call via ldap and failed. I then found that MS servers seem use rpc for sid_to_name, and it works even when in native mode, I ended up just implementing it via rpc (This used to be commit 789833b44e342c0b5de463ed8f9b5f7474a99f27)
-rw-r--r--source3/lib/util_sid.c38
-rw-r--r--source3/nsswitch/winbindd.h6
-rw-r--r--source3/nsswitch/winbindd_ads.c8
-rw-r--r--source3/nsswitch/winbindd_proto.h5
-rw-r--r--source3/nsswitch/winbindd_rpc.c34
-rw-r--r--source3/nsswitch/winbindd_util.c34
-rw-r--r--source3/torture/nsstest.c4
7 files changed, 85 insertions, 44 deletions
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index 0f1b22ca27..7e9299b053 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -498,7 +498,7 @@ BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
{
size_t i;
- if(len < sid_size(sid))
+ if (len < sid_size(sid))
return False;
SCVAL(outbuf,0,sid->sid_rev_num);
@@ -527,10 +527,11 @@ BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
return True;
}
+
/*****************************************************************
- Compare two sids.
+ Compare the domain portion of two sids.
*****************************************************************/
-int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
+int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
{
int i;
@@ -538,14 +539,6 @@ int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
if (!sid1) return -1;
if (!sid2) return 1;
- /* compare most likely different rids, first: i.e start at end */
- for (i = sid1->num_auths-1; i >= 0; --i)
- if (sid1->sub_auths[i] != sid2->sub_auths[i])
- return sid1->sub_auths[i] - sid2->sub_auths[i];
-
- if (sid1->num_auths != sid2->num_auths)
- return sid1->num_auths - sid2->num_auths;
-
if (sid1->sid_rev_num != sid2->sid_rev_num)
return sid1->sid_rev_num - sid2->sid_rev_num;
@@ -556,11 +549,32 @@ int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
return 0;
}
-
/*****************************************************************
Compare two sids.
*****************************************************************/
+int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
+{
+ int i;
+ if (sid1 == sid2) return 0;
+ if (!sid1) return -1;
+ if (!sid2) return 1;
+
+ /* compare most likely different rids, first: i.e start at end */
+ if (sid1->num_auths != sid2->num_auths)
+ return sid1->num_auths - sid2->num_auths;
+
+ for (i = sid1->num_auths-1; i >= 0; --i)
+ if (sid1->sub_auths[i] != sid2->sub_auths[i])
+ return sid1->sub_auths[i] - sid2->sub_auths[i];
+
+ return sid_compare_domain(sid1, sid2);
+}
+
+
+/*****************************************************************
+ Compare two sids.
+*****************************************************************/
BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
{
return sid_compare(sid1, sid2) == 0;
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index 1256736763..610b4503f7 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -103,6 +103,12 @@ struct winbindd_methods {
const char *name,
DOM_SID *sid,
enum SID_NAME_USE *type);
+
+ NTSTATUS (*sid_to_name)(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid,
+ char **name,
+ enum SID_NAME_USE *type);
};
/* Structures to hold per domain information */
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index d54f1d9391..5ff5c90b78 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -271,11 +271,15 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
-/* the rpc backend methods are exposed via this structure */
+/* the ADS backend methods are exposed via this structure */
struct winbindd_methods ads_methods = {
query_dispinfo,
enum_dom_groups,
- name_to_sid
+ name_to_sid,
+ /* I can't see a good way to do a sid to name mapping with ldap,
+ and MS servers always allow RPC for this (even in native mode) so
+ just use RPC. Maybe that's why they allow it? */
+ winbindd_rpc_sid_to_name
};
#endif
diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h
index 923ee2450e..260985ec58 100644
--- a/source3/nsswitch/winbindd_proto.h
+++ b/source3/nsswitch/winbindd_proto.h
@@ -109,6 +109,11 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state);
/* The following definitions come from nsswitch/winbindd_rpc.c */
+NTSTATUS winbindd_rpc_sid_to_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid,
+ char **name,
+ enum SID_NAME_USE *type);
/* The following definitions come from nsswitch/winbindd_sid.c */
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index fe2540f33d..bf2cc5d9d3 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -153,11 +153,43 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
return status;
}
+/*
+ convert a domain SID to a user or group name
+*/
+NTSTATUS winbindd_rpc_sid_to_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid,
+ char **name,
+ enum SID_NAME_USE *type)
+{
+ CLI_POLICY_HND *hnd;
+ char **names;
+ uint32 *types;
+ int num_names;
+ NTSTATUS status;
+
+ if (!(hnd = cm_get_lsa_handle(domain->name)))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ status = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
+ 1, sid, &names, &types,
+ &num_names);
+
+ if (NT_STATUS_IS_OK(status)) {
+ *type = types[0];
+ *name = names[0];
+ DEBUG(5,("Mapped sid to %s\n", *name));
+ }
+
+ return status;
+}
+
/* the rpc backend methods are exposed via this structure */
struct winbindd_methods msrpc_methods = {
query_dispinfo,
enum_dom_groups,
- name_to_sid
+ name_to_sid,
+ winbindd_rpc_sid_to_name
};
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index c18e0deda3..900fc900bf 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -64,7 +64,7 @@ struct winbindd_domain *find_domain_from_name(char *domain_name)
return NULL;
}
-/* Given a domain name, return the struct winbindd domain info for it */
+/* Given a domain sid, return the struct winbindd domain info for it */
struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
{
@@ -74,9 +74,8 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
get_domain_info();
/* Search through list */
-
for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (sid_equal(sid, &tmp->sid))
+ if (sid_compare_domain(sid, &tmp->sid) == 0)
return tmp;
}
@@ -429,10 +428,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
fstring name,
enum SID_NAME_USE *type)
{
- int num_sids = 1, num_names = 0;
- uint32 *types = NULL;
- char **names;
- CLI_POLICY_HND *hnd;
+ char *names;
NTSTATUS result;
TALLOC_CTX *mem_ctx;
BOOL rv = False;
@@ -459,29 +455,15 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
if (!(mem_ctx = talloc_init()))
return False;
- if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
- goto done;
-
- result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
- num_sids, sid, &names, &types,
- &num_names);
+ result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type);
/* Return name and type if successful */
if ((rv = NT_STATUS_IS_OK(result))) {
-
- /* Return name */
-
- if ((names != NULL) && (name != NULL))
- fstrcpy(name, names[0]);
-
- /* Return name type */
-
- if ((type != NULL) && (types != NULL))
- *type = types[0];
+ fstrcpy(name, names);
- store_sid_by_name_in_cache(domain, names[0], sid, types[0]);
- store_name_by_sid_in_cache(domain, sid, names[0], types[0]);
+ store_sid_by_name_in_cache(domain, names, sid, *type);
+ store_name_by_sid_in_cache(domain, sid, names, *type);
} else {
/* OK, so we tried to look up a name in this sid, and
* didn't find it. Therefore add a negative cache
@@ -490,9 +472,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
*type = SID_NAME_UNKNOWN;
fstrcpy(name, name_deadbeef);
}
-
- done:
talloc_destroy(mem_ctx);
return rv;
diff --git a/source3/torture/nsstest.c b/source3/torture/nsstest.c
index 76108876df..8b40eaa163 100644
--- a/source3/torture/nsstest.c
+++ b/source3/torture/nsstest.c
@@ -262,10 +262,10 @@ static void nss_test_users(void)
while ((pwd = nss_getpwent())) {
printf("Testing user %s\n", pwd->pw_name);
printf("getpwent: "); print_passwd(pwd);
- pwd = nss_getpwnam(pwd->pw_name);
- printf("getpwnam: "); print_passwd(pwd);
pwd = nss_getpwuid(pwd->pw_uid);
printf("getpwuid: "); print_passwd(pwd);
+ pwd = nss_getpwnam(pwd->pw_name);
+ printf("getpwnam: "); print_passwd(pwd);
printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid);
printf("\n");
}