From 81800c72cc06f948eeca23d33d6b59df71e858e2 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 18 Nov 2013 14:58:04 +0100 Subject: [PATCH 1/2] s3-lib: Add grpname to talloc_sub_specified(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=2191 Signed-off-by: Andreas Schneider --- source3/include/proto.h | 1 + source3/lib/substitute.c | 31 +++++++++++++++++++++++++------ source3/passdb/passdb.c | 8 ++++---- source3/passdb/pdb_ldap.c | 24 +++++++++++++++++++++--- source3/torture/torture.c | 2 +- source3/utils/net_sam.c | 2 ++ source3/winbindd/wb_fill_pwent.c | 4 ++-- 7 files changed, 56 insertions(+), 16 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index fc7f24d..fe81145 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -217,6 +217,7 @@ char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, char *talloc_sub_specified(TALLOC_CTX *mem_ctx, const char *input_string, const char *username, + const char *grpname, const char *domain, uid_t uid, gid_t gid); diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index a254bca..ca2ac79 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -613,6 +613,7 @@ done: char *talloc_sub_specified(TALLOC_CTX *mem_ctx, const char *input_string, const char *username, + const char *grpname, const char *domain, uid_t uid, gid_t gid) @@ -648,9 +649,18 @@ char *talloc_sub_specified(TALLOC_CTX *mem_ctx, break; case 'G' : if (gid != -1) { - a_string = talloc_string_sub( - tmp_ctx, a_string, "%G", - gidtoname(gid)); + const char *name; + + if (grpname != NULL) { + name = grpname; + } else { + name = gidtoname(gid); + } + + a_string = talloc_string_sub(tmp_ctx, + a_string, + "%G", + name); } else { a_string = talloc_string_sub( tmp_ctx, a_string, @@ -659,9 +669,18 @@ char *talloc_sub_specified(TALLOC_CTX *mem_ctx, break; case 'g' : if (gid != -1) { - a_string = talloc_string_sub( - tmp_ctx, a_string, "%g", - gidtoname(gid)); + const char *name; + + if (grpname != NULL) { + name = grpname; + } else { + name = gidtoname(gid); + } + + a_string = talloc_string_sub(tmp_ctx, + a_string, + "%g", + name); } else { a_string = talloc_string_sub( tmp_ctx, a_string, "%g", "NO_GROUP"); diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 379d858..5a4620f 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -228,16 +228,16 @@ static NTSTATUS samu_set_unix_internal(struct pdb_methods *methods, /* set some basic attributes */ pdb_set_profile_path(user, talloc_sub_specified(user, - lp_logon_path(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), + lp_logon_path(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid), PDB_DEFAULT); pdb_set_homedir(user, talloc_sub_specified(user, - lp_logon_home(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), + lp_logon_home(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid), PDB_DEFAULT); pdb_set_dir_drive(user, talloc_sub_specified(user, - lp_logon_drive(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), + lp_logon_drive(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid), PDB_DEFAULT); pdb_set_logon_script(user, talloc_sub_specified(user, - lp_logon_script(), pwd->pw_name, domain, pwd->pw_uid, pwd->pw_gid), + lp_logon_script(), pwd->pw_name, NULL, domain, pwd->pw_uid, pwd->pw_gid), PDB_DEFAULT); } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index d7db4d8..bb0d3b3 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -5316,11 +5316,29 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, if (is_machine) { /* TODO: choose a more appropriate default for machines */ - homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), "SMB_workstations_home", ldap_state->domain_name, uid, gid); + homedir = talloc_sub_specified(tmp_ctx, + lp_template_homedir(), + "SMB_workstations_home", + NULL, + ldap_state->domain_name, + uid, + gid); shell = talloc_strdup(tmp_ctx, "/bin/false"); } else { - homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), name, ldap_state->domain_name, uid, gid); - shell = talloc_sub_specified(tmp_ctx, lp_template_shell(), name, ldap_state->domain_name, uid, gid); + homedir = talloc_sub_specified(tmp_ctx, + lp_template_homedir(), + name, + NULL, + ldap_state->domain_name, + uid, + gid); + shell = talloc_sub_specified(tmp_ctx, + lp_template_shell(), + name, + NULL, + ldap_state->domain_name, + uid, + gid); } uidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)uid); gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid); diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 8313cf1..af2c466 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -6553,7 +6553,7 @@ static bool subst_test(const char *str, const char *user, const char *domain, char *subst; bool result = true; - subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid); + subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid); if (strcmp(subst, expected) != 0) { printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected " diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index 3a752ce..b7b76e8 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -1873,10 +1873,12 @@ doma_done: gidstr = talloc_asprintf(tc, "%u", (unsigned int)domadmins_gid); dir = talloc_sub_specified(tc, lp_template_homedir(), "Administrator", + NULL, get_global_sam_name(), uid, domadmins_gid); shell = talloc_sub_specified(tc, lp_template_shell(), "Administrator", + NULL, get_global_sam_name(), uid, domadmins_gid); diff --git a/source3/winbindd/wb_fill_pwent.c b/source3/winbindd/wb_fill_pwent.c index 688afc6..3b711bd 100644 --- a/source3/winbindd/wb_fill_pwent.c +++ b/source3/winbindd/wb_fill_pwent.c @@ -214,11 +214,11 @@ static bool fillup_pw_field(const char *lp_template, if ((in != NULL) && (in[0] != '\0') && (lp_security() == SEC_ADS)) { templ = talloc_sub_specified(talloc_tos(), in, - username, domname, + username, NULL, domname, uid, gid); } else { templ = talloc_sub_specified(talloc_tos(), lp_template, - username, domname, + username, NULL, domname, uid, gid); } -- 1.8.4.3 From 1d21e37d44359724a83605897fc10dd4c03bdb9f Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 18 Nov 2013 14:58:14 +0100 Subject: [PATCH 2/2] s3-winbind: Pass the group name to fillup_pw_field(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=2191 Signed-off-by: Andreas Schneider --- source3/winbindd/wb_fill_pwent.c | 73 +++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/source3/winbindd/wb_fill_pwent.c b/source3/winbindd/wb_fill_pwent.c index 3b711bd..9d0abbd 100644 --- a/source3/winbindd/wb_fill_pwent.c +++ b/source3/winbindd/wb_fill_pwent.c @@ -29,6 +29,7 @@ struct wb_fill_pwent_state { static bool fillup_pw_field(const char *lp_template, const char *username, + const char *grpname, const char *domname, uid_t uid, gid_t gid, @@ -36,7 +37,7 @@ static bool fillup_pw_field(const char *lp_template, fstring out); static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq); -static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq); +static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq); struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -90,47 +91,45 @@ static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq) state->pw->pw_uid = (uid_t)xid.id; - subreq = wb_sids2xids_send(state, state->ev, &state->info->group_sid, 1); + subreq = wb_getgrsid_send(state, state->ev, &state->info->group_sid, 1); if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, wb_fill_pwent_sid2gid_done, req); + tevent_req_set_callback(subreq, wb_fill_pwent_getgrsid_done, req); } -static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq) +static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct wb_fill_pwent_state *state = tevent_req_data( req, struct wb_fill_pwent_state); struct winbindd_domain *domain; - char *dom_name; + const char *dom_name; + const char *grp_name; fstring user_name, output_username; char *mapped_name = NULL; + struct talloc_dict *members; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); NTSTATUS status; - struct unixid xid; - - status = wb_sids2xids_recv(subreq, &xid); + bool ok; + + /* xid handling is done in getgrsid() */ + status = wb_getgrsid_recv(subreq, + tmp_ctx, + &dom_name, + &grp_name, + &state->pw->pw_gid, + &members); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { + talloc_free(tmp_ctx); return; } - /* - * We are filtering further down in sids2xids, but that filtering - * depends on the actual type of the sid handed in (as determined - * by lookupsids). Here we need to filter for the type of object - * actually requested, in this case gid. - */ - if (!(xid.type == ID_TYPE_GID || xid.type == ID_TYPE_BOTH)) { - tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); - return; - } - - state->pw->pw_gid = (gid_t)xid.id; - domain = find_domain_from_sid_noinit(&state->info->user_sid); if (domain == NULL) { + talloc_free(tmp_ctx); tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); return; } @@ -166,17 +165,30 @@ static void wb_fill_pwent_sid2gid_done(struct tevent_req *subreq) fstrcpy(state->pw->pw_gecos, state->info->full_name); /* Home directory and shell */ - - if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, - state->pw->pw_uid, state->pw->pw_gid, - state->info->homedir, state->pw->pw_dir)) { + ok = fillup_pw_field(lp_template_homedir(), + user_name, + grp_name, + dom_name, + state->pw->pw_uid, + state->pw->pw_gid, + state->info->homedir, + state->pw->pw_dir); + if (!ok) { + talloc_free(tmp_ctx); tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); return; } - if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, - state->pw->pw_uid, state->pw->pw_gid, - state->info->shell, state->pw->pw_shell)) { + ok = fillup_pw_field(lp_template_shell(), + user_name, + grp_name, + dom_name, + state->pw->pw_uid, + state->pw->pw_gid, + state->info->shell, + state->pw->pw_shell); + talloc_free(tmp_ctx); + if (!ok) { tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); return; } @@ -195,6 +207,7 @@ NTSTATUS wb_fill_pwent_recv(struct tevent_req *req) static bool fillup_pw_field(const char *lp_template, const char *username, + const char *grpname, const char *domname, uid_t uid, gid_t gid, @@ -214,11 +227,11 @@ static bool fillup_pw_field(const char *lp_template, if ((in != NULL) && (in[0] != '\0') && (lp_security() == SEC_ADS)) { templ = talloc_sub_specified(talloc_tos(), in, - username, NULL, domname, + username, grpname, domname, uid, gid); } else { templ = talloc_sub_specified(talloc_tos(), lp_template, - username, NULL, domname, + username, grpname, domname, uid, gid); } -- 1.8.4.3