diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c index d43fc3042b5..42660fa75d5 100644 --- a/source3/winbindd/winbindd_getgrnam.c +++ b/source3/winbindd/winbindd_getgrnam.c @@ -76,14 +76,30 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, state->name_domain, state->name_group); if (!ok) { - DBG_INFO("Could not parse domain user: %s\n", tmp); + DBG_INFO("Could not parse domain of group: %s\n", tmp); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + /* ensure it's okay to proceed calling wb_lookupname_send */ + ok = lookup_local(tmp, + state->name_namespace, + state->name_domain, + state->name_group); + if (!ok) { + DEBUG(5, ("Not processing group: %s\n", + tmp)); + DEBUG(10, ("user: %s(%s), namespace: %s, domain: %s\n", + tmp, + state->name_group, + state->name_namespace, + state->name_domain)); + tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); + return tevent_req_post(req, ev); + } + /* if no domain or our local domain and no local tdb group, default to * our local domain for aliases */ - if ( !*(state->name_domain) || strequal(state->name_domain, get_global_sam_name()) ) { fstrcpy(state->name_domain, get_global_sam_name()); diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c index 63206c28134..d7edd35d0dd 100644 --- a/source3/winbindd/winbindd_getgroups.c +++ b/source3/winbindd/winbindd_getgroups.c @@ -80,11 +80,28 @@ struct tevent_req *winbindd_getgroups_send(TALLOC_CTX *mem_ctx, state->domname, state->username); if (!ok) { - DEBUG(5, ("Could not parse domain user: %s\n", domuser)); + DEBUG(5, ("Could not parse domain of user: %s\n", domuser)); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + /* ensure it's okay to proceed calling wb_lookupname_send */ + ok = lookup_local(domuser, + state->namespace, + state->domname, + state->username); + if (!ok) { + DEBUG(5, ("Not processing groups of user: %s\n", + domuser)); + DEBUG(10, ("user: %s(%s), namespace: %s, domain: %s\n", + domuser, + state->username, + state->namespace, + state->domname)); + tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); + return tevent_req_post(req, ev); + } + subreq = wb_lookupname_send(state, ev, state->namespace, state->domname, diff --git a/source3/winbindd/winbindd_getpwnam.c b/source3/winbindd/winbindd_getpwnam.c index 6f49ea9b356..f1292154f2f 100644 --- a/source3/winbindd/winbindd_getpwnam.c +++ b/source3/winbindd/winbindd_getpwnam.c @@ -76,11 +76,28 @@ struct tevent_req *winbindd_getpwnam_send(TALLOC_CTX *mem_ctx, state->domname, state->username); if (!ok) { - DEBUG(5, ("Could not parse domain user: %s\n", domuser)); + DEBUG(5, ("Could not parse domain of user: %s\n", domuser)); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + /* ensure it's okay to proceed calling wb_lookupname_send */ + ok = lookup_local(domuser, + state->namespace, + state->domname, + state->username); + if (!ok) { + DEBUG(5, ("Not processing user: %s\n", + domuser)); + DEBUG(10, ("user: %s(%s), namespace: %s, domain: %s\n", + domuser, + state->username, + state->namespace, + state->domname)); + tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); + return tevent_req_post(req, ev); + } + subreq = wb_lookupname_send(state, ev, state->namespace, state->domname, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 2a829b0171a..bc113652059 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -478,6 +478,10 @@ struct winbindd_domain *find_our_domain(void); struct winbindd_domain *find_default_route_domain(void); struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid); struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name); +bool lookup_local(const char *domuser, + const char *namespace, + const char *domain, + const char *user); bool parse_domain_user(const char *domuser, fstring namespace, fstring domain, diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 91a2f6ef197..3db54a1e0cd 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1561,6 +1561,31 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) return find_our_domain(); } +/* This function was setup to avoid winbind to lookup names it is not + * authorized for and won't succeed at all */ +bool lookup_local(const char *domuser, + const char *namespace, + const char *domain, + const char *user) +{ + char *p = NULL; + /* Return False when all these match: + * - domain is empty + * - domuser and user are equal (maybe silly, but to be certain) + * - user is not in upn format + * - server is a domain member + * - winbind_use_default_domain is set to no + */ + if (!*(domain) && + strequal(domuser, user) && + (p = strchr(user, '@')) == NULL && + lp_server_role() == ROLE_DOMAIN_MEMBER && + !lp_winbind_use_default_domain()) { + return False; + } + return True; +} + /* Is this a domain which we may assume no DOMAIN\ prefix? */ static bool assume_domain(const char *domain) @@ -1623,7 +1648,6 @@ bool parse_domain_user(const char *domuser, fstrcpy(namespace, lp_netbios_name()); } } - return strupper_m(domain); } diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c index d43fc3042b5..42660fa75d5 100644 --- a/source3/winbindd/winbindd_getgrnam.c +++ b/source3/winbindd/winbindd_getgrnam.c @@ -76,14 +76,30 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, state->name_domain, state->name_group); if (!ok) { - DBG_INFO("Could not parse domain user: %s\n", tmp); + DBG_INFO("Could not parse domain of group: %s\n", tmp); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + /* ensure it's okay to proceed calling wb_lookupname_send */ + ok = lookup_local(tmp, + state->name_namespace, + state->name_domain, + state->name_group); + if (!ok) { + DEBUG(5, ("Not processing group: %s\n", + tmp)); + DEBUG(10, ("user: %s(%s), namespace: %s, domain: %s\n", + tmp, + state->name_group, + state->name_namespace, + state->name_domain)); + tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); + return tevent_req_post(req, ev); + } + /* if no domain or our local domain and no local tdb group, default to * our local domain for aliases */ - if ( !*(state->name_domain) || strequal(state->name_domain, get_global_sam_name()) ) { fstrcpy(state->name_domain, get_global_sam_name()); diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c index 63206c28134..d7edd35d0dd 100644 --- a/source3/winbindd/winbindd_getgroups.c +++ b/source3/winbindd/winbindd_getgroups.c @@ -80,11 +80,28 @@ struct tevent_req *winbindd_getgroups_send(TALLOC_CTX *mem_ctx, state->domname, state->username); if (!ok) { - DEBUG(5, ("Could not parse domain user: %s\n", domuser)); + DEBUG(5, ("Could not parse domain of user: %s\n", domuser)); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + /* ensure it's okay to proceed calling wb_lookupname_send */ + ok = lookup_local(domuser, + state->namespace, + state->domname, + state->username); + if (!ok) { + DEBUG(5, ("Not processing groups of user: %s\n", + domuser)); + DEBUG(10, ("user: %s(%s), namespace: %s, domain: %s\n", + domuser, + state->username, + state->namespace, + state->domname)); + tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); + return tevent_req_post(req, ev); + } + subreq = wb_lookupname_send(state, ev, state->namespace, state->domname, diff --git a/source3/winbindd/winbindd_getpwnam.c b/source3/winbindd/winbindd_getpwnam.c index 6f49ea9b356..f1292154f2f 100644 --- a/source3/winbindd/winbindd_getpwnam.c +++ b/source3/winbindd/winbindd_getpwnam.c @@ -76,11 +76,28 @@ struct tevent_req *winbindd_getpwnam_send(TALLOC_CTX *mem_ctx, state->domname, state->username); if (!ok) { - DEBUG(5, ("Could not parse domain user: %s\n", domuser)); + DEBUG(5, ("Could not parse domain of user: %s\n", domuser)); tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return tevent_req_post(req, ev); } + /* ensure it's okay to proceed calling wb_lookupname_send */ + ok = lookup_local(domuser, + state->namespace, + state->domname, + state->username); + if (!ok) { + DEBUG(5, ("Not processing user: %s\n", + domuser)); + DEBUG(10, ("user: %s(%s), namespace: %s, domain: %s\n", + domuser, + state->username, + state->namespace, + state->domname)); + tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); + return tevent_req_post(req, ev); + } + subreq = wb_lookupname_send(state, ev, state->namespace, state->domname, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 2a829b0171a..bc113652059 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -478,6 +478,10 @@ struct winbindd_domain *find_our_domain(void); struct winbindd_domain *find_default_route_domain(void); struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid); struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name); +bool lookup_local(const char *domuser, + const char *namespace, + const char *domain, + const char *user); bool parse_domain_user(const char *domuser, fstring namespace, fstring domain, diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 91a2f6ef197..3db54a1e0cd 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1561,6 +1561,31 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) return find_our_domain(); } +/* This function was setup to avoid winbind to lookup names it is not + * authorized for and won't succeed at all */ +bool lookup_local(const char *domuser, + const char *namespace, + const char *domain, + const char *user) +{ + char *p = NULL; + /* Return False when all these match: + * - domain is empty + * - domuser and user are equal (maybe silly, but to be certain) + * - user is not in upn format + * - server is a domain member + * - winbind_use_default_domain is set to no + */ + if (!*(domain) && + strequal(domuser, user) && + (p = strchr(user, '@')) == NULL && + lp_server_role() == ROLE_DOMAIN_MEMBER && + !lp_winbind_use_default_domain()) { + return False; + } + return True; +} + /* Is this a domain which we may assume no DOMAIN\ prefix? */ static bool assume_domain(const char *domain) @@ -1623,7 +1648,6 @@ bool parse_domain_user(const char *domuser, fstrcpy(namespace, lp_netbios_name()); } } - return strupper_m(domain); }