summaryrefslogtreecommitdiff
path: root/source/winbindd/winbindd_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/winbindd/winbindd_user.c')
-rw-r--r--source/winbindd/winbindd_user.c351
1 files changed, 144 insertions, 207 deletions
diff --git a/source/winbindd/winbindd_user.c b/source/winbindd/winbindd_user.c
index e5d0a22a73..19feec38db 100644
--- a/source/winbindd/winbindd_user.c
+++ b/source/winbindd/winbindd_user.c
@@ -27,12 +27,12 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
-static bool fillup_pw_field(const char *lp_template,
- const char *username,
+static bool fillup_pw_field(const char *lp_template,
+ const char *username,
const char *domname,
uid_t uid,
gid_t gid,
- const char *in,
+ const char *in,
fstring out)
{
char *templ;
@@ -40,59 +40,54 @@ static bool fillup_pw_field(const char *lp_template,
if (out == NULL)
return False;
- /* The substitution of %U and %D in the 'template
+ /* The substitution of %U and %D in the 'template
homedir' is done by talloc_sub_specified() below.
If we have an in string (which means the value has already
been set in the nss_info backend), then use that.
Otherwise use the template value passed in. */
if ( in && !strequal(in,"") && lp_security() == SEC_ADS ) {
- templ = talloc_sub_specified(NULL, in,
+ templ = talloc_sub_specified(NULL, in,
username, domname,
uid, gid);
} else {
- templ = talloc_sub_specified(NULL, lp_template,
+ templ = talloc_sub_specified(NULL, lp_template,
username, domname,
- uid, gid);
+ uid, gid);
}
-
+
if (!templ)
return False;
safe_strcpy(out, templ, sizeof(fstring) - 1);
TALLOC_FREE(templ);
-
+
return True;
-
+
}
/* Fill a pwent structure with information we have obtained */
-static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name,
+static bool winbindd_fill_pwent(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;
-
+
/* Resolve the uid number */
- if (!NT_STATUS_IS_OK(idmap_sid_to_uid(dom_name, user_sid,
- &pw->pw_uid))) {
+ if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) {
DEBUG(1, ("error getting user id for sid %s\n",
sid_string_dbg(user_sid)));
return False;
}
+
+ /* Resolve the gid number */
- /* Resolve the gid number */
-
- if (!NT_STATUS_IS_OK(idmap_sid_to_gid(dom_name, group_sid,
- &pw->pw_gid))) {
+ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) {
DEBUG(1, ("error getting group id for sid %s\n",
sid_string_dbg(group_sid)));
return False;
@@ -102,42 +97,21 @@ static bool winbindd_fill_pwent(TALLOC_CTX *ctx, char *dom_name, char *user_name
/* Username */
- 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);
- }
+ fill_domain_username(output_username, dom_name, user_name, True);
safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
-
+
/* Full name (gecos) */
-
+
safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1);
/* Home directory and shell */
-
- if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
+
+ if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir))
return False;
- if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
+ if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
pw->pw_uid, pw->pw_gid, shell, pw->pw_shell))
return False;
@@ -161,7 +135,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain,
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
- DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
+ DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
state->request.data.sid));
if (!string_to_sid(&sid, state->request.data.sid)) {
@@ -181,7 +155,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain,
fstrcpy(state->response.data.user_info.full_name, user_info.full_name);
fstrcpy(state->response.data.user_info.homedir, user_info.homedir);
fstrcpy(state->response.data.user_info.shell, user_info.shell);
- state->response.data.user_info.primary_gid = user_info.primary_gid;
+ state->response.data.user_info.primary_gid = user_info.primary_gid;
if (!sid_peek_check_rid(&domain->sid, &user_info.group_sid,
&state->response.data.user_info.group_rid)) {
DEBUG(1, ("Could not extract group rid out of %s\n",
@@ -203,12 +177,11 @@ 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,
const char *acct_name,
- const char *full_name,
+ const char *full_name,
const char *homedir,
const char *shell,
gid_t gid,
@@ -244,10 +217,10 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state,
error:
request_error(state);
}
-
+
static void getpwsid_queryuser_recv(void *private_data, bool success,
const char *acct_name,
- const char *full_name,
+ const char *full_name,
const char *homedir,
const char *shell,
gid_t gid,
@@ -256,8 +229,6 @@ 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",
@@ -268,59 +239,43 @@ static void getpwsid_queryuser_recv(void *private_data, bool success,
if ( acct_name && *acct_name ) {
fstrcpy( username, acct_name );
- } else {
+ } else {
char *domain_name = NULL;
enum lsa_SidType type;
char *user_name = NULL;
struct winbindd_domain *domain = NULL;
-
+
domain = find_lookup_domain_from_sid(&s->user_sid);
if (domain == NULL) {
DEBUG(5, ("find_lookup_domain_from_sid(%s) failed\n",
sid_string_dbg(&s->user_sid)));
request_error(s->state);
- return;
+ return;
}
winbindd_lookup_name_by_sid(s->state->mem_ctx, domain,
&s->user_sid, &domain_name,
- &user_name, &type );
+ &user_name, &type );
/* If this still fails we ar4e done. Just error out */
if ( !user_name ) {
DEBUG(5,("Could not obtain a name for SID %s\n",
sid_string_dbg(&s->user_sid)));
request_error(s->state);
- return;
+ return;
}
- fstrcpy( username, user_name );
+ fstrcpy( username, user_name );
}
strlower_m( username );
s->username = talloc_strdup(s->state->mem_ctx, username);
- 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;
- }
-
+ ws_name_replace( s->username, WB_REPLACE_CHAR );
+
s->fullname = talloc_strdup(s->state->mem_ctx, full_name);
s->homedir = talloc_strdup(s->state->mem_ctx, homedir);
s->shell = talloc_strdup(s->state->mem_ctx, shell);
- s->gid = gid;
+ s->gid = gid;
sid_copy(&s->group_sid, &s->domain->sid);
sid_append_rid(&s->group_sid, group_rid);
@@ -373,29 +328,18 @@ 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);
- }
-
+ 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);
- if (!fillup_pw_field(lp_template_homedir(), s->username,
- s->domain->name, pw->pw_uid, pw->pw_gid,
- s->homedir, pw->pw_dir)) {
+ if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name,
+ pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) {
DEBUG(5, ("Could not compose homedir\n"));
goto failed;
}
- if (!fillup_pw_field(lp_template_shell(), s->username,
- s->domain->name, pw->pw_uid, pw->pw_gid,
- s->shell, pw->pw_shell)) {
+ if (!fillup_pw_field(lp_template_shell(), s->username, s->domain->name,
+ pw->pw_uid, pw->pw_gid, s->shell, pw->pw_shell)) {
DEBUG(5, ("Could not compose shell\n"));
goto failed;
}
@@ -421,39 +365,23 @@ 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);
-
- /* Ensure null termination (it's an fstring) */
- domuser[dusize-1] = '\0';
-
- DEBUG(3, ("[%5lu]: getpwnam %s\n",
- (unsigned long)state->pid,
- domuser));
-
- nt_status = normalize_name_unmap(state->mem_ctx, domuser,
- &mapped_user);
+ /* Ensure null termination */
+ state->request.data.username[sizeof(state->request.data.username)-1]='\0';
- /* If we could not convert from an aliased name or a
- normalized name, then just use the original name */
+ DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid,
+ state->request.data.username));
- if (!NT_STATUS_IS_OK(nt_status) &&
- !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))
- {
- mapped_user = domuser;
- }
+ ws_name_return( state->request.data.username, WB_REPLACE_CHAR );
- if (!parse_domain_user(mapped_user, domname, username)) {
- DEBUG(5, ("Could not parse domain user: %s\n", domuser));
+ if (!parse_domain_user(state->request.data.username, domname,
+ username)) {
+ DEBUG(5, ("Could not parse domain user: %s\n",
+ state->request.data.username));
request_error(state);
return;
}
-
+
/* Get info for the domain */
domain = find_domain_from_name(domname);
@@ -463,24 +391,22 @@ void winbindd_getpwnam(struct winbindd_cli_state *state)
"Using primary domain\n", domname));
if ( (domain = find_our_domain()) == NULL ) {
DEBUG(0,("Cannot find my primary domain structure!\n"));
- request_error(state);
- return;
- }
+ request_error(state);
+ return;
+ }
}
- if (strequal(domname, lp_workgroup()) &&
- lp_winbind_trusted_domains_only() ) {
- DEBUG(7,("winbindd_getpwnam: My domain -- "
- "rejecting getpwnam() for %s\\%s.\n",
- domname, username));
+ if ( strequal(domname, lp_workgroup()) && lp_winbind_trusted_domains_only() ) {
+ DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n",
+ domname, username));
request_error(state);
return;
- }
+ }
/* Get rid and name type from name. The following costs 1 packet */
winbindd_lookupname_async(state->mem_ctx, domname, username,
- getpwnam_name2sid_recv, WINBINDD_GETPWNAM,
+ getpwnam_name2sid_recv, WINBINDD_GETPWNAM,
state);
}
@@ -489,25 +415,27 @@ static void getpwnam_name2sid_recv(void *private_data, bool success,
{
struct winbindd_cli_state *state =
(struct winbindd_cli_state *)private_data;
- fstring domname, username;
- char *domuser = state->request.data.username;
+ fstring domname, username;
if (!success) {
- DEBUG(5, ("Could not lookup name for user %s\n", domuser));
+ DEBUG(5, ("Could not lookup name for user %s\n",
+ state->request.data.username));
request_error(state);
return;
}
if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) {
- DEBUG(5, ("%s is not a user\n", domuser));
+ DEBUG(5, ("%s is not a user\n", state->request.data.username));
request_error(state);
return;
}
- if (parse_domain_user(domuser, domname, username)) {
- check_domain_trusted(domname, sid);
+ if ( parse_domain_user(state->request.data.username, domname, username) ) {
+ check_domain_trusted( domname, sid );
}
+
+
winbindd_getpwsid(state, sid);
}
@@ -523,7 +451,7 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid)
request_error(state);
return;
}
-
+
DEBUG(10,("uid2sid_recv: uid %lu has sid %s\n",
(unsigned long)(state->request.data.uid), sid));
@@ -534,16 +462,12 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid)
/* Return a password structure given a uid number */
void winbindd_getpwuid(struct winbindd_cli_state *state)
{
- uid_t uid = state->request.data.uid;
-
- DEBUG(3, ("[%5lu]: getpwuid %lu\n",
- (unsigned long)state->pid,
- (unsigned long)uid));
+ DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.uid));
/* always query idmap via the async interface */
- /* if this turns to be too slow we will add here
- * a direct query to the cache */
- winbindd_uid2sid_async(state->mem_ctx, uid, getpwuid_recv, state);
+ /* if this turns to be too slow we will add here a direct query to the cache */
+ winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, getpwuid_recv, state);
}
/*
@@ -555,53 +479,66 @@ void winbindd_getpwuid(struct winbindd_cli_state *state)
static bool winbindd_setpwent_internal(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
-
+
DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid));
-
+
/* Check user has enabled this */
-
+
if (!lp_winbind_enum_users()) {
return False;
}
/* Free old static data if it exists */
-
+
if (state->getpwent_state != NULL) {
free_getent_state(state->getpwent_state);
state->getpwent_state = NULL;
}
+#if 0 /* JERRY */
+ /* add any local users we have */
+
+ if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL )
+ return False;
+
+ ZERO_STRUCTP(domain_state);
+
+ /* Add to list of open domains */
+
+ DLIST_ADD(state->getpwent_state, domain_state);
+#endif
+
/* Create sam pipes for each domain we know about */
-
+
for(domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
-
-
- /* don't add our domaina if we are a PDC or if we
+
+
+ /* don't add our domaina if we are a PDC or if we
are a member of a Samba domain */
-
- if ((IS_DC || lp_winbind_trusted_domains_only())
- && strequal(domain->name, lp_workgroup())) {
+
+ if ( (IS_DC || lp_winbind_trusted_domains_only())
+ && strequal(domain->name, lp_workgroup()) )
+ {
continue;
}
-
+
/* Create a state record for this domain */
-
- domain_state = SMB_MALLOC_P(struct getent_state);
- if (!domain_state) {
+
+ if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) {
DEBUG(0, ("malloc failed\n"));
return False;
}
-
+
ZERO_STRUCTP(domain_state);
fstrcpy(domain_state->domain_name, domain->name);
/* Add to list of open domains */
-
+
DLIST_ADD(state->getpwent_state, domain_state);
}
-
+
state->getpwent_initialized = True;
return True;
}
@@ -621,7 +558,7 @@ void winbindd_endpwent(struct winbindd_cli_state *state)
{
DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid));
- free_getent_state(state->getpwent_state);
+ free_getent_state(state->getpwent_state);
state->getpwent_initialized = False;
state->getpwent_state = NULL;
request_ok(state);
@@ -657,23 +594,23 @@ static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx)
SAFE_FREE(ent->sam_entries);
ent->num_sam_entries = 0;
-
+
/* Call query_user_list to get a list of usernames and user rids */
num_entries = 0;
- status = methods->query_user_list(domain, mem_ctx, &num_entries, &info);
-
+ status = methods->query_user_list(domain, mem_ctx, &num_entries,
+ &info);
+
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("get_sam_user_entries: "
- "query_user_list failed with %s\n",
- nt_errstr(status)));
+ DEBUG(10,("get_sam_user_entries: query_user_list failed with %s\n",
+ nt_errstr(status) ));
return False;
}
if (num_entries) {
- name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user,
- ent->num_sam_entries + num_entries);
+ name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user, ent->num_sam_entries + num_entries);
+
if (!name_list) {
DEBUG(0,("get_sam_user_entries realloc failed.\n"));
return False;
@@ -685,40 +622,40 @@ static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx)
if (!info[i].acct_name) {
fstrcpy(name_list[ent->num_sam_entries + i].name, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].name,
- info[i].acct_name);
+ fstrcpy(name_list[ent->num_sam_entries + i].name,
+ info[i].acct_name);
}
if (!info[i].full_name) {
fstrcpy(name_list[ent->num_sam_entries + i].gecos, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].gecos,
- info[i].full_name);
+ fstrcpy(name_list[ent->num_sam_entries + i].gecos,
+ info[i].full_name);
}
if (!info[i].homedir) {
- fstrcpy(name_list[ent->num_sam_entries + i].homedir,"");
+ fstrcpy(name_list[ent->num_sam_entries + i].homedir, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].homedir,
- info[i].homedir);
+ fstrcpy(name_list[ent->num_sam_entries + i].homedir,
+ info[i].homedir);
}
if (!info[i].shell) {
fstrcpy(name_list[ent->num_sam_entries + i].shell, "");
} else {
- fstrcpy(name_list[ent->num_sam_entries + i].shell,
- info[i].shell);
+ fstrcpy(name_list[ent->num_sam_entries + i].shell,
+ info[i].shell);
}
-
-
+
+
/* User and group ids */
sid_copy(&name_list[ent->num_sam_entries+i].user_sid,
&info[i].user_sid);
sid_copy(&name_list[ent->num_sam_entries+i].group_sid,
&info[i].group_sid);
}
-
+
ent->num_sam_entries += num_entries;
-
+
/* Fill in remaining fields */
-
+
ent->sam_entries = name_list;
ent->sam_entry_index = 0;
return ent->num_sam_entries > 0;
@@ -751,20 +688,20 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
request_error(state);
return;
}
-
- user_list = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users);
- if (!user_list) {
+
+ if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) {
request_error(state);
return;
}
- /* will be freed by process_request() */
- state->response.extra_data.data = user_list;
- memset(user_list, 0, num_users * sizeof(struct winbindd_pw));
+ memset(state->response.extra_data.data, 0, num_users *
+ sizeof(struct winbindd_pw));
+
+ user_list = (struct winbindd_pw *)state->response.extra_data.data;
if (!state->getpwent_initialized)
winbindd_setpwent_internal(state);
-
+
if (!(ent = state->getpwent_state)) {
request_error(state);
return;
@@ -794,20 +731,19 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
SAFE_FREE(ent);
ent = next_ent;
}
-
+
/* No more domains */
- if (!ent)
+ if (!ent)
break;
}
name_list = (struct getpwent_user *)ent->sam_entries;
/* Lookup user info */
-
+
result = winbindd_fill_pwent(
- state->mem_ctx,
- ent->domain_name,
+ ent->domain_name,
name_list[ent->sam_entry_index].name,
&name_list[ent->sam_entry_index].user_sid,
&name_list[ent->sam_entry_index].group_sid,
@@ -815,21 +751,22 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
name_list[ent->sam_entry_index].homedir,
name_list[ent->sam_entry_index].shell,
&user_list[user_list_ndx]);
-
+
/* Add user to return list */
-
+
if (result) {
-
+
user_list_ndx++;
state->response.data.num_entries++;
- state->response.length += sizeof(struct winbindd_pw);
+ state->response.length +=
+ sizeof(struct winbindd_pw);
} else
DEBUG(1, ("could not lookup domain user %s\n",
name_list[ent->sam_entry_index].name));
ent->sam_entry_index++;
-
+
}
/* Out of domains */