merge from APP_HEAD
authorGerald Carter <jerry@samba.org>
Tue, 8 Oct 2002 18:29:57 +0000 (18:29 +0000)
committerGerald Carter <jerry@samba.org>
Tue, 8 Oct 2002 18:29:57 +0000 (18:29 +0000)
* s/driverlocation/comment
* detect native mode domain and enumerate local groups

Also

* Added sendfile stats from SAMBA_2_2
(This used to be commit 764b58e2c0b3179cffe157c0ab58761b156b8423)

source3/nsswitch/winbindd.h
source3/nsswitch/winbindd_cache.c
source3/nsswitch/winbindd_cm.c
source3/nsswitch/winbindd_group.c
source3/nsswitch/winbindd_rpc.c
source3/nsswitch/winbindd_util.c
source3/rpc_client/cli_pipe.c
source3/rpc_server/srv_spoolss_nt.c
source3/utils/status.c

index 4ca59ff1cccf72fb44457c618e9b8c3cd7ff9d58..e8bcf76bd3bf26fd12f2b7b53aa448c935b7ab5d 100644 (file)
@@ -123,12 +123,18 @@ struct winbindd_methods {
                                   uint32 *num_entries, 
                                   WINBIND_USERINFO **info);
 
-       /* get a list of groups */
+       /* get a list of domain groups */
        NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain,
                                    TALLOC_CTX *mem_ctx,
                                    uint32 *num_entries, 
                                    struct acct_info **info);
 
+       /* get a list of domain local groups */
+       NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain,
+                                   TALLOC_CTX *mem_ctx,
+                                   uint32 *num_entries, 
+                                   struct acct_info **info);
+                                   
        /* convert one user or group name to a sid */
        NTSTATUS (*name_to_sid)(struct winbindd_domain *domain,
                                const char *name,
index 060139af3ed1b0101203a7ac67bc70b606d40c05..8c02160e029d664ec183762a961a8bf0c0e1115b 100644 (file)
@@ -559,7 +559,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
 
        if (!cache->tdb) goto do_query;
 
-       centry = wcache_fetch(cache, domain, "GL/%s", domain->name);
+       centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
        if (!centry) goto do_query;
 
        *num_entries = centry_uint32(centry);
@@ -599,13 +599,83 @@ do_query:
                centry_put_string(centry, (*info)[i].acct_desc);
                centry_put_uint32(centry, (*info)[i].rid);
        }       
-       centry_end(centry, "GL/%s", domain->name);
+       centry_end(centry, "GL/%s/domain", domain->name);
        centry_free(centry);
 
 skip_save:
        return status;
 }
 
+/* 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 winbind_cache *cache = get_cache(domain);
+       struct cache_entry *centry = NULL;
+       NTSTATUS status;
+       int i;
+
+       if (!cache->tdb) goto do_query;
+
+       centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
+       if (!centry) goto do_query;
+
+       *num_entries = centry_uint32(centry);
+       
+       if (*num_entries == 0) goto do_cached;
+
+       (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
+       if (! (*info)) smb_panic("enum_dom_groups out of memory");
+       for (i=0; i<(*num_entries); i++) {
+               fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
+               fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
+               (*info)[i].rid = centry_uint32(centry);
+       }
+
+do_cached:     
+
+       /* If we are returning cached data and the domain controller
+          is down then we don't know whether the data is up to date
+          or not.  Return NT_STATUS_MORE_PROCESSING_REQUIRED to
+          indicate this. */
+
+       if (wcache_server_down(domain)) {
+               DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
+               status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+       } else
+               status = centry->status;
+
+       centry_free(centry);
+       return status;
+
+do_query:
+       *num_entries = 0;
+       *info = NULL;
+
+       if (wcache_server_down(domain)) {
+               return NT_STATUS_SERVER_DISABLED;
+       }
+
+       status = cache->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
+
+       /* and save it */
+       refresh_sequence_number(domain, True);
+       centry = centry_start(domain, status);
+       if (!centry) goto skip_save;
+       centry_put_uint32(centry, *num_entries);
+       for (i=0; i<(*num_entries); i++) {
+               centry_put_string(centry, (*info)[i].acct_name);
+               centry_put_string(centry, (*info)[i].acct_desc);
+               centry_put_uint32(centry, (*info)[i].rid);
+       }       
+       centry_end(centry, "GL/%s/local", domain->name);
+       centry_free(centry);
+
+skip_save:
+       return status;
+}
 
 /* convert a single name to a sid in a domain */
 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
