Move to a handle database per pipe name, not per pipe.
authorJeremy Allison <jra@samba.org>
Tue, 13 Mar 2001 20:18:45 +0000 (20:18 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 13 Mar 2001 20:18:45 +0000 (20:18 +0000)
Jeremy.

source/include/ntdomain.h
source/include/proto.h
source/rpc_server/srv_lsa_hnd.c
source/rpc_server/srv_pipe_hnd.c
source/rpc_server/srv_spoolss_nt.c

index 799fa6d90726eef79ae1c708e22db3819423afe0..f56b765d291a678703da1d8c36c6ae604db621e5 100644 (file)
@@ -153,8 +153,9 @@ struct policy
 };
 
 struct handle_list {
-       struct policy *Policy;
-       size_t count;
+       struct policy *Policy;  /* List of policies. */
+       size_t count;                   /* Current number of handles. */
+       size_t pipe_ref_count;  /* Number of pipe handles referring to this list. */
 };
 
 /* Domain controller authentication protocol info */
@@ -246,7 +247,7 @@ typedef struct pipes_struct
        TALLOC_CTX *mem_ctx;
 
        /* handle database to use on this pipe. */
-       struct handle_list pipe_handles;
+       struct handle_list *pipe_handles;
 
 } pipes_struct;
 
index 006b26cf054de81a40573aaa343ceed331397835..331d080f5472634d558422bec4d5a67d219b4338 100644 (file)
@@ -3454,7 +3454,7 @@ BOOL api_ntlsa_rpc(pipes_struct *p);
 
 /*The following definitions come from  rpc_server/srv_lsa_hnd.c  */
 
-void init_pipe_handles(pipes_struct *p);
+BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name);
 BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *), void *data_ptr);
 BOOL find_policy_by_hnd(pipes_struct *p, POLICY_HND *hnd, void **data_p);
 BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd);
index bcc3878d863d652d3fd422bdfa7f3bc89da1b599..d0a26abc6b6638b1fe4423fd819515fc1ef26c43 100644 (file)
 
 extern int DEBUGLEVEL;
 
-/* This is the max handles per pipe. */
+/* This is the max handles across all instances of a pipe name. */
 #ifndef MAX_OPEN_POLS
-#define MAX_OPEN_POLS 256
+#define MAX_OPEN_POLS 1024
 #endif
 
 /****************************************************************************
-  initialise policy handle states...
+ Initialise a policy handle list on a pipe. Handle list is shared between all
+ pipes of the same name.
 ****************************************************************************/
 
-void init_pipe_handles(pipes_struct *p)
+BOOL init_pipe_handle_list(pipes_struct *p, char *pipe_name)
 {
-       p->pipe_handles.Policy = NULL;
-       p->pipe_handles.count = 0;
+       pipes_struct *plist = get_first_pipe();
+       struct handle_list *hl = NULL;
+
+       for (plist = get_first_pipe(); plist; plist = get_next_pipe(plist)) {
+               if (strequal( plist->name, pipe_name)) {
+                       if (!plist->pipe_handles) {
+                               pstring msg;
+                               slprintf(msg, sizeof(msg)-1, "init_pipe_handles: NULL pipe_handle pointer in pipe %s",
+                                               pipe_name );
+                               smb_panic(msg);
+                       }
+                       hl = plist->pipe_handles;
+                       break;
+               }
+       }
+
+       if (!hl) {
+               /*
+                * No handle list for this pipe (first open of pipe).
+                * Create list.
+                */
+
+               if ((hl = (struct handle_list *)malloc(sizeof(struct handle_list))) == NULL)
+                       return False;
+               ZERO_STRUCTP(hl);
+
+               DEBUG(10,("init_pipe_handles: created handle list for pipe %s\n", pipe_name ));
+       }
+
+       /*
+        * One more pipe is using this list.
+        */
+
+       hl->pipe_ref_count++;
+
+       /*
+        * Point this pipe at this list.
+        */
+
+       p->pipe_handles = hl;
+
+       DEBUG(10,("init_pipe_handles: pipe_handles ref count = %u for pipe %s\n",
+                       p->pipe_handles->pipe_ref_count, pipe_name ));
+
+       return True;
 }
 
 /****************************************************************************
@@ -51,8 +95,9 @@ BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *)
 
        struct policy *pol;
 
-       if (p->pipe_handles.count > MAX_OPEN_POLS) {
-               DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n", (int)p->pipe_handles.count));
+       if (p->pipe_handles->count > MAX_OPEN_POLS) {
+               DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n",
+                               (int)p->pipe_handles->count));
                return False;
        }
 
@@ -78,12 +123,12 @@ BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *)
     SIVAL(pol->pol_hnd.data5, 0, time(NULL)); /* something random */
     SIVAL(pol->pol_hnd.data5, 4, sys_getpid()); /* something more random */
 
-       DLIST_ADD(p->pipe_handles.Policy, pol);
-       p->pipe_handles.count++;
+       DLIST_ADD(p->pipe_handles->Policy, pol);
+       p->pipe_handles->count++;
 
        *hnd = pol->pol_hnd;
        
-       DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles.count));
+       DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
        dump_data(4, (char *)hnd, sizeof(*hnd));
 
        return True;
