1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

winbindd: Update the calls to ws_name_XX() to reflect API changes.

* Ensures that all points an which a name is received or returned
  to/from a client passes through the name aliases layer (users
  and groups).
This commit is contained in:
Gerald (Jerry) Carter 2008-09-15 15:50:15 -05:00 committed by Jeremy Allison
parent d6de32db2f
commit 544cd1b4b9
4 changed files with 314 additions and 46 deletions

View File

@ -179,12 +179,32 @@ static bool fill_passdb_alias_grmem(struct winbindd_domain *domain,
/* Fill a grent structure from various other information */
static bool fill_grent(struct winbindd_gr *gr, const char *dom_name,
const char *gr_name, gid_t unix_gid)
static bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr,
const char *dom_name,
char *gr_name, gid_t unix_gid)
{
fstring full_group_name;
char *mapped_name = NULL;
struct winbindd_domain *domain = find_domain_from_name_noinit(dom_name);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
fill_domain_username( full_group_name, dom_name, gr_name, True );
nt_status = normalize_name_map(mem_ctx, domain, gr_name,
&mapped_name);
/* Basic whitespace replacement */
if (NT_STATUS_IS_OK(nt_status)) {
fill_domain_username(full_group_name, dom_name,
mapped_name, true);
}
/* Mapped to an aliase */
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
fstrcpy(full_group_name, mapped_name);
}
/* no change */
else {
fill_domain_username( full_group_name, dom_name,
gr_name, True );
}
gr->gr_gid = unix_gid;
@ -280,7 +300,10 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
char *domainname = NULL;
char *username = NULL;
fstring name;
char *mapped_name = NULL;
enum lsa_SidType type;
struct winbindd_domain *target_domain = NULL;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
DEBUG(10,("fill_grent_mem_domain_users: "
"sid %s in 'Domain Users' in domain %s\n",
@ -300,7 +323,24 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
nt_errstr(status)));
return False;
}
fill_domain_username(name, domain->name, username, True);
target_domain = find_domain_from_name_noinit(domainname);
name_map_status = normalize_name_map(mem_ctx, target_domain,
username, &mapped_name);
/* Basic whitespace replacement */
if (NT_STATUS_IS_OK(name_map_status)) {
fill_domain_username(name, domainname, mapped_name, true);
}
/* Mapped to an alias */
else if (NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) {
fstrcpy(name, mapped_name);
}
/* no mapping done...use original name */
else {
fill_domain_username(name, domainname, username, true);
}
len = strlen(name);
buf_len = len + 1;
if (!(buf = (char *)SMB_MALLOC(buf_len))) {
@ -552,6 +592,7 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
uint32 n_members = 0;
char **members = NULL;
NTSTATUS nt_status;
int j;
nt_status = expand_groups( mem_ctx, domain,
glist, n_glist,
@ -562,13 +603,45 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
goto done;
}
/* Add new group members to list */
/* Add new group members to list. Pass through the
alias mapping function */
nt_status = add_names_to_list( mem_ctx, &names, &num_names,
members, n_members );
if ( !NT_STATUS_IS_OK(nt_status) ) {
result = False;
goto done;
for (j=0; j<n_members; j++) {
fstring name_domain, name_acct;
fstring qualified_name;
char *mapped_name = NULL;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
struct winbindd_domain *target_domain = NULL;
if (parse_domain_user(members[j], name_domain, name_acct)) {
target_domain = find_domain_from_name_noinit(name_domain);
/* NOW WHAT ? */
}
if (!target_domain) {
target_domain = domain;
}
name_map_status = normalize_name_map(members, target_domain,
name_acct, &mapped_name);
/* Basic whitespace replacement */
if (NT_STATUS_IS_OK(name_map_status)) {
fill_domain_username(qualified_name, name_domain,
mapped_name, true);
mapped_name = qualified_name;
}
/* no mapping at all */
else if (!NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) {
mapped_name = members[j];
}
nt_status = add_names_to_list( mem_ctx, &names,
&num_names,
&mapped_name, 1);
if ( !NT_STATUS_IS_OK(nt_status) ) {
result = False;
goto done;
}
}
TALLOC_FREE( members );
@ -679,6 +752,7 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
struct winbindd_domain *domain;
fstring name_domain, name_group;
char *tmp;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
@ -686,11 +760,20 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid,
state->request.data.groupname));
nt_status = normalize_name_unmap(state->mem_ctx,
state->request.data.groupname,
&tmp);
/* If we didn't map anything in the above call, just reset the
tmp pointer to the original string */
if (!NT_STATUS_IS_OK(nt_status) &&
!NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
{
tmp = state->request.data.groupname;
}
/* Parse domain and groupname */
memset(name_group, 0, sizeof(fstring));
tmp = state->request.data.groupname;
memset(name_group, 0, sizeof(name_group));
name_domain[0] = '\0';
name_group[0] = '\0';
@ -723,7 +806,7 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
/* Get rid and name type from name */
ws_name_replace( name_group, WB_REPLACE_CHAR );
fstrcpy( name_group, tmp );
winbindd_lookupname_async( state->mem_ctx, domain->name, name_group,
getgrnam_recv, WINBINDD_GETGRNAM, state );
@ -771,7 +854,8 @@ static void getgrsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
return;
}
if (!fill_grent(&s->state->response.data.gr, dom_name, group_name, gid) ||
if (!fill_grent(s->state->mem_ctx, &s->state->response.data.gr,
dom_name, group_name, gid) ||
!fill_grent_mem(domain, s->state, &s->group_sid, s->group_type,
&num_gr_mem, &gr_mem, &gr_mem_len))
{
@ -796,6 +880,9 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
enum lsa_SidType name_type )
{
struct getgrsid_state *s = (struct getgrsid_state *)private_data;
char *mapped_name = NULL;
fstring raw_name;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
if (!success) {
DEBUG(5,("getgrsid_lookupsid_recv: lookupsid failed!\n"));
@ -814,15 +901,39 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
dom_name, name, name_type));
request_error(s->state);
return;
}
}
if ( (s->group_name = talloc_asprintf( s->state->mem_ctx,
"%s%c%s",
dom_name,
*lp_winbind_separator(),
name)) == NULL )
{
DEBUG(1, ("getgrsid_lookupsid_recv: talloc_asprintf() Failed!\n"));
/* normalize the name and ensure that we have the DOM\name
coming out of here */
fstrcpy(raw_name, name);
nt_status = normalize_name_unmap(s->state->mem_ctx, raw_name,
&mapped_name);
/* basiuc whitespace reversal */
if (NT_STATUS_IS_OK(nt_status)) {
s->group_name = talloc_asprintf(s->state->mem_ctx,
"%s%c%s",
dom_name,
*lp_winbind_separator(),
mapped_name);
}
/* mapped from alias */
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
s->group_name = mapped_name;
}
/* no mapping at all. use original string */
else {
s->group_name = talloc_asprintf(s->state->mem_ctx,
"%s%c%s",
dom_name,
*lp_winbind_separator(),
raw_name);
}
if (s->group_name == NULL) {
DEBUG(1, ("getgrsid_lookupsid_recv: group_name is NULL!\n"));
request_error(s->state);
return;
}
@ -831,10 +942,10 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
winbindd_sid2gid_async(s->state->mem_ctx, &s->group_sid,
getgrsid_sid2gid_recv, s);
}
}
static void winbindd_getgrsid( struct winbindd_cli_state *state, const DOM_SID group_sid )
{
{
struct getgrsid_state *s;
if ( (s = TALLOC_ZERO_P(state->mem_ctx, struct getgrsid_state)) == NULL ) {
@ -1261,7 +1372,7 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
fill_domain_username(domain_group_name, ent->domain_name,
name_list[ent->sam_entry_index].acct_name, True);
result = fill_grent(&group_list[group_list_ndx],
result = fill_grent(state->mem_ctx, &group_list[group_list_ndx],
ent->domain_name,
name_list[ent->sam_entry_index].acct_name,
group_gid);
@ -1413,6 +1524,8 @@ static void getgroups_sid2gid_recv(void *private_data, bool success, gid_t gid);
void winbindd_getgroups(struct winbindd_cli_state *state)
{
struct getgroups_state *s;
char *real_name = NULL;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.username
@ -1432,13 +1545,22 @@ void winbindd_getgroups(struct winbindd_cli_state *state)
s->state = state;
ws_name_return( state->request.data.username, WB_REPLACE_CHAR );
nt_status = normalize_name_unmap(state->mem_ctx,
state->request.data.username,
&real_name);
if (!parse_domain_user_talloc(state->mem_ctx,
state->request.data.username,
/* Reset the real_name pointer if we didn't do anything
productive in the above call */
if (!NT_STATUS_IS_OK(nt_status) &&
!NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
{
real_name = state->request.data.username;
}
if (!parse_domain_user_talloc(state->mem_ctx, real_name,
&s->domname, &s->username)) {
DEBUG(5, ("Could not parse domain user: %s\n",
state->request.data.username));
real_name));
/* error out if we do not have nested group support */

View File

@ -811,7 +811,9 @@ void winbindd_pam_auth(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
fstring name_domain, name_user;
char *mapped_user = NULL;
NTSTATUS result;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.auth.user
@ -831,10 +833,20 @@ void winbindd_pam_auth(struct winbindd_cli_state *state)
/* Parse domain and username */
ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR );
name_map_status = normalize_name_unmap(state->mem_ctx,
state->request.data.auth.user,
&mapped_user);
if (!canonicalize_username(state->request.data.auth.user,
name_domain, name_user)) {
/* If the name normalization didnt' actually do anything,
just use the original name */
if (!NT_STATUS_IS_OK(name_map_status) &&
!NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
{
mapped_user = state->request.data.auth.user;
}
if (!canonicalize_username(mapped_user, name_domain, name_user)) {
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
@ -1447,7 +1459,10 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
NTSTATUS result = NT_STATUS_LOGON_FAILURE;
NTSTATUS krb5_result = NT_STATUS_OK;
fstring name_domain, name_user;
char *mapped_user;
fstring domain_user;
struct netr_SamInfo3 *info3 = NULL;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
/* Ensure null termination */
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
@ -1465,9 +1480,26 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
/* Parse domain and username */
ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR );
name_map_status = normalize_name_unmap(state->mem_ctx,
state->request.data.auth.user,
&mapped_user);
parse_domain_user(state->request.data.auth.user, name_domain, name_user);
/* If the name normalization didnt' actually do anything,
just use the original name */
if (!NT_STATUS_IS_OK(name_map_status) &&
!NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
{
mapped_user = state->request.data.auth.user;
}
parse_domain_user(mapped_user, name_domain, name_user);
if ( mapped_user != state->request.data.auth.user ) {
fstr_sprintf( domain_user, "%s\\%s", name_domain, name_user );
safe_strcpy( state->request.data.auth.user, domain_user,
sizeof(state->request.data.auth.user)-1 );
}
if (domain->online == false) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
@ -1970,14 +2002,30 @@ done:
void winbindd_pam_chauthtok(struct winbindd_cli_state *state)
{
fstring domain, user;
char *mapped_user;
struct winbindd_domain *contact_domain;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
state->request.data.chauthtok.user));
/* Setup crap */
ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR );
nt_status = normalize_name_unmap(state->mem_ctx,
state->request.data.chauthtok.user,
&mapped_user);
/* Update the chauthtok name if we did any mapping */
if (NT_STATUS_IS_OK(nt_status) ||
NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
{
fstrcpy(state->request.data.chauthtok.user, mapped_user);
}
/* Must pass in state->...chauthtok.user because
canonicalize_username() assumes an fstring(). Since
we have already copied it (if necessary), this is ok. */
if (!canonicalize_username(state->request.data.chauthtok.user, domain, user)) {
set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER);

View File

@ -279,6 +279,8 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
char *full_name = NULL;
struct rpc_pipe_client *cli;
POLICY_HND lsa_policy;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
if (name == NULL || *name=='\0') {
full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
@ -294,9 +296,19 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
ws_name_return( full_name, WB_REPLACE_CHAR );
name_map_status = normalize_name_unmap(mem_ctx, full_name,
&mapped_name);
DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
/* Reset the full_name pointer if we mapped anytthing */
if (NT_STATUS_IS_OK(name_map_status) ||
NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
{
full_name = mapped_name;
}
DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
full_name?full_name:"", domain_name ));
result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
if (!NT_STATUS_IS_OK(result))
@ -332,6 +344,8 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
NTSTATUS result;
struct rpc_pipe_client *cli;
POLICY_HND lsa_policy;
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
domain->name ));
@ -356,9 +370,17 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
*domain_name = domains[0];
*name = names[0];
ws_name_replace( *name, WB_REPLACE_CHAR );
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
name_map_status = normalize_name_map(mem_ctx, domain, *name,
&mapped_name);
if (NT_STATUS_IS_OK(name_map_status) ||
NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
{
*name = mapped_name;
DEBUG(5,("returning mapped name -- %s\n", *name));
}
return NT_STATUS_OK;
}
@ -411,8 +433,20 @@ NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
ret_names = *names;
for (i=0; i<num_rids; i++) {
NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
char *mapped_name = NULL;
if ((*types)[i] != SID_NAME_UNKNOWN) {
ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
name_map_status = normalize_name_map(mem_ctx,
domain,
ret_names[i],
&mapped_name);
if (NT_STATUS_IS_OK(name_map_status) ||
NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
{
ret_names[i] = mapped_name;
}
*domain_name = domains[i];
}
}

View File

@ -67,12 +67,15 @@ static bool fillup_pw_field(const char *lp_template,
}
/* Fill a pwent structure with information we have obtained */
static bool winbindd_fill_pwent(char *dom_name, char *user_name,
static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name,
DOM_SID *user_sid, DOM_SID *group_sid,
char *full_name, char *homedir, char *shell,
struct winbindd_pw *pw)
{
fstring output_username;
char *mapped_name = NULL;
struct winbindd_domain *domain = NULL;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
if (!pw || !dom_name || !user_name)
return False;
@ -99,7 +102,28 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name,
/* Username */
fill_domain_username(output_username, dom_name, user_name, True);
domain = find_domain_from_name_noinit(dom_name);
if (domain) {
nt_status = normalize_name_map(ctx, domain, user_name,
&mapped_name);
} else {
DEBUG(5,("winbindd_fill_pwent: Failed to find domain for %s. "
"Disabling name alias support\n", dom_name));
nt_status = NT_STATUS_NO_SUCH_DOMAIN;
}
/* Basic removal of whitespace */
if (NT_STATUS_IS_OK(nt_status)) {
fill_domain_username(output_username, dom_name, mapped_name, True);
}
/* Complete name replacement */
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
fstrcpy(output_username, mapped_name);
}
/* No change at all */
else {
fill_domain_username(output_username, dom_name, user_name, True);
}
safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
@ -179,6 +203,7 @@ struct getpwsid_state {
uid_t uid;
DOM_SID group_sid;
gid_t gid;
bool username_mapped;
};
static void getpwsid_queryuser_recv(void *private_data, bool success,
@ -231,6 +256,8 @@ static void getpwsid_queryuser_recv(void *private_data, bool success,
fstring username;
struct getpwsid_state *s =
talloc_get_type_abort(private_data, struct getpwsid_state);
char *mapped_name;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
if (!success) {
DEBUG(5, ("Could not query domain %s SID %s\n",
@ -272,7 +299,23 @@ static void getpwsid_queryuser_recv(void *private_data, bool success,
strlower_m( username );
s->username = talloc_strdup(s->state->mem_ctx, username);
ws_name_replace( s->username, WB_REPLACE_CHAR );
nt_status = normalize_name_map(s->state->mem_ctx, s->domain,
s->username, &mapped_name);
/* Basic removal of whitespace */
if (NT_STATUS_IS_OK(nt_status)) {
s->username = mapped_name;
s->username_mapped = false;
}
/* Complete name replacement */
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) {
s->username = mapped_name;
s->username_mapped = true;
}
/* No change at all */
else {
s->username_mapped = false;
}
s->fullname = talloc_strdup(s->state->mem_ctx, full_name);
s->homedir = talloc_strdup(s->state->mem_ctx, homedir);
@ -330,8 +373,16 @@ static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid)
pw = &s->state->response.data.pw;
pw->pw_uid = s->uid;
pw->pw_gid = s->gid;
/* allow username to be overridden by the alias mapping */
if ( s->username_mapped ) {
fstrcpy( output_username, s->username );
} else {
fill_domain_username(output_username, s->domain->name,
s->username, True);
}
safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1);
@ -370,8 +421,10 @@ void winbindd_getpwnam(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
fstring domname, username;
char *mapped_user = NULL;
char *domuser;
size_t dusize;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
domuser = state->request.data.username;
dusize = sizeof(state->request.data.username);
@ -383,9 +436,19 @@ void winbindd_getpwnam(struct winbindd_cli_state *state)
(unsigned long)state->pid,
domuser));
ws_name_return(domuser, WB_REPLACE_CHAR);
nt_status = normalize_name_unmap(state->mem_ctx, domuser,
&mapped_user);
if (!parse_domain_user(domuser, domname, username)) {
/* If we could not convert from an aliased name or a
normalized name, then just use the original name */
if (!NT_STATUS_IS_OK(nt_status) &&
!NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
{
mapped_user = domuser;
}
if (!parse_domain_user(mapped_user, domname, username)) {
DEBUG(5, ("Could not parse domain user: %s\n", domuser));
request_error(state);
return;
@ -743,6 +806,7 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
/* Lookup user info */
result = winbindd_fill_pwent(
state->mem_ctx,
ent->domain_name,
name_list[ent->sam_entry_index].name,
&name_list[ent->sam_entry_index].user_sid,