@@ -906,6 +976,7 @@ struct winbindd_methods cache_methods = {
        True,
        query_user_list,
        enum_dom_groups,
+       enum_local_groups,
        name_to_sid,
        sid_to_name,
        query_user,
index def73edde63cabf3e0f24e35b7c430c7c459f24b..cb1779f59062c066356163f1e22cb464825d5bd5 100644 (file)
@@ -462,6 +462,15 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
        
        if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
                result = NT_STATUS_PIPE_NOT_AVAILABLE;
+               /* 
+                * only cache a failure if we are not trying to open the 
+                * **win2k** specific lsarpc UUID.  This could be an NT PDC 
+                * and therefore a failure is normal.  This should probably
+                * be abstracted to a check for 2k specific pipes and wondering
+                * if the PDC is an NT4 box.   but since there is only one 2k 
+                * specific UUID right now, i'm not going to bother.  --jerry
+                */
+               if ( !is_win2k_pipe(pipe_index) )
                add_failed_connection_entry(new_conn, result);
                cli_shutdown(new_conn->cli);
                return result;
@@ -563,7 +572,7 @@ BOOL cm_check_for_native_mode_win2k( const char *domain )
        
        if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) 
        {
-               DEBUG(3, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n", 
+               DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n", 
                          domain, nt_errstr(result)));
                return False;
        }
index abb6b9da75745b93b1fa846361442d161d221655..dc22be1754e7aa2556ea18fd10a485f54bb63e4f 100644 (file)
@@ -406,7 +406,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;
@@ -436,10 +436,9 @@ 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)));
@@ -450,12 +449,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 )
+       {
+               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 */
 
index 047280e21e48bc2c31a1c7a77dc4ea19e6192401..d3a418027d004b8d0516cb336dc178ea5d7586c7 100644 (file)
@@ -183,6 +183,65 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
        return status;
 }
 
+/* List all domain groups */
+
+static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
+                               TALLOC_CTX *mem_ctx,
+                               uint32 *num_entries, 
+                               struct acct_info **info)
+{
+       uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+       CLI_POLICY_HND *hnd;
+       POLICY_HND dom_pol;
+       NTSTATUS result;
+
+       *num_entries = 0;
+       *info = NULL;
+
+       if ( !(hnd = cm_get_sam_handle(domain->name)) )
+               return NT_STATUS_UNSUCCESSFUL;
+
+       if ( !NT_STATUS_IS_OK(result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol, 
+                                               des_access, &domain->sid, &dom_pol)) )
+       {
+               return result;
+       }
+
+       do {
+               struct acct_info *info2 = NULL;
+               uint32 count = 0, start = *num_entries;
+               TALLOC_CTX *mem_ctx2;
+
+               mem_ctx2 = talloc_init_named("enum_dom_local_groups[rpc]");
+
+               result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
+                                         &start, 0xFFFF, &info2, &count);
+                                         
+               if ( !NT_STATUS_IS_OK(result) 
+                       && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) 
+               {
+                       talloc_destroy(mem_ctx2);
+                       break;
+               }
+
+               (*info) = talloc_realloc(mem_ctx, *info, 
+                                        sizeof(**info) * ((*num_entries) + count));
+               if (! *info) {
+                       talloc_destroy(mem_ctx2);
+                       cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
+               (*num_entries) += count;
+               talloc_destroy(mem_ctx2);
+       } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
+
+       cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
+
+       return result;
+}
+
 /* convert a single name to a sid in a domain */
 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
                            const char *name,
