summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd.h4
-rw-r--r--source3/nsswitch/winbindd_ads.c24
-rw-r--r--source3/nsswitch/winbindd_async.c9
-rw-r--r--source3/nsswitch/winbindd_cache.c8
-rw-r--r--source3/nsswitch/winbindd_nss.h2
-rw-r--r--source3/nsswitch/winbindd_rpc.c9
-rw-r--r--source3/nsswitch/winbindd_user.c118
7 files changed, 127 insertions, 47 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index 378120c80b..3a7728e4a2 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -84,6 +84,8 @@ struct getent_state {
struct getpwent_user {
fstring name; /* Account name */
fstring gecos; /* User information */
+ fstring homedir; /* User Home Directory */
+ fstring shell; /* User Login Shell */
DOM_SID user_sid; /* NT user and primary group SIDs */
DOM_SID group_sid;
};
@@ -103,6 +105,8 @@ extern struct winbindd_state server_state; /* Server information */
typedef struct {
char *acct_name;
char *full_name;
+ char *homedir;
+ char *shell;
DOM_SID user_sid; /* NT user and primary group SIDs */
DOM_SID group_sid;
} WINBIND_USERINFO;
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index c807ec59a5..868a7bc2ac 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -95,6 +95,11 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
return NULL;
}
+ if (lp_winbind_sfu_support() && (!ads_check_sfu_mapping(ads))) {
+ DEBUG(0,("ads_cached_connection: failed to check sfu attributes\n"));
+ return NULL;
+ }
+
/* set the flag that says we don't own the memory even
though we do so that ads_destroy() won't destroy the
structure we pass back by reference */
@@ -116,7 +121,10 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
const char *attrs[] = {"userPrincipalName",
"sAMAccountName",
"name", "objectSid", "primaryGroupID",
- "sAMAccountType", NULL};
+ "sAMAccountType",
+ ADS_ATTR_SFU_HOMEDIR_OID,
+ ADS_ATTR_SFU_SHELL_OID,
+ NULL};
int i, count;
ADS_STATUS rc;
void *res = NULL;
@@ -155,7 +163,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
i = 0;
for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
- char *name, *gecos;
+ char *name, *gecos, *homedir, *shell;
uint32 group;
uint32 atype;
@@ -167,6 +175,9 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
name = ads_pull_username(ads, mem_ctx, msg);
gecos = ads_pull_string(ads, mem_ctx, msg, "name");
+ homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr);
+ shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr);
+
if (!ads_pull_sid(ads, msg, "objectSid",
&(*info)[i].user_sid)) {
DEBUG(1,("No sid for %s !?\n", name));
@@ -179,6 +190,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
(*info)[i].acct_name = name;
(*info)[i].full_name = gecos;
+ (*info)[i].homedir = homedir;
+ (*info)[i].shell = shell;
sid_compose(&(*info)[i].group_sid, &domain->sid, group);
i++;
}
@@ -364,7 +377,10 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
const char *attrs[] = {"userPrincipalName",
"sAMAccountName",
"name",
- "primaryGroupID", NULL};
+ "primaryGroupID",
+ ADS_ATTR_SFU_HOMEDIR_OID,
+ ADS_ATTR_SFU_SHELL_OID,
+ NULL};
ADS_STATUS rc;
int count;
void *msg = NULL;
@@ -402,6 +418,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
info->acct_name = ads_pull_username(ads, mem_ctx, msg);
info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
+ info->homedir = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_homedir_attr);
+ info->shell = ads_pull_string(ads, mem_ctx, msg, ads->schema.sfu_shell_attr);
if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) {
DEBUG(1,("No primary group for %s !?\n",
diff --git a/source3/nsswitch/winbindd_async.c b/source3/nsswitch/winbindd_async.c
index d227177ec1..acae7e7f37 100644
--- a/source3/nsswitch/winbindd_async.c
+++ b/source3/nsswitch/winbindd_async.c
@@ -1372,16 +1372,19 @@ static void query_user_recv(TALLOC_CTX *mem_ctx, BOOL success,
void *c, void *private_data)
{
void (*cont)(void *priv, BOOL succ, const char *acct_name,
- const char *full_name, uint32 group_rid) = c;
+ const char *full_name, const char *homedir,
+ const char *shell, uint32 group_rid) = c;
if (!success) {
DEBUG(5, ("Could not trigger query_user\n"));
- cont(private_data, False, NULL, NULL, -1);
+ cont(private_data, False, NULL, NULL, NULL, NULL, -1);
return;
}
cont(private_data, True, response->data.user_info.acct_name,
response->data.user_info.full_name,
+ response->data.user_info.homedir,
+ response->data.user_info.shell,
response->data.user_info.group_rid);
}
@@ -1390,6 +1393,8 @@ void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
void (*cont)(void *private_data, BOOL success,
const char *acct_name,
const char *full_name,
+ const char *homedir,
+ const char *shell,
uint32 group_rid),
void *private_data)
{
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 90ccb43a6e..730da7a9b5 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -652,6 +652,8 @@ static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WI
return;
centry_put_string(centry, info->acct_name);
centry_put_string(centry, info->full_name);
+ centry_put_string(centry, info->homedir);
+ centry_put_string(centry, info->shell);
centry_put_sid(centry, &info->user_sid);
centry_put_sid(centry, &info->group_sid);
centry_end(centry, "U/%s", sid_to_string(sid_string, &info->user_sid));
@@ -689,6 +691,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
for (i=0; i<(*num_entries); i++) {
(*info)[i].acct_name = centry_string(centry, mem_ctx);
(*info)[i].full_name = centry_string(centry, mem_ctx);
+ (*info)[i].homedir = centry_string(centry, mem_ctx);
+ (*info)[i].shell = centry_string(centry, mem_ctx);
centry_sid(centry, &(*info)[i].user_sid);
centry_sid(centry, &(*info)[i].group_sid);
}
@@ -747,6 +751,8 @@ do_query:
for (i=0; i<(*num_entries); i++) {
centry_put_string(centry, (*info)[i].acct_name);
centry_put_string(centry, (*info)[i].full_name);
+ centry_put_string(centry, (*info)[i].homedir);
+ centry_put_string(centry, (*info)[i].shell);
centry_put_sid(centry, &(*info)[i].user_sid);
centry_put_sid(centry, &(*info)[i].group_sid);
if (domain->backend->consistent) {
@@ -1082,6 +1088,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
info->acct_name = centry_string(centry, mem_ctx);
info->full_name = centry_string(centry, mem_ctx);
+ info->homedir = centry_string(centry, mem_ctx);
+ info->shell = centry_string(centry, mem_ctx);
centry_sid(centry, &info->user_sid);
centry_sid(centry, &info->group_sid);
status = centry->status;
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index b249b62d69..cf0fae74a0 100644
--- a/source3/nsswitch/winbindd_nss.h
+++ b/source3/nsswitch/winbindd_nss.h
@@ -322,6 +322,8 @@ struct winbindd_response {
struct {
fstring acct_name;
fstring full_name;
+ fstring homedir;
+ fstring shell;
uint32 group_rid;
} user_info;
} data;
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index 2b4c020d88..63e2487700 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -101,6 +101,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
(*info)[i].acct_name = talloc_strdup(mem_ctx, username );
(*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
+ (*info)[i].homedir = NULL;
+ (*info)[i].shell = NULL;
sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
/* For the moment we set the primary group for
@@ -352,7 +354,10 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
&user->uni_user_name);
user_info->full_name = unistr2_tdup(mem_ctx,
&user->uni_full_name);
-
+
+ user_info->homedir = NULL;
+ user_info->shell = NULL;
+
SAFE_FREE(user);
return NT_STATUS_OK;
@@ -388,6 +393,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
&ctr->info.id21->uni_user_name);
user_info->full_name = unistr2_tdup(mem_ctx,
&ctr->info.id21->uni_full_name);
+ user_info->homedir = NULL;
+ user_info->shell = NULL;
return NT_STATUS_OK;
}
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index 576ceaea23..f849bff42d 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -30,15 +30,50 @@
extern userdom_struct current_user_info;
+static BOOL fillup_pw_field(const char *lp_template,
+ const char *username,
+ const char *domname,
+ uid_t uid,
+ gid_t gid,
+ const char *in,
+ fstring out)
+{
+ char *templ;
+
+ if (out == NULL)
+ return False;
+
+ if (in && !strequal(in,"") && lp_security() == SEC_ADS && lp_winbind_sfu_support()) {
+ safe_strcpy(out, in, sizeof(fstring) - 1);
+ return True;
+ }
+
+ /* Home directory and shell - use template config parameters. The
+ defaults are /tmp for the home directory and /bin/false for
+ shell. */
+
+ /* The substitution of %U and %D in the 'template homedir' is done
+ by alloc_sub_specified() below. */
+
+ templ = alloc_sub_specified(lp_template, username, domname, uid, gid);
+
+ if (!templ)
+ return False;
+
+ safe_strcpy(out, templ, sizeof(fstring) - 1);
+ SAFE_FREE(templ);
+
+ return True;
+
+}
/* Fill a pwent structure with information we have obtained */
static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
DOM_SID *user_sid, DOM_SID *group_sid,
- char *full_name, struct winbindd_pw *pw)
+ char *full_name, char *homedir, char *shell,
+ struct winbindd_pw *pw)
{
fstring output_username;
- char *homedir;
- char *shell;
fstring sid_string;
if (!pw || !dom_name || !user_name)
@@ -79,25 +114,14 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
fstrcpy(current_user_info.domain, dom_name);
- homedir = alloc_sub_specified(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid);
-
- if (!homedir)
+ if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name,
+ pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir))
return False;
-
- safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
-
- SAFE_FREE(homedir);
-
- shell = alloc_sub_specified(lp_template_shell(), user_name, dom_name, pw->pw_uid, pw->pw_gid);
- if (!shell)
+ if (!fillup_pw_field(lp_template_shell(), user_name, dom_name,
+ pw->pw_uid, pw->pw_gid, shell, pw->pw_shell))
return False;
- safe_strcpy(pw->pw_shell, shell,
- sizeof(pw->pw_shell) - 1);
-
- SAFE_FREE(shell);
-
/* Password - set to "x" as we can't generate anything useful here.
Authentication can be done using the pam_winbind module. */
@@ -136,6 +160,8 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain,
fstrcpy(state->response.data.user_info.acct_name, user_info.acct_name);
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);
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",
@@ -151,6 +177,8 @@ struct getpwsid_state {
struct winbindd_domain *domain;
char *username;
char *fullname;
+ char *homedir;
+ char *shell;
DOM_SID user_sid;
uid_t uid;
DOM_SID group_sid;
@@ -159,7 +187,10 @@ struct getpwsid_state {
static void getpwsid_queryuser_recv(void *private_data, BOOL success,
const char *acct_name,
- const char *full_name, uint32 group_rid);
+ const char *full_name,
+ const char *homedir,
+ const char *shell,
+ uint32 group_rid);
static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid);
static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid);
@@ -194,7 +225,10 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state,
static void getpwsid_queryuser_recv(void *private_data, BOOL success,
const char *acct_name,
- const char *full_name, uint32 group_rid)
+ const char *full_name,
+ const char *homedir,
+ const char *shell,
+ uint32 group_rid)
{
struct getpwsid_state *s =
talloc_get_type_abort(private_data, struct getpwsid_state);
@@ -208,6 +242,8 @@ static void getpwsid_queryuser_recv(void *private_data, BOOL success,
s->username = talloc_strdup(s->state->mem_ctx, acct_name);
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);
sid_copy(&s->group_sid, &s->domain->sid);
sid_append_rid(&s->group_sid, group_rid);
@@ -238,8 +274,6 @@ static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid)
talloc_get_type_abort(private_data, struct getpwsid_state);
struct winbindd_pw *pw;
fstring output_username;
- char *homedir;
- char *shell;
if (!success) {
DEBUG(5, ("Could not query user's %s\\%s\n gid",
@@ -256,32 +290,19 @@ static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid)
safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1);
safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1);
- /* Home directory and shell - use template config parameters. The
- defaults are /tmp for the home directory and /bin/false for
- shell. */
-
- /* The substitution of %U and %D in the 'template homedir' is done
- by alloc_sub_specified() below. */
-
fstrcpy(current_user_info.domain, s->domain->name);
- homedir = alloc_sub_specified(lp_template_homedir(), s->username,
- s->domain->name, pw->pw_uid, pw->pw_gid);
- if (homedir == NULL) {
+ 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;
}
- safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
- SAFE_FREE(homedir);
-
- shell = alloc_sub_specified(lp_template_shell(), s->username,
- s->domain->name, pw->pw_uid, pw->pw_gid);
- if (shell == NULL) {
+
+ 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;
}
- safe_strcpy(pw->pw_shell, shell, sizeof(pw->pw_shell) - 1);
- SAFE_FREE(shell);
/* Password - set to "x" as we can't generate anything useful here.
Authentication can be done using the pam_winbind module. */
@@ -555,7 +576,20 @@ static BOOL get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx)
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, "");
+ } else {
+ 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);
+ }
+
+
/* User and group ids */
sid_copy(&name_list[ent->num_sam_entries+i].user_sid,
&info[i].user_sid);
@@ -658,6 +692,8 @@ void winbindd_getpwent(struct winbindd_cli_state *state)
&name_list[ent->sam_entry_index].user_sid,
&name_list[ent->sam_entry_index].group_sid,
name_list[ent->sam_entry_index].gecos,
+ name_list[ent->sam_entry_index].homedir,
+ name_list[ent->sam_entry_index].shell,
&user_list[user_list_ndx]);
ent->sam_entry_index++;