diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/ntdomain.h | 7 | ||||
-rw-r--r-- | source3/include/proto.h | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_hnd.c | 94 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 8 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 53 |
5 files changed, 120 insertions, 44 deletions
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 799fa6d907..f56b765d29 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -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; diff --git a/source3/include/proto.h b/source3/include/proto.h index 006b26cf05..331d080f54 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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); diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c index bcc3878d86..d0a26abc6b 100644 --- a/source3/rpc_server/srv_lsa_hnd.c +++ b/source3/rpc_server/srv_lsa_hnd.c @@ -25,19 +25,63 @@ 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 )); + } } diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index ed1f9d36db..893bc8cb88 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -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); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 9fcf9930bf..804fe8a523 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -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); } } |