@@ -635,6 +694,7 @@ struct winbindd_methods msrpc_methods = {
        False,
        query_user_list,
        enum_dom_groups,
+       enum_local_groups,
        name_to_sid,
        sid_to_name,
        query_user,
index 005b1609b64f7bf975e04b98bff0a2250d7b5b8f..00354187aa64ef0c9ff7c8229c8edacb0760196e 100644 (file)
@@ -128,7 +128,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
           
        if ( strequal( lp_workgroup(), domain_name) )   {
                domain->native_mode = cm_check_for_native_mode_win2k( domain_name );
-               DEBUG(5,("add_trusted_domain: %s is a %s mode domain\n", domain_name,
+               DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain_name,
                                        domain->native_mode ? "native" : "mixed" ));
        }       
 
index 7e1289edff63aba5651d9511f879c5b6b0352ac4..71e422f25196a1385fab944a9c1da490f43fe4f5 100644 (file)
@@ -983,6 +983,22 @@ char* get_pipe_name_from_index( const int pipe_index )
        return pipe_names[pipe_index].client_pipe;              
 }
 
+/****************************************************************************
+ Check to see if this pipe index points to one of 
+ the pipes only supported by Win2k
+ ****************************************************************************/
+
+BOOL is_win2k_pipe( const int pipe_idx )
+{
+       switch ( pipe_idx )
+       {
+               case PI_LSARPC_DS:
+                       return True;
+       }
+       
+       return False;
+}
+
 /****************************************************************************
  check the rpc bind acknowledge response
 ****************************************************************************/
index 41ef599a3c91e0d4e210c988cc38b2998dd72d05..2851ed79c6ea256dfc17442dcabd38787e939c1d 100644 (file)
@@ -5603,23 +5603,17 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
        char *cmd = lp_addprinter_cmd();
        char **qlines;
        pstring command;
-       pstring driverlocation;
        int numlines;
        int ret;
        int fd;
        fstring remote_machine = "%m";
 
-       /* build driver path... only 9X architecture is needed for legacy reasons */
-       slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
-                       get_called_name());
-       /* change \ to \\ for the shell */
-       all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
        standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
        
        slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
                        cmd, printer->info_2->printername, printer->info_2->sharename,
                        printer->info_2->portname, printer->info_2->drivername,
-                       printer->info_2->location, driverlocation, remote_machine);
+                       printer->info_2->location, printer->info_2->comment, remote_machine);
 
        DEBUG(10,("Running [%s]\n", command));
        ret = smbrun(command, &fd);
index 7fd7c93615e21e3a993768b3ee8bf35b9cb9a60d..c84f8c267ac5d409b3b17eb78b49a9ca9d7249af 100644 (file)
@@ -173,6 +173,11 @@ static int profile_dump(void)
        d_printf("write_count:                    %u\n", profile_p->syscall_write_count);
        d_printf("write_time:                     %u\n", profile_p->syscall_write_time);
        d_printf("write_bytes:                    %u\n", profile_p->syscall_write_bytes);
+#ifdef HAVE_SENDFILE
+       d_printf("sendfile_count:                 %u\n", profile_p->syscall_sendfile_count);
+       d_printf("sendfile_time:                  %u\n", profile_p->syscall_sendfile_time);
+       d_printf("sendfile_bytes:                 %u\n", profile_p->syscall_sendfile_bytes);
+#endif
        d_printf("lseek_count:                    %u\n", profile_p->syscall_lseek_count);
        d_printf("lseek_time:                     %u\n", profile_p->syscall_lseek_time);
        d_printf("rename_count:                   %u\n", profile_p->syscall_rename_count);