summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorJean-François Micouleau <jfm@samba.org>2000-02-26 22:22:24 +0000
committerJean-François Micouleau <jfm@samba.org>2000-02-26 22:22:24 +0000
commitbadee62bca8b81db7ede74ac8ea7710b14a07b4c (patch)
tree2155e29f174f7b445693248b761fe5dc4e095159 /source3/rpc_server
parent0f1eee5c7ac4031cd2a97524b1f65a24d0d618c2 (diff)
downloadsamba-badee62bca8b81db7ede74ac8ea7710b14a07b4c.tar.gz
samba-badee62bca8b81db7ede74ac8ea7710b14a07b4c.tar.bz2
samba-badee62bca8b81db7ede74ac8ea7710b14a07b4c.zip
rewrote enumprinterdata. still a bug in it but reproducing it hard and
borring. I need a client test program urgently!!! rewrote setprinter, doesn't coredump anymore, and no memleak. J.F. (This used to be commit b76ae1f92f4f12b38c4245456cdd2db970724077)
Diffstat (limited to 'source3/rpc_server')
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c37
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c213
2 files changed, 126 insertions, 124 deletions
diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c
index be6775f35d..d20f6c1616 100755
--- a/source3/rpc_server/srv_spoolss.c
+++ b/source3/rpc_server/srv_spoolss.c
@@ -444,8 +444,6 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *
/****************************************************************************
-FIX ME: JFM: freeing memory ????
-
****************************************************************************/
static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
{
@@ -460,13 +458,15 @@ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rd
return False;
}
- DEBUG(0,("api_spoolss_setprinter: typecast sec_des to uint8*!\n"));
- r_u.status = _spoolss_setprinter(&q_u.handle,
- q_u.level, &q_u.info,
- q_u.devmode,
- q_u.security.size_of_buffer,
- (const uint8*)q_u.security.data,
- q_u.command);
+ r_u.status = _spoolss_setprinter(&q_u.handle, q_u.level, &q_u.info,
+ q_u.devmode_ctr, q_u.command);
+
+ /* now, we can free the memory */
+ if (q_u.info.level==2 && q_u.info.info_ptr!=0)
+ safe_free(q_u.info.info_2);
+
+ if (q_u.devmode_ctr.devmode_ptr!=0)
+ safe_free(q_u.devmode_ctr.devmode);
if(!spoolss_io_r_setprinter("",&r_u,rdata,0)) {
DEBUG(0,("spoolss_io_r_setprinter: unable to marshall SPOOL_R_SETPRINTER.\n"));
@@ -836,24 +836,19 @@ static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struc
return False;
}
- r_u.valuesize = q_u.valuesize;
- r_u.datasize = q_u.datasize;
-
- r_u.status = _spoolss_enumprinterdata(&q_u.handle,
- q_u.index,/* in */
- &r_u.valuesize,/* in out */
- &r_u.value,/* out */
- &r_u.realvaluesize,/* out */
- &r_u.type,/* out */
- &r_u.datasize,/* in out */
- &r_u.data,/* out */
- &r_u.realdatasize);/* out */
+ r_u.status = _spoolss_enumprinterdata(&q_u.handle, q_u.index, q_u.valuesize, q_u.datasize,
+ &r_u.valuesize, &r_u.value, &r_u.realvaluesize,
+ &r_u.type,
+ &r_u.datasize, &r_u.data, &r_u.realdatasize);
if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) {
DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n"));
+ safe_free(r_u.value);
+ safe_free(r_u.data);
return False;
}
+ safe_free(r_u.value);
safe_free(r_u.data);
return True;
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index da7eda5795..3ab426e9c2 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -66,6 +66,10 @@ typedef struct _Printer{
uint32 printerlocal;
SPOOL_NOTIFY_OPTION *option;
} notify;
+ struct {
+ fstring machine;
+ fstring user;
+ } client;
} Printer_entry;
static ubi_dlList Printer_list;
@@ -160,8 +164,6 @@ static BOOL close_printer_handle(POLICY_HND *hnd)
safe_free(Printer);
- DEBUG(0,("[%d] entrys still in list\n", ubi_dlCount(&Printer_list)));
-
return True;
}
@@ -2632,25 +2634,30 @@ static uint32 control_printer(const POLICY_HND *handle, uint32 command)
if (!OPEN_HANDLE(Printer))
return NT_STATUS_INVALID_HANDLE;
- if (!get_printer_snum(handle, &snum) )
- {
+ if (!get_printer_snum(handle, &snum) )
return NT_STATUS_INVALID_HANDLE;
- }
- switch (command)
- {
+ switch (command) {
case PRINTER_CONTROL_PAUSE:
/* pause the printer here */
status_printqueue(NULL, snum, LPSTAT_STOPPED);
return 0x0;
-
+ break;
case PRINTER_CONTROL_RESUME:
case PRINTER_CONTROL_UNPAUSE:
/* UN-pause the printer here */
status_printqueue(NULL, snum, LPSTAT_OK);
return 0x0;
+ break;
case PRINTER_CONTROL_PURGE:
- /* Envoi des dragées FUCA dans l'imprimante */
+ /*
+ * It's not handled by samba
+ * we need a smb.conf param to do
+ * lprm -P%p - on BSD
+ * lprm -P%p all on LPRNG
+ * I don't know on SysV
+ * we could do it by looping in the job's list...
+ */
break;
}
@@ -2675,9 +2682,8 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level,
DEBUG(8,("update_printer\n"));
- if (level!=2)
- {
- DEBUG(0,("Send a mail to samba-bugs@samba.org\n"));
+ if (level!=2) {
+ DEBUG(0,("Send a mail to jfm@samba.org\n"));
DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
return NT_STATUS_INVALID_INFO_CLASS;
}
@@ -2688,13 +2694,12 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level,
if (!get_printer_snum(handle, &snum) )
return NT_STATUS_INVALID_HANDLE;
- get_a_printer(&printer, level, lp_servicename(snum));
+ get_a_printer(&printer, 2, lp_servicename(snum));
DEBUGADD(8,("Converting info_2 struct\n"));
convert_printer_info(info, &printer, level);
- if ((info->info_2)->devmode_ptr != 0)
- {
+ if ((info->info_2)->devmode_ptr != 0) {
/* we have a valid devmode
convert it and link it*/
@@ -2710,36 +2715,30 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level,
convert_devicemode(*devmode, nt_devmode);
}
- else
- {
+ else {
if (printer.info_2->devmode != NULL)
- {
free(printer.info_2->devmode);
- }
printer.info_2->devmode=NULL;
}
- if (status == 0x0)
- {
- status = add_a_printer(printer, level);
- }
- if (status == 0x0)
- {
- status = free_a_printer(printer, level);
+ if (add_a_printer(printer, 2)!=0) {
+ free_a_printer(printer, 2);
+
+ /* I don't really know what to return here !!! */
+ return NT_STATUS_INVALID_INFO_CLASS;
}
- return status;
+ free_a_printer(printer, 2);
+
+ return NT_STATUS_NO_PROBLEMO;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_setprinter( const POLICY_HND *handle,
- uint32 level,
- const SPOOL_PRINTER_INFO_LEVEL *info,
- const DEVICEMODE *devmode,
- uint32 sec_buf_size,
- const char *sec_buf,
- uint32 command)
+uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
+ const SPOOL_PRINTER_INFO_LEVEL *info,
+ const DEVMODE_CTR devmode_ctr,
+ uint32 command)
{
Printer_entry *Printer = find_printer_index_by_hnd(handle);
@@ -2747,13 +2746,12 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle,
return NT_STATUS_INVALID_HANDLE;
/* check the level */
- switch (level)
- {
+ switch (level) {
case 0:
return control_printer(handle, command);
break;
case 2:
- return update_printer(handle, level, info, devmode);
+ return update_printer(handle, level, info, devmode_ctr.devmode);
break;
}
@@ -3094,7 +3092,7 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri
/* fill the buffer with the form structures */
for (i=0; i<*returned; i++)
{
- DEBUGADD(6,("adding form [%d] to buffer\n",i));
+ DEBUGADD(6,("adding driver [%d] to buffer\n",i));
new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
}
@@ -3135,7 +3133,7 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri
/* fill the buffer with the form structures */
for (i=0; i<*returned; i++)
{
- DEBUGADD(6,("adding form [%d] to buffer\n",i));
+ DEBUGADD(6,("adding driver [%d] to buffer\n",i));
new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
}
@@ -3588,15 +3586,11 @@ uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environmen
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_enumprinterdata(const POLICY_HND *handle,
- uint32 idx,
- uint32 *valuesize,
- UNISTR *uni_value,
- uint32 *realvaluesize,
- uint32 *type,
- uint32 *datasize,
- uint8 **data,
- uint32 *realdatasize)
+uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
+ uint32 in_value_len, uint32 in_data_len,
+ uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
+ uint32 *out_type,
+ uint32 *out_max_data_len, uint8 **out_data, uint32 *out_data_len)
{
NT_PRINTER_INFO_LEVEL printer;
@@ -3606,12 +3600,22 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle,
uint32 biggest_valuesize;
uint32 biggest_datasize;
uint32 data_len;
- uint32 status = 0x0;
Printer_entry *Printer = find_printer_index_by_hnd(handle);
int snum;
+ uint8 *data=NULL;
+ uint32 type;
ZERO_STRUCT(printer);
- (*data)=NULL;
+
+ *out_max_value_len=0;
+ *out_value=NULL;
+ *out_value_len=0;
+
+ *out_type=0;
+
+ *out_max_data_len=0;
+ *out_data=NULL;
+ *out_data_len=0;
DEBUG(5,("spoolss_enumprinterdata\n"));
@@ -3621,74 +3625,77 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle,
if (!get_printer_snum(handle, &snum))
return NT_STATUS_INVALID_HANDLE;
- status = get_a_printer(&printer, 2, lp_servicename(snum));
-
- if (status != 0x0)
- return status;
+ if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0x0)
+ return NT_STATUS_INVALID_HANDLE;
- /* The NT machine wants to know the biggest size of value and data */
- if ( ((*valuesize)==0) && ((*datasize)==0) )
- {
+ /*
+ * The NT machine wants to know the biggest size of value and data
+ *
+ * cf: MSDN EnumPrinterData remark section
+ */
+ if ( (in_value_len==0) && (in_data_len==0) ) {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
- (*valuesize)=0;
- (*realvaluesize)=0;
- (*type)=0;
- (*datasize)=0;
- (*realdatasize)=0;
- status=0;
-
param_index=0;
biggest_valuesize=0;
biggest_datasize=0;
- while (get_specific_param_by_index(printer, 2, param_index, value, data, type, &data_len))
- {
+ while (get_specific_param_by_index(printer, 2, param_index, value, &data, &type, &data_len)) {
if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
- if (data_len > biggest_datasize) biggest_datasize=data_len;
+ if (data_len > biggest_datasize) biggest_datasize=data_len;
+ DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
+
+ safe_free(data);
param_index++;
}
-
- /* I wrote it, I didn't designed the protocol */
- if (biggest_valuesize!=0)
- {
- SIVAL(&(value),0, 2*(biggest_valuesize+1) );
- }
- (*data)=(uint8 *)malloc(4*sizeof(uint8));
- SIVAL((*data), 0, biggest_datasize );
+
+ /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
+ *out_value_len=2*(1+biggest_valuesize);
+ *out_data_len=biggest_datasize;
+
+ DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
+
+ free_a_printer(printer, 2);
+ return NT_STATUS_NO_PROBLEMO;
}
- else
- {
- /*
- * the value len is wrong in NT sp3
- * that's the number of bytes not the number of unicode chars
- */
-
- if (get_specific_param_by_index(printer, 2, idx, value, data, type, &data_len))
- {
- init_unistr(uni_value, value);
-
- /* the length are in bytes including leading NULL */
- (*realvaluesize)=2*(strlen(value)+1);
- (*realdatasize)=data_len;
-
- status=0;
- }
- else
- {
- (*valuesize)=0;
- (*realvaluesize)=0;
- (*datasize)=0;
- (*realdatasize)=0;
- (*type)=0;
- status=0x0103; /* ERROR_NO_MORE_ITEMS */
- }
+
+ /*
+ * the value len is wrong in NT sp3
+ * that's the number of bytes not the number of unicode chars
+ */
+
+ if (!get_specific_param_by_index(printer, 2, index, value, &data, &type, &data_len)) {
+ free_a_printer(printer, 2);
+ return 0x0103; /* ERROR_NO_MORE_ITEMS */
}
+
+ /*
+ * the value is:
+ * - counted in bytes in the request
+ * - counted in UNICODE chars in the max reply
+ * - counted in bytes in the real size
+ *
+ * take a pause *before* coding not *during* coding
+ */
+
+ *out_max_value_len=in_value_len/2;
+ *out_value=(uint16 *)malloc(in_value_len*sizeof(uint8));
+ ascii_to_unistr(*out_value, value, *out_max_value_len);
+ *out_value_len=2*(1+strlen(value));
+
+ *out_type=type;
+
+ /* the data is counted in bytes */
+ *out_max_data_len=in_data_len;
+ *out_data=(uint8 *)malloc(in_data_len*sizeof(uint8));
+ memcpy(*out_data, data, data_len);
+ *out_data_len=data_len;
+
+ safe_free(data);
free_a_printer(printer, 2);
-
- return status;
+ return NT_STATUS_NO_PROBLEMO;
}
/****************************************************************************