Merge removal of unpopular winbind client environment variable.
[tprouty/samba.git] / source / nsswitch / winbindd_group.c
index 94aae73baf5b6526195340403abaab7b7dcfb6bd..ab6268583f74d86c41db20f42544cd5c15b1ecbd 100644 (file)
@@ -75,7 +75,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
        *num_gr_mem = 0;
        
        if (group_name_type != SID_NAME_DOM_GRP) {
-               DEBUG(1, ("rid %d in domain %s isn't a " "domain group\n", 
+               DEBUG(1, ("rid %d in domain %s isn't a domain group\n", 
                          group_rid, domain->name));
                 goto done;
        }
@@ -84,8 +84,8 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
        status = domain->methods->lookup_groupmem(domain, mem_ctx, group_rid, &num_names, 
                                                  &rid_mem, &names, &name_types);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("could not lookup membership for group rid %d in domain %s\n", 
-                         group_rid, domain->name));
+               DEBUG(1, ("could not lookup membership for group rid %d in domain %s (error: %s)\n", 
+                         group_rid, domain->name, nt_errstr(status)));
 
                goto done;
        }
@@ -196,6 +196,9 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
        gid_t gid;
        int gr_mem_len;
        
+       /* Ensure null termination */
+       state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
+
        DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
                  state->request.data.groupname));
 
@@ -353,18 +356,13 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
        for (domain = domain_list(); domain != NULL; domain = domain->next) {
                struct getent_state *domain_state;
                
-               /* Skip domains other than WINBINDD_DOMAIN environment 
-                  variable */
-               
-               if ((strcmp(state->request.domain, "") != 0) &&
-                   !check_domain_env(state->request.domain, domain->name))
-                       continue;
-               
                /* Create a state record for this domain */
                
                if ((domain_state = (struct getent_state *)
-                    malloc(sizeof(struct getent_state))) == NULL)
+                    malloc(sizeof(struct getent_state))) == NULL) {
+                       DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n"));
                        return WINBINDD_ERROR;
+               }
                
                ZERO_STRUCTP(domain_state);
                
@@ -401,7 +399,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
 {
        NTSTATUS status;
        uint32 num_entries;
-       struct acct_info *name_list = NULL;
+       struct acct_info *name_list = NULL, *tmp_name_list = NULL;
        TALLOC_CTX *mem_ctx;
        BOOL result = False;
        struct acct_info *sam_grp_entries = NULL;
@@ -411,8 +409,10 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
                return False;
 
        if (!(mem_ctx = talloc_init_named("get_sam_group_entries(%s)",
-                                         ent->domain_name)))
+                                         ent->domain_name))) {
+               DEBUG(1, ("get_sam_group_entries: could not create talloc context!\n")); 
                return False;
+       }
                
        /* Free any existing group info */
 
@@ -429,12 +429,12 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
                goto done;
        }
 
-       status = domain->methods->enum_dom_groups(domain,
-                                                 mem_ctx, 
-                                                 &num_entries,
-                                                 &sam_grp_entries);
+       /* always get the domain global groups */
+
+       status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
        
        if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(3, ("get_sam_group_entries: could not enumerate domain groups! Error: %s", nt_errstr(status)));
                result = False;
                goto done;
        }
@@ -442,12 +442,54 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
        /* Copy entries into return buffer */
 
        if (num_entries) {
-               name_list = malloc(sizeof(struct acct_info) * num_entries);
-               memcpy(name_list, sam_grp_entries, 
-                      num_entries * sizeof(struct acct_info));
+               if ( !(name_list = malloc(sizeof(struct acct_info) * num_entries)) ) {
+                       DEBUG(0,("get_sam_group_entries: Failed to malloc memory for %d domain groups!\n", 
+                               num_entries));
+                       result = False;
+                       goto done;
+               }
+               memcpy( name_list, sam_grp_entries, num_entries * sizeof(struct acct_info) );
        }
        
        ent->num_sam_entries = num_entries;
+       
+       /* get the domain local groups if we are a member of 
+          a native win2k domain */
+          
+       if ( domain->native_mode && domain->methods->enum_local_groups )
+       {
+               DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n"));
+               
+               status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
+               
+               if ( !NT_STATUS_IS_OK(status) ) { 
+                       DEBUG(3,("get_sam_group_entries: Failed to enumerate domain local groups!\n"));
+                       num_entries = 0;
+               }
+               else
+                       DEBUG(4,("get_sam_group_entries: Returned %d local groups\n", num_entries));
+               
+               /* Copy entries into return buffer */
+
+               if ( num_entries ) {
+                       if ( !(tmp_name_list = Realloc( name_list, sizeof(struct acct_info) * (ent->num_sam_entries+num_entries))) )
+                       {
+                               DEBUG(0,("get_sam_group_entries: Failed to realloc more memory for %d local groups!\n", 
+                                       num_entries));
+                               result = False;
+                               SAFE_FREE( name_list );
+                               goto done;
+                       }
+                       
+                       name_list = tmp_name_list;
+                               
+                       memcpy( &name_list[ent->num_sam_entries], sam_grp_entries, 
+                               num_entries * sizeof(struct acct_info) );
+               }
+       
+               ent->num_sam_entries += num_entries;
+       }
+       
                
        /* Fill in remaining fields */
 
@@ -575,14 +617,21 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
                                goto done;
                        }
 
-                       /* Get group membership */
+                       group_list[group_list_ndx].num_gr_mem = 0;
+                       gr_mem = NULL;
+                       gr_mem_len = 0;
                        
-                       result = fill_grent_mem(
-                               domain,
-                               name_list[ent->sam_entry_index].rid,
-                               SID_NAME_DOM_GRP,
-                               &group_list[group_list_ndx].num_gr_mem, 
-                               &gr_mem, &gr_mem_len);
+                       /* Get group membership */                      
+                       if (state->request.cmd == WINBINDD_GETGRLST) {
+                               result = True;
+                       } else {
+                               result = fill_grent_mem(
+                                       domain,
+                                       name_list[ent->sam_entry_index].rid,
+                                       SID_NAME_DOM_GRP,
+                                       &group_list[group_list_ndx].num_gr_mem, 
+                                       &gr_mem, &gr_mem_len);
+                       }
                }
 
                if (result) {
@@ -692,12 +741,6 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
 
                ZERO_STRUCT(groups);
 
-               /* Skip domains other than WINBINDD_DOMAIN environment
-                  variable */ 
-               if ((strcmp(state->request.domain, "") != 0) &&
-                   !check_domain_env(state->request.domain, domain->name))
-                       continue;
-
                /* Get list of sam groups */
                ZERO_STRUCT(groups);
                fstrcpy(groups.domain_name, domain->name);
@@ -771,6 +814,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
        int i;
        TALLOC_CTX *mem_ctx;
        
+       /* Ensure null termination */
+       state->request.data.username[sizeof(state->request.data.username)-1]='\0';
+
        DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
                  state->request.data.username));