@@ -101,7 +146,7 @@ static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *h
        if (data_p)
                *data_p = NULL;
 
-       for (i = 0, pol=p->pipe_handles.Policy;pol;pol=pol->next, i++) {
+       for (i = 0, pol=p->pipe_handles->Policy;pol;pol=pol->next, i++) {
                if (memcmp(&pol->pol_hnd, hnd, sizeof(*hnd)) == 0) {
                        DEBUG(4,("Found policy hnd[%d] ", (int)i));
                        dump_data(4, (char *)hnd, sizeof(*hnd));
@@ -144,9 +189,9 @@ BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd)
        if (pol->free_fn && pol->data_ptr)
                (*pol->free_fn)(pol->data_ptr);
 
-       pol->p->pipe_handles.count--;
+       pol->p->pipe_handles->count--;
 
-       DLIST_REMOVE(pol->p->pipe_handles.Policy, pol);
+       DLIST_REMOVE(pol->p->pipe_handles->Policy, pol);
 
        ZERO_STRUCTP(pol);
 
@@ -156,14 +201,25 @@ BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd)
 }
 
 /****************************************************************************
- Close all the pipe handles.
+ Close a pipe - free the handle list if it was the last pipe reference.
 ****************************************************************************/
 
 void close_policy_by_pipe(pipes_struct *p)
 {
-       while (p->pipe_handles.Policy)
-               close_policy_hnd(p, &p->pipe_handles.Policy->pol_hnd);
+       p->pipe_handles->pipe_ref_count--;
+
+       if (p->pipe_handles->pipe_ref_count == 0) {
+               /*
+                * Last pipe open on this list - free the list.
+                */
+               while (p->pipe_handles->Policy)
+                       close_policy_hnd(p, &p->pipe_handles->Policy->pol_hnd);
 
-       p->pipe_handles.Policy = NULL;
-       p->pipe_handles.count = 0;
+               p->pipe_handles->Policy = NULL;
+               p->pipe_handles->count = 0;
+
+               free(p->pipe_handles);
+               p->pipe_handles = NULL;
+               DEBUG(10,("close_policy_by_pipe: deleted handle list for pipe %s\n", p->name ));
+       }
 }
index ed1f9d36db56d0cfb95a7d5d3c6431657620a831..893bc8cb8842213c7aa90acba9584b0db6d985ec 100644 (file)
@@ -163,7 +163,13 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
                return NULL;
        }
 
-       init_pipe_handles(p);
+       if (!init_pipe_handle_list(p, pipe_name)) {
+               DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
+               talloc_destroy(p->mem_ctx);
+               free(p);
+               return NULL;
+       }
+
 
        DLIST_ADD(Pipes, p);
 
index 9fcf9930bf4b68f9c685f31c10d7462c2f799409..804fe8a523dab77d1f524bd504e00f8ae7fcdc69 100644 (file)
@@ -569,7 +569,7 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name)
                return False;
        }
 
-       DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles.count ));
+       DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
 
        return True;
 }
@@ -634,6 +634,8 @@ void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
        fstring printer;
        uint32 status;
        struct pipes_struct *p;
+       struct policy *pol;
+       struct handle_list *hl;
 
        *printer = '\0';
        fstrcpy(printer,buf);
@@ -645,32 +647,43 @@ void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
 
        DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer ));
 
-       /* We need to enumerate all our pipes and all printers on them. */
+       /*
+        * We need to enumerate all printers. The handle list is shared
+        * across pipes of the same name, so just find the first open
+        * spoolss pipe.
+        */
+
+       hl = NULL;      
        for ( p = get_first_pipe(); p; get_next_pipe(p)) {
-               struct policy *pol;
+               if (strequal(p->name, "spoolss")) {
+                       hl = p->pipe_handles;
+                       break;
+               }
+       }
 
-               if (!strequal(p->name, "spoolss"))
-                       continue;
+       if (!hl) {
+               DEBUG(0,("srv_spoolss_receive_message: no handle list on spoolss pipe !\n"));
+               return;
+       }
 
-               /* Iterate the printer list on this pipe. */
-               for (pol = p->pipe_handles.Policy; pol; pol = pol->next ) {
-                       Printer_entry *find_printer = (Printer_entry *)pol->data_ptr;
+       /* Iterate the printer list on this pipe. */
+       for (pol = hl->Policy; pol; pol = pol->next ) {
+               Printer_entry *find_printer = (Printer_entry *)pol->data_ptr;
 
-                       if (!find_printer)
-                               continue;
+               if (!find_printer)
+                       continue;
 
-                       /*
-                        * if the entry is the given printer or if it's a printerserver
-                        * we send the message
-                        */
+               /*
+                * if the entry is the given printer or if it's a printerserver
+                * we send the message
+                */
 
-                       if (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
-                               if (strcmp(find_printer->dev.handlename, printer))
-                                       continue;
+               if (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
+                       if (strcmp(find_printer->dev.handlename, printer))
+                               continue;
 
-                       if (find_printer->notify.client_connected==True)
-                               cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status);
-               }
+               if (find_printer->notify.client_connected==True)
+                       cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status);
        }
 }