From 6f907af4e73b53c3ddab934ba954788a2134b913 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Dec 2001 11:11:14 +0000 Subject: 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) --- source3/lib/util_sid.c | 38 ++++++++++++++++++++++++++------------ source3/nsswitch/winbindd.h | 6 ++++++ source3/nsswitch/winbindd_ads.c | 8 ++++++-- source3/nsswitch/winbindd_proto.h | 5 +++++ source3/nsswitch/winbindd_rpc.c | 34 +++++++++++++++++++++++++++++++++- source3/nsswitch/winbindd_util.c | 34 +++++++--------------------------- source3/torture/nsstest.c | 4 ++-- 7 files changed, 85 insertions(+), 44 deletions(-) diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 0f1b22ca272..7e9299b053b 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 12567367634..610b4503f7c 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 d54f1d93910..5ff5c90b78f 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 923ee2450e8..260985ec585 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 fe2540f33d4..bf2cc5d9d30 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 c18e0deda3e..900fc900bfe 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 76108876dff..8b40eaa1635 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"); } -- cgit