summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-03-01 00:14:45 +0000
committerJeremy Allison <jra@samba.org>2001-03-01 00:14:45 +0000
commit011422ab5a45570d92740f4e11d1104296e38c9b (patch)
treee0bb5bcb1fcd3c8200cccab6ca58a6654f85de23
parent30d74f54e6d6c876d3a6b8258b2c0cab1b5a3ef3 (diff)
downloadsamba-011422ab5a45570d92740f4e11d1104296e38c9b.tar.gz
samba-011422ab5a45570d92740f4e11d1104296e38c9b.tar.bz2
samba-011422ab5a45570d92740f4e11d1104296e38c9b.zip
Ensure that SPOOL_NOTIFY_OPTION structs are safely copied out of the talloc
area into the Printer_entry struct - these are used for changenotification. Jeremy. (This used to be commit 4c2a49168e53b5ed96d61c6bae908086c3852f64)
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 8e7e3c28e5..d17082b880 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -133,6 +133,55 @@ static int nt_printq_status(int v)
}
/****************************************************************************
+ Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
+****************************************************************************/
+
+static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
+{
+ SPOOL_NOTIFY_OPTION *sp = *pp;
+
+ *pp = NULL;
+
+ if (!sp)
+ return;
+
+ if (sp->ctr.type)
+ safe_free(sp->ctr.type);
+
+ free(sp);
+
+}
+
+/****************************************************************************
+ Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
+****************************************************************************/
+
+SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
+{
+ SPOOL_NOTIFY_OPTION *new_sp = malloc(sizeof(SPOOL_NOTIFY_OPTION));
+
+ if (!sp)
+ return NULL;
+
+ new_sp = (SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
+ if (!new_sp)
+ return NULL;
+
+ *new_sp = *sp;
+
+ if (sp->ctr.count) {
+ new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
+
+ if (!new_sp->ctr.type) {
+ safe_free(new_sp);
+ return NULL;
+ }
+ }
+
+ return new_sp;
+}
+
+/****************************************************************************
initialise printer handle states...
****************************************************************************/
void init_printer_hnd(void)
@@ -241,6 +290,7 @@ static BOOL srv_spoolss_replycloseprinter(POLICY_HND *handle)
/****************************************************************************
close printer index by handle
****************************************************************************/
+
static BOOL close_printer_handle(POLICY_HND *hnd)
{
Printer_entry *Printer = find_printer_index_by_hnd(hnd);
@@ -259,8 +309,7 @@ static BOOL close_printer_handle(POLICY_HND *hnd)
Printer->notify.options=0;
Printer->notify.localmachine[0]='\0';
Printer->notify.printerlocal=0;
- safe_free(Printer->notify.option);
- Printer->notify.option=NULL;
+ free_spool_notify_option(&Printer->notify.option);
Printer->notify.client_connected=False;
clear_handle(hnd);
@@ -1316,9 +1365,14 @@ uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
}
Printer->notify.flags=flags;
- Printer->notify.options=options;
Printer->notify.printerlocal=printerlocal;
- Printer->notify.option=option;
+
+ if (Printer->notify.option)
+ free_spool_notify_option(&Printer->notify.option);
+
+ Printer->notify.options=options;
+ Printer->notify.option=dup_spool_notify_option(option);
+
unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
/* connect to the client machine and send a ReplyOpenPrinter */
@@ -2272,8 +2326,7 @@ static uint32 printserver_notify_info(const POLICY_HND *hnd,
for (snum=0; snum<n_services; snum++)
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- if (construct_notify_printer_info
- (info, snum, option_type, id, mem_ctx))
+ if (construct_notify_printer_info(info, snum, option_type, id, mem_ctx))
id++;
}
@@ -2328,9 +2381,7 @@ static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
switch ( option_type->type ) {
case PRINTER_NOTIFY_TYPE:
- if(construct_notify_printer_info(info, snum,
- option_type, id,
- mem_ctx))
+ if(construct_notify_printer_info(info, snum, option_type, id, mem_ctx))
id--;
break;
@@ -2340,8 +2391,7 @@ static uint32 printer_notify_info(POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
memset(&status, 0, sizeof(status));
count = print_queue_status(snum, &queue, &status);
- if (get_a_printer(&printer, 2,
- lp_servicename(snum)) != 0)
+ if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
goto done;
for (j=0; j<count; j++) {
@@ -4602,9 +4652,7 @@ uint32 _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
Printer->notify.localmachine[0]='\0';
Printer->notify.printerlocal=0;
if (Printer->notify.option)
- safe_free(Printer->notify.option->ctr.type);
- safe_free(Printer->notify.option);
- Printer->notify.option=NULL;
+ free_spool_notify_option(&Printer->notify.option);
Printer->notify.client_connected=False;
return NT_STATUS_NO_PROBLEMO;