diff options
author | Andrew Bartlett <abartlet@samba.org> | 2002-01-20 01:24:59 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2002-01-20 01:24:59 +0000 |
commit | 93a8358910d2b8788ffea33c04244ffd5ffecabf (patch) | |
tree | b087c75b8cdf4818a8355e678b1e212cc3f9052d | |
parent | a6541401b03e0a97dc7e265b223289cad7160b75 (diff) | |
download | samba-93a8358910d2b8788ffea33c04244ffd5ffecabf.tar.gz samba-93a8358910d2b8788ffea33c04244ffd5ffecabf.tar.bz2 samba-93a8358910d2b8788ffea33c04244ffd5ffecabf.zip |
This patch makes the 'winbind use default domain' code interact better with
smbd, and also makes it much cleaner inside winbindd.
It is mostly my code, with a few changes and testing performed by Alexander
Bokovoy <a.bokovoy@sam-solutions.net>. ab has tested it in security=domain and
security=ads, but more testing is always appricatiated.
The idea is that we no longer cart around a 'domain\user' string, we keep them
seperate until the last moment - when we push that string into a pwent on onto
the socket.
This removes the need to be constantly parsing that string - the domain prefix
is almost always already provided, (only a couple of functions actually changed
arguments in all this).
Some consequential changes to the RPC client code, to stop it concatonating the
two strings (it now passes them both back as params).
I havn't changed the cache code, however the usernames will no longer have a
double domain prefix in the key string. The actual structures are unchanged
- but the meaning of 'username' in the 'rid' will have changed. (The cache is
invalidated at startup, so on-disk formats are not an issue here).
Andrew Bartlett
(This used to be commit e870f0e727952aeb8599cf93ad2650ae56eca033)
-rw-r--r-- | source3/lib/util_getent.c | 2 | ||||
-rw-r--r-- | source3/libsmb/cli_lsarpc.c | 28 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 11 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 12 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 42 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_proto.h | 3 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 16 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_sid.c | 12 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 63 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 27 | ||||
-rw-r--r-- | source3/rpc_parse/parse_lsa.c | 16 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 6 | ||||
-rw-r--r-- | source3/rpc_server/srv_util.c | 10 | ||||
-rw-r--r-- | source3/rpcclient/cmd_lsarpc.c | 13 | ||||
-rw-r--r-- | source3/smbd/uid.c | 2 | ||||
-rw-r--r-- | source3/utils/smbcacls.c | 19 |
16 files changed, 134 insertions, 148 deletions
diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c index 81b36effcb..02be8e7c25 100644 --- a/source3/lib/util_getent.c +++ b/source3/lib/util_getent.c @@ -280,7 +280,7 @@ struct sys_userlist *get_users_in_group(const char *gname) * pointless (and slow). */ - if (strchr(gname,*lp_winbind_separator())) { + if (strchr(gname,*lp_winbind_separator()) || lp_winbind_use_default_domain()) { if ((gptr = (struct group *)getgrnam(gname)) == NULL) return NULL; return add_members_to_userlist(list_head, gptr); diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 95169afd7c..66504d8355 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -218,7 +218,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***names, uint32 **types, int *num_names) + char ***domains, char ***names, uint32 **types, int *num_names) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -279,6 +279,12 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, (*num_names) = r.mapped_count; result = NT_STATUS_OK; + if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; @@ -292,7 +298,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, } for (i = 0; i < r.mapped_count; i++) { - fstring name, dom_name, full_name; + fstring name, dom_name; uint32 dom_idx = t_names.name[i].domain_idx; /* Translate optimised name through domain index array */ @@ -304,13 +310,15 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, rpcstr_pull_unistr2_fstring( name, &t_names.uni_name[i]); - slprintf(full_name, sizeof(full_name) - 1, - "%s%s%s", dom_name, - (dom_name[0] && name[0]) ? - lp_winbind_separator() : "", name); - - (*names)[i] = talloc_strdup(mem_ctx, full_name); + (*names)[i] = talloc_strdup(mem_ctx, name); + (*domains)[i] = talloc_strdup(mem_ctx, dom_name); (*types)[i] = t_names.name[i].sid_name_use; + + if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } } else { (*names)[i] = NULL; @@ -328,7 +336,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, const char **names, + POLICY_HND *pol, int num_names, const char **dom_names, const char **names, DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; @@ -348,7 +356,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_lookup_names(mem_ctx, &q, pol, num_names, names); + init_q_lookup_names(mem_ctx, &q, pol, num_names, dom_names, names); if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index c6a0b040cb..35d85fe186 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -294,13 +294,6 @@ static BOOL wbinfo_lookupname(char *name) struct winbindd_request request; struct winbindd_response response; - /* - * Don't do the lookup if the name has no separator. - */ - - if (!strchr(name, get_winbind_separator())) - return False; - /* Send off request */ ZERO_STRUCT(request); @@ -365,10 +358,6 @@ static BOOL wbinfo_auth_crap(char *username) fstring pass; char *p; - /* - * Don't do the lookup if the name has no separator. - */ - /* Send off request */ ZERO_STRUCT(request); diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index a0d35030bf..168ee8847d 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -366,22 +366,14 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, void *res = NULL; char *exp; uint32 t; - fstring name2, dom2, fullname2; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - /* sigh. Need to fix interface to give us a raw name */ - fstrcpy(fullname2, name); - fstring_sub(fullname2, "\\", lp_winbind_separator()); - if (!parse_domain_user(fullname2, dom2, name2)) { - goto done; - } - DEBUG(3,("ads: name_to_sid\n")); ads = ads_cached_connection(domain); if (!ads) goto done; - asprintf(&exp, "(sAMAccountName=%s)", name2); + asprintf(&exp, "(sAMAccountName=%s)", name); rc = ads_search_retry(ads, &res, exp, attrs); free(exp); if (!ADS_ERR_OK(rc)) { @@ -454,7 +446,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, } s = ads_pull_string(ads, mem_ctx, msg, "sAMAccountName"); - *name = talloc_asprintf(mem_ctx, "%s%s%s", domain->name, lp_winbind_separator(), s); + *name = talloc_strdup(mem_ctx, s); *type = ads_atype_map(atype); status = NT_STATUS_OK; diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index a70f94781e..9ef942a95d 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -30,16 +30,18 @@ /* Fill a grent structure from various other information */ -static BOOL fill_grent(struct winbindd_gr *gr, char *gr_name, - gid_t unix_gid) +static BOOL fill_grent(struct winbindd_gr *gr, const char *dom_name, + const char *gr_name, gid_t unix_gid) { + fstring full_group_name; /* Fill in uid/gid */ + fill_domain_username(full_group_name, dom_name, gr_name); gr->gr_gid = unix_gid; /* Group name and password */ - safe_strcpy(gr->gr_name, gr_name, sizeof(gr->gr_name) - 1); + safe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1); safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1); return True; @@ -187,7 +189,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) struct winbindd_domain *domain; enum SID_NAME_USE name_type; uint32 group_rid; - fstring name_domain, name_group, name; + fstring name_domain, name_group; char *tmp, *gr_mem; gid_t gid; int gr_mem_len; @@ -211,11 +213,9 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - snprintf(name, sizeof(name), "%s\\%s", name_domain, name_group); - /* Get rid and name type from name */ - if (!winbindd_lookup_sid_by_name(domain, name, &group_sid, + if (!winbindd_lookup_sid_by_name(domain, name_domain, name_group, &group_sid, &name_type)) { DEBUG(1, ("group %s in domain %s does not exist\n", name_group, name_domain)); @@ -237,8 +237,8 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - if (!fill_grent(&state->response.data.gr, - state->request.data.groupname, gid) || + if (!fill_grent(&state->response.data.gr, name_domain, + name_group, gid) || !fill_grent_mem(domain, group_rid, name_type, &state->response.data.gr.num_gr_mem, &gr_mem, &gr_mem_len)) { @@ -262,6 +262,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) struct winbindd_domain *domain; DOM_SID group_sid; enum SID_NAME_USE name_type; + fstring dom_name; fstring group_name; uint32 group_rid; int gr_mem_len; @@ -290,16 +291,11 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) sid_copy(&group_sid, &domain->sid); sid_append_rid(&group_sid, group_rid); - if (!winbindd_lookup_name_by_sid(&group_sid, group_name, &name_type)) { + if (!winbindd_lookup_name_by_sid(&group_sid, dom_name, group_name, &name_type)) { DEBUG(1, ("could not lookup sid\n")); return WINBINDD_ERROR; } - if (strcmp(lp_winbind_separator(),"\\")) - string_sub(group_name, "\\", lp_winbind_separator(), - sizeof(fstring)); - strip_domain_name_if_needed(&group_name); - if (!((name_type == SID_NAME_ALIAS) || (name_type == SID_NAME_DOM_GRP))) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", @@ -309,7 +305,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) /* Fill in group structure */ - if (!fill_grent(&state->response.data.gr, group_name, + if (!fill_grent(&state->response.data.gr, dom_name, group_name, state->request.data.gid) || !fill_grent_mem(domain, group_rid, name_type, &state->response.data.gr.num_gr_mem, @@ -473,7 +469,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) struct getent_state *ent; struct winbindd_gr *group_list = NULL; int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0; - char *sep, *new_extra_data, *gr_mem_list = NULL; + char *new_extra_data, *gr_mem_list = NULL; DEBUG(3, ("[%5d]: getgrent\n", state->pid)); @@ -491,7 +487,6 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) state->response.data.num_entries = 0; group_list = (struct winbindd_gr *)state->response.extra_data; - sep = lp_winbind_separator(); if (!(ent = state->getgrent_state)) return WINBINDD_ERROR; @@ -562,7 +557,9 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) name_list[ent->sam_entry_index].acct_name); result = fill_grent(&group_list[group_list_ndx], - domain_group_name, group_gid); + ent->domain_name, + name_list[ent->sam_entry_index].acct_name, + group_gid); /* Fill in group membership entry */ @@ -732,7 +729,6 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) fstring name; fill_domain_username(name, domain->name, group_name); - /* Append to extra data */ memcpy(&extra_data[extra_data_len], name, strlen(name)); @@ -761,7 +757,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) { - fstring name_domain, name_user, name; + fstring name_domain, name_user; DOM_SID user_sid; enum SID_NAME_USE name_type; uint32 user_rid, num_groups, num_gids; @@ -794,11 +790,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; } - slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user); - /* Get rid and name type from name. The following costs 1 packet */ - if (!winbindd_lookup_sid_by_name(domain, name, &user_sid, + if (!winbindd_lookup_sid_by_name(domain, name_domain, name_user, &user_sid, &name_type)) { DEBUG(1, ("user '%s' does not exist\n", name_user)); goto done; diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index cc936642ed..1823efaa9f 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -109,15 +109,16 @@ BOOL init_domain_list(void); struct winbindd_domain *find_domain_from_name(char *domain_name); struct winbindd_domain *find_domain_from_sid(DOM_SID *sid); BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, + const char *dom_name, const char *name, DOM_SID *sid, enum SID_NAME_USE *type); BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, + fstring dom_name, fstring name, enum SID_NAME_USE *type); void free_getent_state(struct getent_state *state); BOOL winbindd_param_init(void); BOOL check_domain_env(char *domain_env, char *domain); BOOL parse_domain_user(const char *domuser, fstring domain, fstring user); -void strip_domain_name_if_needed(fstring *name); void fill_domain_username(fstring name, const char *domain, const char *user); #endif /* _PROTO_H_ */ diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index badbd459a7..7d9a26f906 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -177,6 +177,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, DOM_SID *sids = NULL; uint32 *types = NULL; int num_sids; + const char *domain_name = domain->name; if (!(mem_ctx = talloc_init_named("name_to_sid[rpc]"))) return NT_STATUS_NO_MEMORY; @@ -184,7 +185,8 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, if (!(hnd = cm_get_lsa_handle(domain->name))) return NT_STATUS_UNSUCCESSFUL; - status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1, &name, + status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1, + &domain_name, &name, &sids, &types, &num_sids); /* Return rid and type if lookup successful */ @@ -207,6 +209,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, enum SID_NAME_USE *type) { CLI_POLICY_HND *hnd; + char **domains; char **names; uint32 *types; int num_names; @@ -216,15 +219,20 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, return NT_STATUS_UNSUCCESSFUL; status = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol, - 1, sid, &names, &types, + 1, sid, &domains, &names, &types, &num_names); if (NT_STATUS_IS_OK(status)) { *type = types[0]; *name = names[0]; - DEBUG(5,("Mapped sid to %s\n", *name)); - } + DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name)); + /* Parinoia */ + if (strcasecmp(domain->name, domains[0]) != 0) { + DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0])); + return NT_STATUS_UNSUCCESSFUL; + } + } return status; } diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index a6daecff71..34318a633d 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -33,6 +33,7 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) DOM_SID sid, tmp_sid; uint32 rid; fstring name; + fstring dom_name; DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid, state->request.data.sid)); @@ -52,12 +53,11 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) /* Lookup the sid */ - if (!winbindd_lookup_name_by_sid(&sid, name, &type)) { + if (!winbindd_lookup_name_by_sid(&sid, dom_name, name, &type)) { return WINBINDD_ERROR; } - string_sub(name, "\\", lp_winbind_separator(), sizeof(fstring)); - fstrcpy(state->response.data.name.name, name); + fill_domain_username(state->response.data.name.name, dom_name, name); state->response.data.name.type = type; return WINBINDD_OK; @@ -68,7 +68,7 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) { enum SID_NAME_USE type; - fstring sid_str, name_domain, name_user, name; + fstring sid_str, name_domain, name_user; DOM_SID sid; struct winbindd_domain *domain; DEBUG(3, ("[%5d]: lookupname %s\n", state->pid, @@ -77,8 +77,6 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) if (!parse_domain_user(state->request.data.name, name_domain, name_user)) return WINBINDD_ERROR; - snprintf(name, sizeof(name), "%s\\%s", name_domain, name_user); - if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(0, ("could not find domain entry for domain %s\n", name_domain)); @@ -86,7 +84,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) } /* Lookup name from PDC using lsa_lookup_names() */ - if (!winbindd_lookup_sid_by_name(domain, name, &sid, &type)) { + if (!winbindd_lookup_sid_by_name(domain, name_domain, name_user, &sid, &type)) { return WINBINDD_ERROR; } diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index 6a825c81f4..f2fe50034a 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -26,20 +26,20 @@ /* Fill a pwent structure with information we have obtained */ -static BOOL winbindd_fill_pwent(char *domain_name, char *name, +static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, uint32 user_rid, uint32 group_rid, char *full_name, struct winbindd_pw *pw) { extern userdom_struct current_user_info; - fstring name_domain, name_user; + fstring output_username; pstring homedir; - if (!pw || !name) + if (!pw || !dom_name || !user_name) return False; /* Resolve the uid number */ - if (!winbindd_idmap_get_uid_from_rid(domain_name, user_rid, + if (!winbindd_idmap_get_uid_from_rid(dom_name, user_rid, &pw->pw_uid)) { DEBUG(1, ("error getting user id for rid %d\n", user_rid)); return False; @@ -47,15 +47,17 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name, /* Resolve the gid number */ - if (!winbindd_idmap_get_gid_from_rid(domain_name, group_rid, + if (!winbindd_idmap_get_gid_from_rid(dom_name, group_rid, &pw->pw_gid)) { DEBUG(1, ("error getting group id for rid %d\n", group_rid)); return False; } /* Username */ - - safe_strcpy(pw->pw_name, name, sizeof(pw->pw_name) - 1); + + fill_domain_username(output_username, dom_name, user_name); + + safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); /* Full name (gecos) */ @@ -65,16 +67,11 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name, defaults are /tmp for the home directory and /bin/false for shell. */ - if (!parse_domain_user(name, name_domain, name_user)) { - DEBUG(1, ("error parsing domain user for %s\n", name_user )); - return False; - } - /* The substitution of %U and %D in the 'template homedir' is done by lp_string() calling standard_sub_basic(). */ - fstrcpy(current_user_info.smb_name, name_user); - fstrcpy(current_user_info.domain, name_domain); + fstrcpy(current_user_info.smb_name, user_name); + fstrcpy(current_user_info.domain, dom_name); pstrcpy(homedir, lp_template_homedir()); @@ -84,7 +81,7 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name, sizeof(pw->pw_shell) - 1); /* Password - set to "x" as we can't generate anything useful here. - Authentication can be done using the pam_ntdom module. */ + Authentication can be done using the pam_winbind module. */ safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1); @@ -99,7 +96,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) WINBIND_USERINFO user_info; DOM_SID user_sid; NTSTATUS status; - fstring name_domain, name_user, name; + fstring name_domain, name_user; enum SID_NAME_USE name_type; struct winbindd_domain *domain; TALLOC_CTX *mem_ctx; @@ -110,19 +107,17 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) /* Parse domain and username */ if (!parse_domain_user(state->request.data.username, name_domain, - name_user)) + name_user)) return WINBINDD_ERROR; if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(5, ("no such domain: %s\n", name_domain)); return WINBINDD_ERROR; } - - slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user); /* Get rid and name type from name */ - if (!winbindd_lookup_sid_by_name(domain, name, &user_sid, &name_type)) { + if (!winbindd_lookup_sid_by_name(domain, name_domain, name_user, &user_sid, &name_type)) { DEBUG(1, ("user '%s' does not exist\n", name_user)); return WINBINDD_ERROR; } @@ -137,8 +132,8 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) from the winbind_lookup_by_name() call and use it in a winbind_lookup_userinfo() */ - if (!(mem_ctx = talloc_init_named("winbindd_getpwnam(%s)", - name_user))) { + if (!(mem_ctx = talloc_init_named("winbindd_getpwnam([%s]\\[%s])", + name_domain, name_user))) { DEBUG(1, ("out of memory\n")); return WINBINDD_ERROR; } @@ -149,14 +144,14 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) &user_info); if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("error getting user info for user '%s'\n", - name_user)); + DEBUG(1, ("error getting user info for user '[%s]\\[%s]'\n", + name_domain, name_user)); talloc_destroy(mem_ctx); return WINBINDD_ERROR; } /* Now take all this information and fill in a passwd structure */ - if (!winbindd_fill_pwent(name_domain, state->request.data.username, + if (!winbindd_fill_pwent(name_domain, name_user, user_rid, user_info.group_rid, user_info.full_name, &state->response.data.pw)) { @@ -176,6 +171,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) DOM_SID user_sid; struct winbindd_domain *domain; uint32 user_rid; + fstring dom_name; fstring user_name; enum SID_NAME_USE name_type; WINBIND_USERINFO user_info; @@ -206,7 +202,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) sid_copy(&user_sid, &domain->sid); sid_append_rid(&user_sid, user_rid); - if (!winbindd_lookup_name_by_sid(&user_sid, user_name, &name_type)) { + if (!winbindd_lookup_name_by_sid(&user_sid, dom_name, user_name, &name_type)) { fstring temp; sid_to_string(temp, &user_sid); @@ -214,11 +210,6 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - if (strcmp("\\", lp_winbind_separator())) - string_sub(user_name, "\\", lp_winbind_separator(), - sizeof(fstring)); - strip_domain_name_if_needed(&user_name); - /* Get some user info */ if (!(mem_ctx = talloc_init_named("winbind_getpwuid(%d)", @@ -234,6 +225,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("error getting user info for user '%s'\n", user_name)); + talloc_destroy(mem_ctx); return WINBINDD_ERROR; } @@ -241,6 +233,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) if (!winbindd_idmap_get_gid_from_rid(domain->name, user_info.group_rid, &gid)) { DEBUG(1, ("error getting group id for user %s\n", user_name)); + talloc_destroy(mem_ctx); return WINBINDD_ERROR; } @@ -248,6 +241,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) if (!winbindd_fill_pwent(domain->name, user_name, user_rid, user_info.group_rid, user_info.full_name, &state->response.data.pw)) { + talloc_destroy(mem_ctx); return WINBINDD_ERROR; } @@ -431,7 +425,6 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) struct getent_state *ent; struct winbindd_pw *user_list; int num_users, user_list_ndx = 0, i; - char *sep; DEBUG(3, ("[%5d]: getpwent\n", state->pid)); @@ -452,7 +445,6 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) sizeof(struct winbindd_pw)); user_list = (struct winbindd_pw *)state->response.extra_data; - sep = lp_winbind_separator(); if (!(ent = state->getpwent_state)) return WINBINDD_ERROR; @@ -501,12 +493,9 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) /* Lookup user info */ - fill_domain_username(domain_user_name, ent->domain_name, - name_list[ent->sam_entry_index].name); - result = winbindd_fill_pwent( ent->domain_name, - domain_user_name, + name_list[ent->sam_entry_index].name, name_list[ent->sam_entry_index].user_rid, name_list[ent->sam_entry_index].group_rid, name_list[ent->sam_entry_index].gecos, diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 640b581ce3..ad362ff8a6 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -216,6 +216,7 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) /* Lookup a sid in a domain from a name */ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, + const char *dom_name, const char *name, DOM_SID *sid, enum SID_NAME_USE *type) { @@ -244,6 +245,8 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, * * @param name On success, set to the name corresponding to @p sid. * + * @param dom_name On success, set to the 'domain name' corresponding to @p sid. + * * @param type On success, contains the type of name: alias, group or * user. * @@ -251,6 +254,7 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, * are set, otherwise False. **/ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, + fstring dom_name, fstring name, enum SID_NAME_USE *type) { @@ -277,6 +281,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, /* Return name and type if successful */ if ((rv = NT_STATUS_IS_OK(result))) { + fstrcpy(dom_name, domain->name); fstrcpy(name, names); } else { *type = SID_NAME_UNKNOWN; @@ -369,28 +374,6 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) return True; } -/* - Strip domain name if it is same as default domain name and - winbind use default domain = true - - it assumes that name is actually fstring so that memory management - isn't needed. -*/ -void strip_domain_name_if_needed(fstring *name) -{ - if(lp_winbind_use_default_domain()) { - char *sep = lp_winbind_separator(); - char *new_name = strchr(*name, *sep); - if(new_name) { - *new_name = 0; - if (!strcmp(global_myworkgroup, *name)) { - new_name++; - safe_strcpy(*name, new_name, sizeof(fstring)); - } else *new_name = *sep; - } - } -} - /* Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and 'winbind separator' options. diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 12b0ec2e16..04acc75d7e 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -1045,7 +1045,7 @@ makes a structure. ********************************************************************/ void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l, - POLICY_HND *hnd, int num_names, const char **names) + POLICY_HND *hnd, int num_names, const char **dom_names, const char **names) { int i; @@ -1072,10 +1072,20 @@ void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l, for (i = 0; i < num_names; i++) { const char *name = names[i]; - int len = strlen(name); + const char *dom_name = dom_names[i]; + char *full_name; + int len; + + full_name = talloc_asprintf(mem_ctx, "%s\\%s", dom_name, name); + if (!full_name) { + DEBUG(0, ("init_q_lookup_names(): out of memory doing talloc_asprintf\n")); + return; + } + + len = strlen(full_name); init_uni_hdr(&q_l->hdr_name[i], len); - init_unistr2(&q_l->uni_name[i], name, len); + init_unistr2(&q_l->uni_name[i], full_name, len); } } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index c17e22ada2..6ac71298fa 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -656,12 +656,12 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM SAFE_FREE(map); } else if (sid_equal(sid, &global_sam_sid) && !lp_hide_local_users()) { - char *sep; struct sys_grent *glist; struct sys_grent *grp; struct passwd *pw; + gid_t winbind_gid_low, winbind_gid_high; - sep = lp_winbind_separator(); + lp_winbind_gid(&winbind_gid_low, &winbind_gid_high); /* local aliases */ /* we return the UNIX groups here. This seems to be the right */ @@ -691,7 +691,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM continue; /* Don't return winbind groups as they are not local! */ - if (strchr_m(smap.nt_name, *sep) != NULL) { + if ((grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) { DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name )); continue; } diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index 14caf89e2f..1788512db7 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -82,7 +82,6 @@ rid_name domain_group_rids[] = NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, uint32 **prids, DOM_SID *q_sid) { SAM_ACCOUNT *sam_pass=NULL; - char *sep; struct sys_grent *glist; struct sys_grent *grp; int i, num, cur_rid=0; @@ -93,6 +92,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui fstring str_domsid, str_qsid; uint32 rid,grid; uint32 *rids=NULL, *new_rids=NULL; + gid_t winbind_gid_low, winbind_gid_high; BOOL ret; /* @@ -109,7 +109,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui *prids=NULL; *numgroups=0; - sep = lp_winbind_separator(); + lp_winbind_gid(&winbind_gid_low, &winbind_gid_high); DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n", @@ -158,7 +158,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui } /* Don't return winbind groups as they are not local! */ - if (strchr_m(map.nt_name, *sep) != NULL) { + if ((grp->gr_gid >= winbind_gid_low) && (grp->gr_gid <= winbind_gid_high)) { DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name)); continue; } @@ -227,7 +227,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui } /* Don't return winbind groups as they are not local! */ - if (strchr_m(map.nt_name, *sep) != NULL) { + if ((gid >= winbind_gid_low) && (gid <= winbind_gid_high)) { DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name )); goto done; } @@ -271,7 +271,7 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA uint32 grid; uint32 tmp_rid; - *numgroups=0; + *numgroups= 0; fstrcpy(user_name, pdb_get_username(sam_pass)); grid=pdb_get_group_rid(sam_pass); diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 528987d3e2..f6d0569de9 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -80,6 +80,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli, DOM_SID *sids; uint32 *types; int num_names, i; + fstring name, domain; if (argc == 1) { printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]); @@ -95,8 +96,10 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli, /* Lookup the names */ + split_domain_name(argv[1], domain, name); + result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1, - (const char **)&argv[1], &sids, + (const char**)&domain, (const char**)&name, &sids, &types, &num_names); if (!NT_STATUS_IS_OK(result)) @@ -124,6 +127,7 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; + char **domains; char **names; uint32 *types; int num_names, i; @@ -155,7 +159,7 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Lookup the SIDs */ result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, - &names, &types, &num_names); + &domains, &names, &types, &num_names); if (!NT_STATUS_IS_OK(result)) goto done; @@ -166,8 +170,9 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, fstring sid_str; sid_to_string(sid_str, &sids[i]); - printf("%s %s (%d)\n", sid_str, names[i] ? names[i] : - "*unknown*", types[i]); + printf("%s [%s]\\[%s] (%d)\n", sid_str, + domains[i] ? domains[i] : "*unknown*", + names[i] ? names[i] : "*unknown*", types[i]); } done: diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8df08a0e72..d9cedaf7b5 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -453,7 +453,7 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) /* If we are looking up a domain user, make sure it is for the local machine only */ - if (strchr_m(name, sep[0]) || strchr_m(name, '\\')) { + if (strchr_m(name, sep[0]) || strchr_m(name, '\\') || lp_winbind_use_default_domain()) { fstring domain, username; split_domain_name(name, domain, username); diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 94eada5c3d..d62907e14b 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -106,6 +106,7 @@ static BOOL cacls_open_policy_hnd(void) /* convert a SID to a string, either numeric or username/group */ static void SidToString(fstring str, DOM_SID *sid) { + char **domains = NULL; char **names = NULL; uint32 *types = NULL; int num_names; @@ -117,15 +118,19 @@ static void SidToString(fstring str, DOM_SID *sid) /* Ask LSA to convert the sid to a name */ if (!cacls_open_policy_hnd() || - !NT_STATUS_IS_OK(cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, sid, &names, + !NT_STATUS_IS_OK(cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, + &pol, 1, sid, &domains, &names, &types, &num_names)) || - !names || !names[0]) { + !domains || !domains[0] || !names || !names[0]) { return; } /* Converted OK */ + + slprintf(str, sizeof(fstring) - 1, "%s%s%s", + domains[0], lp_winbind_separator(), + names[0]); - fstrcpy(str, names[0]); } /* convert a string to a SID, either numeric or username/group */ @@ -135,14 +140,18 @@ static BOOL StringToSid(DOM_SID *sid, const char *str) DOM_SID *sids = NULL; int num_sids; BOOL result = True; + fstring name, domain; if (strncmp(str, "S-", 2) == 0) { return string_to_sid(sid, str); } + split_domain_name(str, domain, name); + if (!cacls_open_policy_hnd() || - !NT_STATUS_IS_OK(cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, &str, - &sids, &types, &num_sids))) { + !NT_STATUS_IS_OK(cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, + (const char **)&domain, (const char **)&name, + &sids, &types, &num_sids))) { result = False; goto done; } |