diff options
author | Gerald Carter <jerry@samba.org> | 2004-04-07 12:43:44 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:51:10 -0500 |
commit | b393469d9581f20e4d4c52633b952ee984cca36f (patch) | |
tree | 92472b0af539644013e95f2c55ebba56c072b28f /source/nsswitch | |
parent | 1fae60ab20c5cbe396dc8af1c8c9a98d5683fdf4 (diff) | |
download | samba-b393469d9581f20e4d4c52633b952ee984cca36f.tar.gz samba-b393469d9581f20e4d4c52633b952ee984cca36f.tar.xz samba-b393469d9581f20e4d4c52633b952ee984cca36f.zip |
r116: volker's patch for local group and group nesting
Diffstat (limited to 'source/nsswitch')
-rw-r--r-- | source/nsswitch/wb_client.c | 24 | ||||
-rw-r--r-- | source/nsswitch/wbinfo.c | 19 | ||||
-rw-r--r-- | source/nsswitch/winbindd.c | 1 | ||||
-rw-r--r-- | source/nsswitch/winbindd.h | 1 | ||||
-rw-r--r-- | source/nsswitch/winbindd_group.c | 136 | ||||
-rw-r--r-- | source/nsswitch/winbindd_nss.h | 3 | ||||
-rw-r--r-- | source/nsswitch/winbindd_passdb.c | 339 | ||||
-rw-r--r-- | source/nsswitch/winbindd_sid.c | 33 | ||||
-rw-r--r-- | source/nsswitch/winbindd_util.c | 43 |
9 files changed, 543 insertions, 56 deletions
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c index 90e4584daba..5d431392450 100644 --- a/source/nsswitch/wb_client.c +++ b/source/nsswitch/wb_client.c @@ -235,6 +235,30 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) return (result == NSS_STATUS_SUCCESS); } +BOOL winbind_allocate_rid(uint32 *rid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Make request */ + + result = winbindd_request(WINBINDD_ALLOCATE_RID, &request, &response); + + if (result != NSS_STATUS_SUCCESS) + return False; + + /* Copy out result */ + *rid = response.data.rid; + + return True; +} + /* Fetch the list of groups a user is a member of from winbindd. This is used by winbind_getgroups. */ diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c index 2cea4130adc..ce48e9ae652 100644 --- a/source/nsswitch/wbinfo.c +++ b/source/nsswitch/wbinfo.c @@ -436,6 +436,18 @@ static BOOL wbinfo_sid_to_gid(char *sid) return True; } +static BOOL wbinfo_allocate_rid(void) +{ + uint32 rid; + + if (!winbind_allocate_rid(&rid)) + return False; + + d_printf("New rid: %d\n", rid); + + return True; +} + /* Convert sid to string */ static BOOL wbinfo_lookupsid(char *sid) @@ -1042,6 +1054,7 @@ int main(int argc, char **argv) { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" }, { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" }, { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" }, + { "allocate-rid", 'A', POPT_ARG_NONE, 0, 'A', "Get a new RID out of idmap" }, { "create-user", 'c', POPT_ARG_STRING, &string_arg, 'c', "Create a local user account", "name" }, { "delete-user", 'x', POPT_ARG_STRING, &string_arg, 'x', "Delete a local user account", "name" }, { "create-group", 'C', POPT_ARG_STRING, &string_arg, 'C', "Create a local group", "name" }, @@ -1164,6 +1177,12 @@ int main(int argc, char **argv) goto done; } break; + case 'A': + if (!wbinfo_allocate_rid()) { + d_printf("Could not allocate a RID\n"); + goto done; + } + break; case 't': if (!wbinfo_check_secret()) { d_printf("Could not check secret\n"); diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c index b55ea297b49..283b2e4a89c 100644 --- a/source/nsswitch/winbindd.c +++ b/source/nsswitch/winbindd.c @@ -255,6 +255,7 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" }, { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" }, { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" }, + { WINBINDD_ALLOCATE_RID, winbindd_allocate_rid, "ALLOCATE_RID" }, /* Miscellaneous */ diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h index 0087d58195d..5c05a1b0457 100644 --- a/source/nsswitch/winbindd.h +++ b/source/nsswitch/winbindd.h @@ -97,6 +97,7 @@ struct winbindd_domain { BOOL native_mode; /* is this a win2k domain in native mode ? */ BOOL active_directory; /* is this a win2k active directory ? */ BOOL primary; /* is this our primary domain ? */ + BOOL internal; /* BUILTIN and member SAM */ /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c index 3ee8c0877b5..f9b6df1aed9 100644 --- a/source/nsswitch/winbindd_group.c +++ b/source/nsswitch/winbindd_group.c @@ -106,6 +106,15 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain, DEBUG(10, ("group SID %s\n", sid_to_string(sid_string, group_sid))); *num_gr_mem = 0; + + /* HACK ALERT!! This whole routine does not cope with group members + * from more than one domain, ie aliases. Thus we have to work it out + * ourselves in a special routine. */ + + if (domain->internal) + return fill_passdb_alias_grmem(domain, group_sid, + num_gr_mem, + gr_mem, gr_mem_len); if ( !((group_name_type==SID_NAME_DOM_GRP) || ((group_name_type==SID_NAME_ALIAS) && domain->primary)) ) @@ -243,14 +252,11 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) /* if no domain or our local domain, then do a local tdb search */ - if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) { + if ( (!*name_domain || strequal(name_domain, get_global_sam_name())) && + ((grp = wb_getgrnam(name_group)) != NULL) ) { + char *buffer = NULL; - if ( !(grp=wb_getgrnam(name_group)) ) { - DEBUG(5,("winbindd_getgrnam: lookup for %s\\%s failed\n", - name_domain, name_group)); - return WINBINDD_ERROR; - } memcpy( &state->response.data.gr, grp, sizeof(WINBINDD_GR) ); gr_mem_len = gr_mem_buffer( &buffer, grp->gr_mem, grp->num_gr_mem ); @@ -262,6 +268,13 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_OK; } + /* if no domain or our local domain and no local tdb group, default to + * our local domain for aliases */ + + if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) { + fstrcpy(name_domain, get_global_sam_name()); + } + /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { @@ -287,7 +300,8 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) } if ( !((name_type==SID_NAME_DOM_GRP) || - ((name_type==SID_NAME_ALIAS) && domain->primary)) ) + ((name_type==SID_NAME_ALIAS) && domain->primary) || + ((name_type==SID_NAME_ALIAS) && domain->internal)) ) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", name_group, name_type)); @@ -378,7 +392,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) } if ( !((name_type==SID_NAME_DOM_GRP) || - ((name_type==SID_NAME_ALIAS) && domain->primary) )) + ((name_type==SID_NAME_ALIAS) && domain->primary) || + ((name_type==SID_NAME_ALIAS) && domain->internal)) ) { DEBUG(1, ("name '%s' is not a local or domain group: %d\n", group_name, name_type)); @@ -541,8 +556,8 @@ static BOOL get_sam_group_entries(struct getent_state *ent) /* get the domain local groups if we are a member of a native win2k domain and are not using LDAP to get the groups */ - if ( lp_security() != SEC_ADS && domain->native_mode - && domain->primary ) + if ( ( lp_security() != SEC_ADS && domain->native_mode + && domain->primary) || domain->internal ) { DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n")); @@ -898,6 +913,61 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) return WINBINDD_OK; } +static void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num) +{ + int i; + + if ((*num) >= groups_max()) + return; + + for (i=0; i<*num; i++) { + if ((*gids)[i] == gid) + return; + } + + *gids = Realloc(*gids, (*num+1) * sizeof(gid_t)); + + if (*gids == NULL) + return; + + (*gids)[*num] = gid; + *num += 1; +} + +static void add_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num) +{ + gid_t gid; + DOM_SID *aliases; + int j, num_aliases; + + DEBUG(10, ("Adding gids from SID: %s\n", sid_string_static(sid))); + + if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0))) + add_gid_to_array_unique(gid, gids, num); + + /* Don't expand aliases if not explicitly activated -- for now */ + /* we don't support windows local nested groups if we are a DC. + refer to to sid_to_gid() in the smbd server code to see why + -- jerry */ + + if (!lp_winbind_nested_groups() || IS_DC) + return; + + /* Add nested group memberships */ + + if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + return; + + for (j=0; j<num_aliases; j++) { + + if (!NT_STATUS_IS_OK(sid_to_gid(&aliases[j], &gid))) + continue; + + add_gid_to_array_unique(gid, gids, num); + } + SAFE_FREE(aliases); +} + /* Get user supplementary groups. This is much quicker than trying to invert the groups database. We merge the groups from the gids and other_sids info3 fields as trusted domain, universal group @@ -915,7 +985,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) DOM_SID **user_grpsids; struct winbindd_domain *domain; enum winbindd_result result = WINBINDD_ERROR; - gid_t *gid_list; + gid_t *gid_list = NULL; unsigned int i; TALLOC_CTX *mem_ctx; NET_USER_INFO_3 *info3 = NULL; @@ -963,6 +1033,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; } + add_gids_from_sid(&user_sid, &gid_list, &num_gids); + /* Treat the info3 cache as authoritative as the lookup_usergroups() function may return cached data. */ @@ -972,7 +1044,6 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) info3->num_groups2, info3->num_other_sids)); num_groups = info3->num_other_sids + info3->num_groups2; - gid_list = calloc(sizeof(gid_t), num_groups); /* Go through each other sid and convert it to a gid */ @@ -1006,23 +1077,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) continue; } - /* Map to a gid */ + add_gids_from_sid(&info3->other_sids[i].sid, + &gid_list, &num_gids); - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&info3->other_sids[i].sid, &gid_list[num_gids], 0)) ) - { - DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n", - sid_string_static(&info3->other_sids[i].sid))); - continue; - } - - /* We've jumped through a lot of hoops to get here */ - - DEBUG(10, ("winbindd_getgroups: mapped other sid %s to " - "gid %lu\n", sid_string_static( - &info3->other_sids[i].sid), - (unsigned long)gid_list[num_gids])); - - num_gids++; + if (gid_list == NULL) + goto done; } for (i = 0; i < info3->num_groups2; i++) { @@ -1032,12 +1091,10 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) sid_copy( &group_sid, &domain->sid ); sid_append_rid( &group_sid, info3->gids[i].g_rid ); - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid_list[num_gids], 0)) ) { - DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n", - sid_string_static(&group_sid))); - } + add_gids_from_sid(&group_sid, &gid_list, &num_gids); - num_gids++; + if (gid_list == NULL) + goto done; } SAFE_FREE(info3); @@ -1049,18 +1106,15 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) if (!NT_STATUS_IS_OK(status)) goto done; - gid_list = malloc(sizeof(gid_t) * num_groups); - if (state->response.extra_data) goto done; for (i = 0; i < num_groups; i++) { - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(user_grpsids[i], &gid_list[num_gids], 0))) { - DEBUG(1, ("unable to convert group sid %s to gid\n", - sid_string_static(user_grpsids[i]))); - continue; - } - num_gids++; + add_gids_from_sid(user_grpsids[i], + &gid_list, &num_gids); + + if (gid_list == NULL) + goto done; } } diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h index 73b39569a96..8167cfafa86 100644 --- a/source/nsswitch/winbindd_nss.h +++ b/source/nsswitch/winbindd_nss.h @@ -84,6 +84,7 @@ enum winbindd_cmd { WINBINDD_SID_TO_GID, WINBINDD_UID_TO_SID, WINBINDD_GID_TO_SID, + WINBINDD_ALLOCATE_RID, /* Miscellaneous other stuff */ @@ -270,7 +271,7 @@ struct winbindd_response { char user_session_key[16]; char first_8_lm_hash[8]; } auth; - uint32 rid; /* create user or group */ + uint32 rid; /* create user or group or allocate rid */ struct { fstring name; fstring alt_name; diff --git a/source/nsswitch/winbindd_passdb.c b/source/nsswitch/winbindd_passdb.c new file mode 100644 index 00000000000..36f5297efeb --- /dev/null +++ b/source/nsswitch/winbindd_passdb.c @@ -0,0 +1,339 @@ +/* + Unix SMB/CIFS implementation. + + Winbind rpc backend functions + + Copyright (C) Tim Potter 2000-2001,2003 + Copyright (C) Simo Sorce 2003 + Copyright (C) Volker Lendecke 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "winbindd.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_WINBIND + +static void +add_member(const char *domain, const char *user, + char **members, int *num_members) +{ + fstring name; + + fill_domain_username(name, domain, user); + safe_strcat(name, ",", sizeof(name)-1); + string_append(members, name); + *num_members += 1; +} + +/********************************************************************** + Add member users resulting from sid. Expand if it is a domain group. +**********************************************************************/ + +static void +add_expanded_sid(const DOM_SID *sid, char **members, int *num_members) +{ + DOM_SID dom_sid; + uint32 rid; + struct winbindd_domain *domain; + int i; + + char *name = NULL; + enum SID_NAME_USE type; + + uint32 num_names; + DOM_SID **sid_mem; + char **names; + uint32 *types; + + NTSTATUS result; + + TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid"); + + if (mem_ctx == NULL) { + DEBUG(1, ("talloc_init failed\n")); + return; + } + + sid_copy(&dom_sid, sid); + sid_split_rid(&dom_sid, &rid); + + domain = find_domain_from_sid(&dom_sid); + + if (domain == NULL) { + DEBUG(3, ("Could not find domain for sid %s\n", + sid_string_static(sid))); + goto done; + } + + result = domain->methods->sid_to_name(domain, mem_ctx, sid, + &name, &type); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("sid_to_name failed for sid %s\n", + sid_string_static(sid))); + goto done; + } + + DEBUG(10, ("Found name %s, type %d\n", name, type)); + + if (type == SID_NAME_USER) { + add_member(domain->name, name, members, num_members); + goto done; + } + + if (type != SID_NAME_DOM_GRP) { + DEBUG(10, ("Alias member %s neither user nor group, ignore\n", + name)); + goto done; + } + + /* Expand the domain group */ + + result = domain->methods->lookup_groupmem(domain, mem_ctx, + sid, &num_names, + &sid_mem, &names, + &types); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10, ("Could not lookup group members for %s: %s\n", + name, nt_errstr(result))); + goto done; + } + + for (i=0; i<num_names; i++) { + DEBUG(10, ("Adding group member SID %s\n", + sid_string_static(sid_mem[i]))); + + if (types[i] != SID_NAME_USER) { + DEBUG(1, ("Hmmm. Member %s of group %s is no user. " + "Ignoring.\n", names[i], name)); + continue; + } + + add_member(domain->name, names[i], members, num_members); + } + + done: + talloc_destroy(mem_ctx); + return; +} + +BOOL fill_passdb_alias_grmem(struct winbindd_domain *domain, + DOM_SID *group_sid, + int *num_gr_mem, char **gr_mem, int *gr_mem_len) +{ + DOM_SID *members; + int i, num_members; + + *num_gr_mem = 0; + *gr_mem = NULL; + *gr_mem_len = 0; + + if (!pdb_enum_aliasmem(group_sid, &members, &num_members)) + return True; + + for (i=0; i<num_members; i++) { + add_expanded_sid(&members[i], gr_mem, num_gr_mem); + } + + SAFE_FREE(members); + + if (*gr_mem != NULL) { + int len; + + /* We have at least one member, strip off the last "," */ + len = strlen(*gr_mem); + (*gr_mem)[len-1] = '\0'; + *gr_mem_len = len; + } + + return True; +} + +/* Query display info for a domain. This returns enough information plus a + bit extra to give an overview of domain users for the User Manager + application. */ +static NTSTATUS query_user_list(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_entries, + WINBIND_USERINFO **info) +{ + /* We don't have users */ + *num_entries = 0; + *info = NULL; + return NT_STATUS_OK; +} + +/* list all domain groups */ +static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_entries, + struct acct_info **info) +{ + /* We don't have domain groups */ + *num_entries = 0; + *info = NULL; + return NT_STATUS_OK; +} + +/* List all domain groups */ + +static NTSTATUS enum_local_groups(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_entries, + struct acct_info **info) +{ + struct acct_info *talloced_info; + + /* Hmm. One billion aliases should be enough for a start */ + + if (!pdb_enum_aliases(&domain->sid, 0, 1000000000, + num_entries, info)) { + /* Nothing to report, just exit. */ + return NT_STATUS_OK; + } + + talloced_info = (struct acct_info *) + talloc_memdup(mem_ctx, *info, + *num_entries * sizeof(struct acct_info)); + + SAFE_FREE(*info); + *info = talloced_info; + + return NT_STATUS_OK; +} + +/* convert a single name to a sid in a domain */ +static NTSTATUS name_to_sid(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const char *name, + DOM_SID *sid, + enum SID_NAME_USE *type) +{ + DEBUG(10, ("Finding name %s\n", name)); + + if (!pdb_find_alias(name, sid)) + return NT_STATUS_NONE_MAPPED; + + *type = SID_NAME_ALIAS; + return NT_STATUS_OK; +} + +/* + convert a domain SID to a user or group name +*/ +static NTSTATUS sid_to_name(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + char **name, + enum SID_NAME_USE *type) +{ + struct acct_info info; + + DEBUG(10, ("Converting SID %s\n", sid_string_static(sid))); + + if (!pdb_get_aliasinfo(sid, &info)) + return NT_STATUS_NONE_MAPPED; + + *name = talloc_strdup(mem_ctx, info.acct_name); + *type = SID_NAME_ALIAS; + + return NT_STATUS_OK; +} + +/* Lookup user information from a rid or username. */ +static NTSTATUS query_user(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *user_sid, + WINBIND_USERINFO *user_info) +{ + return NT_STATUS_NO_SUCH_USER; +} + +/* Lookup groups a user is a member of. I wish Unix had a call like this! */ +static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *user_sid, + uint32 *num_groups, DOM_SID ***user_gids) +{ + return NT_STATUS_NO_SUCH_USER; +} + + +/* Lookup group membership given a rid. */ +static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *group_sid, uint32 *num_names, + DOM_SID ***sid_mem, char ***names, + uint32 **name_types) +{ + return NT_STATUS_OK; +} + +/* find the sequence number for a domain */ +static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) +{ + *seq = 1; + return NT_STATUS_OK; +} + +/* get a list of trusted domains */ +static NTSTATUS trusted_domains(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 *num_domains, + char ***names, + char ***alt_names, + DOM_SID **dom_sids) +{ + return NT_STATUS_OK; +} + +/* find the domain sid for a domain */ +static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid) +{ + sid_copy(sid, &domain->sid); + return NT_STATUS_OK; +} + +/* find alternate names list for the domain + * should we look for netbios aliases?? + SSS */ +static NTSTATUS alternate_name(struct winbindd_domain *domain) +{ + DEBUG(3,("pdb: alternate_name\n")); + + return NT_STATUS_OK; +} + + +/* the rpc backend methods are exposed via this structure */ +struct winbindd_methods passdb_methods = { + False, + query_user_list, + enum_dom_groups, + enum_local_groups, + name_to_sid, + sid_to_name, + query_user, + lookup_usergroups, + lookup_groupmem, + sequence_number, + trusted_domains, + domain_sid, + alternate_name +}; diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c index 9fbf47046d6..d4206558c5e 100644 --- a/source/nsswitch/winbindd_sid.c +++ b/source/nsswitch/winbindd_sid.c @@ -30,10 +30,8 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) { - extern DOM_SID global_sid_Builtin; enum SID_NAME_USE type; - DOM_SID sid, tmp_sid; - uint32 rid; + DOM_SID sid; fstring name; fstring dom_name; @@ -50,15 +48,6 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - /* Don't look up BUILTIN sids */ - - sid_copy(&tmp_sid, &sid); - sid_split_rid(&tmp_sid, &rid); - - if (sid_equal(&tmp_sid, &global_sid_Builtin)) { - return WINBINDD_ERROR; - } - /* Lookup the sid */ if (!winbindd_lookup_name_by_sid(&sid, dom_name, name, &type)) { @@ -445,3 +434,23 @@ done: return WINBINDD_OK; } + +enum winbindd_result winbindd_allocate_rid(struct winbindd_cli_state *state) +{ + if ( !state->privileged ) { + DEBUG(2, ("winbindd_allocate_rid: non-privileged access " + "denied!\n")); + return WINBINDD_ERROR; + } + + /* We tell idmap to always allocate a user RID. There might be a good + * reason to keep RID allocation for users to even and groups to + * odd. This needs discussion I think. For now only allocate user + * rids. */ + + if (!NT_STATUS_IS_OK(idmap_allocate_rid(&state->response.data.rid, + USER_RID_TYPE))) + return WINBINDD_ERROR; + + return WINBINDD_OK; +} diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c index 403ba399c88..1a01f1c05e6 100644 --- a/source/nsswitch/winbindd_util.c +++ b/source/nsswitch/winbindd_util.c @@ -83,6 +83,20 @@ void free_domain_list(void) } } +static BOOL is_internal_domain(const DOM_SID *sid) +{ + DOM_SID tmp_sid; + + if (sid_equal(sid, get_global_sam_sid())) + return True; + + string_to_sid(&tmp_sid, "S-1-5-32"); + if (sid_equal(sid, &tmp_sid)) + return True; + + return False; +} + /* Add a trusted domain to our list of domains */ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, @@ -143,6 +157,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const domain->methods = methods; domain->backend = NULL; + domain->internal = is_internal_domain(sid); domain->sequence_number = DOM_SEQUENCE_NONE; domain->last_seq_check = 0; if (sid) { @@ -150,8 +165,9 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const } /* set flags about native_mode, active_directory */ - - set_dc_type_and_flags( domain ); + + if (!domain->internal) + set_dc_type_and_flags( domain ); DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name, domain->active_directory ? "ADS" : "NT4", @@ -303,6 +319,29 @@ BOOL init_domain_list(void) /* do an initial scan for trusted domains */ add_trusted_domains(domain); + + /* Don't expand aliases if not explicitly activated -- for now */ + /* we don't support windows local nested groups if we are a DC. + refer to to sid_to_gid() in the smbd server code to see why + -- jerry */ + + + if (lp_winbind_nested_groups() || IS_DC) { + + /* Add our local SAM domains */ + DOM_SID sid; + extern struct winbindd_methods passdb_methods; + struct winbindd_domain *dom; + + string_to_sid(&sid, "S-1-5-32"); + + dom = add_trusted_domain("BUILTIN", NULL, &passdb_methods, + &sid); + + dom = add_trusted_domain(get_global_sam_name(), NULL, + &passdb_methods, + get_global_sam_sid()); + } /* avoid rescanning this right away */ last_trustdom_scan = time(NULL); |