diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 14 | ||||
-rwxr-xr-x | source3/include/rpc_spoolss.h | 4 | ||||
-rw-r--r-- | source3/lib/util.c | 85 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 278 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 112 | ||||
-rw-r--r-- | source3/script/mkproto.awk | 4 |
6 files changed, 310 insertions, 187 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index b9e090d834..f98dffad2a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -490,12 +490,19 @@ void free_unistr_array(uint32 num_entries, UNISTR2 **entries); UNISTR2* add_unistr_to_array(uint32 *len, UNISTR2 ***array, UNISTR2 *name); void free_sid_array(uint32 num_entries, DOM_SID **entries); DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); +void free_printer_info_2(PRINTER_INFO_2 *printer); void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries); PRINTER_INFO_2 *add_print2_to_array(uint32 *len, PRINTER_INFO_2 ***array, const PRINTER_INFO_2 *prt); void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries); PRINTER_INFO_1 *add_print1_to_array(uint32 *len, PRINTER_INFO_1 ***array, const PRINTER_INFO_1 *prt); +void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries); +JOB_INFO_1 *add_job1_to_array(uint32 *len, JOB_INFO_1 ***array, + const JOB_INFO_1 *job); +void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries); +JOB_INFO_2 *add_job2_to_array(uint32 *len, JOB_INFO_2 ***array, + const JOB_INFO_2 *job); /*The following definitions come from lib/util_file.c */ @@ -2991,6 +2998,7 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 size); BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth); +void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u); BOOL spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); @@ -3009,7 +3017,13 @@ BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth) BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth); +void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u); BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); +BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, PRINTER_HND *hnd, + uint32 firstjob, + uint32 numofjobs, + uint32 level, + uint32 buf_size); BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 626835933b..8eb0c7efb1 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -1013,8 +1013,8 @@ typedef struct spool_r_enumjobs { uint32 level; union { - JOB_INFO_1 *job_info_1; - JOB_INFO_2 *job_info_2; + JOB_INFO_1 **job_info_1; + JOB_INFO_2 **job_info_2; } job; uint32 offered; uint32 numofjobs; diff --git a/source3/lib/util.c b/source3/lib/util.c index 4e18cb93ba..54844fadcc 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2933,7 +2933,7 @@ void out_ascii(FILE *f, const unsigned char *buf,int len) void out_struct(FILE *f, const char *buf1,int len, int per_line) { - const unsigned char *buf = (unsigned char *)buf1; + const unsigned char *buf = (const unsigned char *)buf1; int i; if (len<=0) @@ -3309,6 +3309,25 @@ DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid) (void***)array, (const void*)sid, *fn, False); } +void free_devmode(DEVICEMODE *devmode) +{ + if (devmode!=NULL) + { + if (devmode->private!=NULL) + free(devmode->private); + free(devmode); + } +} + +void free_printer_info_2(PRINTER_INFO_2 *printer) +{ + if (printer!=NULL) + { + free_devmode(printer->devmode); + free(printer); + } +} + static PRINTER_INFO_2 *prt2_dup(const PRINTER_INFO_2* from) { PRINTER_INFO_2 *copy = (PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2)); @@ -3328,7 +3347,7 @@ static PRINTER_INFO_2 *prt2_dup(const PRINTER_INFO_2* from) void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries) { - void(*fn)(void*) = (void(*)(void*))&free; + void(*fn)(void*) = (void(*)(void*))&free_printer_info_2; free_void_array(num_entries, (void**)entries, *fn); } @@ -3371,3 +3390,65 @@ PRINTER_INFO_1 *add_print1_to_array(uint32 *len, PRINTER_INFO_1 ***array, (void***)array, (const void*)prt, *fn, True); } +static JOB_INFO_1 *job1_dup(const JOB_INFO_1* from) +{ + JOB_INFO_1 *copy = (JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1)); + if (copy != NULL) + { + if (from != NULL) + { + memcpy(copy, from, sizeof(*copy)); + } + else + { + memset(copy, 0, sizeof(*copy)); + } + } + return copy; +} + +void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries) +{ + void(*fn)(void*) = (void(*)(void*))&free; + free_void_array(num_entries, (void**)entries, *fn); +} + +JOB_INFO_1 *add_job1_to_array(uint32 *len, JOB_INFO_1 ***array, + const JOB_INFO_1 *job) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&job1_dup; + return (JOB_INFO_1*)add_item_to_array(len, + (void***)array, (const void*)job, *fn, True); +} + +static JOB_INFO_2 *job2_dup(const JOB_INFO_2* from) +{ + JOB_INFO_2 *copy = (JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2)); + if (copy != NULL) + { + if (from != NULL) + { + memcpy(copy, from, sizeof(*copy)); + } + else + { + memset(copy, 0, sizeof(*copy)); + } + } + return copy; +} + +void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries) +{ + void(*fn)(void*) = (void(*)(void*))&free; + free_void_array(num_entries, (void**)entries, *fn); +} + +JOB_INFO_2 *add_job2_to_array(uint32 *len, JOB_INFO_2 ***array, + const JOB_INFO_2 *job) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&job2_dup; + return (JOB_INFO_2*)add_item_to_array(len, + (void***)array, (const void*)job, *fn, True); +} + diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 6b60b74147..059b21644f 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -1688,6 +1688,18 @@ static uint32 spoolss_size_monitor_info_1(PRINTMONITOR_1 *info) } /******************************************************************* + * make a structure. + ********************************************************************/ +static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size) +{ + buffer->ptr = (size != 0) ? 1 : 0; + buffer->size = size; + buffer->data = (uint8 *)Realloc( NULL, (buffer->size) * sizeof(uint8) ); + + return (buffer->data != NULL || size == 0); +} + +/******************************************************************* * read a uint8 buffer of size *size. * allocate memory for it * return a pointer to the allocated memory and the size @@ -1732,6 +1744,15 @@ static BOOL spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER } } + if (!ps->io) + { + /* writing */ + if (buffer->data != NULL) + { + free(buffer->data); + } + buffer->data = NULL; + } return True; } @@ -1934,10 +1955,7 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, make_unistr2(&(q_u->servername), servername, len_name); q_u->level = level; - q_u->buffer.ptr = (size != 0) ? 1 : 0; - q_u->buffer.size = size; - q_u->buffer.data = (uint8 *)Realloc( NULL, - (q_u->buffer.size) * sizeof(uint8) ); + make_spoolss_buffer(&q_u->buffer, size); q_u->buf_size = size; return True; @@ -1966,19 +1984,29 @@ BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, spoolss_io_read_buffer("buffer", ps, depth, &(q_u->buffer)); - if (!ps->io) + prs_uint32("buf_size", ps, depth, &q_u->buf_size); + + return True; +} + +/**************************************************************************** +****************************************************************************/ +void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u) +{ + DEBUG(4,("free_enum_printers_info: [%d] structs to free at level [%d]\n", r_u->returned, r_u->level)); + switch (r_u->level) { - /* writing */ - if (q_u->buffer.data != NULL) + case 1: { - free(q_u->buffer.data); + free_print1_array(r_u->returned, r_u->printer.printers_1); + break; + } + case 2: + { + free_print2_array(r_u->returned, r_u->printer.printers_2); + break; } - q_u->buffer.data = NULL; } - - prs_uint32("buf_size", ps, depth, &q_u->buf_size); - - return True; } /******************************************************************* @@ -1994,7 +2022,6 @@ BOOL spoolss_io_r_enumprinters(char *desc, int i; uint32 start_offset, end_offset, beginning; uint32 bufsize_required=0; - uint32 tmp_ct = 0; PRINTER_INFO_1 *info1; PRINTER_INFO_2 *info2; @@ -2073,10 +2100,10 @@ BOOL spoolss_io_r_enumprinters(char *desc, ps->offset = beginning; } - tmp_ct = 0; - for(i=0;i<r_u->returned;i++) { + uint32 tmp_ct = 0; + switch (r_u->level) { case 1: @@ -2121,6 +2148,12 @@ BOOL spoolss_io_r_enumprinters(char *desc, prs_uint32("count", ps, depth, &(r_u->returned)); prs_uint32("status", ps, depth, &(r_u->status)); + if (ps->io) + { + /* writing */ + free_r_enumprinters(r_u); + } + return True; } @@ -2482,6 +2515,26 @@ BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int de return True; } +/**************************************************************************** +****************************************************************************/ +void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u) +{ + DEBUG(4,("free_enum_jobs_info: [%d] structs to free at level [%d]\n", r_u->numofjobs, r_u->level)); + switch (r_u->level) + { + case 1: + { + free_job1_array(r_u->numofjobs, r_u->job.job_info_1); + break; + } + case 2: + { + free_job2_array(r_u->numofjobs, r_u->job.job_info_2); + break; + } + } +} + /******************************************************************* ********************************************************************/ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth) @@ -2489,6 +2542,7 @@ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, in uint32 useless_ptr=0xADDE0FF0; uint32 start_offset, end_offset, beginning; uint32 bufsize_required=0; + uint32 tmp_ct = 0; int i; prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs"); @@ -2498,104 +2552,158 @@ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, in prs_uint32("pointer", ps, depth, &useless_ptr); - switch (r_u->level) + if (!ps->io) { - case 1: + /* writing */ + switch (r_u->level) { - JOB_INFO_1 *info; - info=r_u->job.job_info_1; - - for (i=0; i<r_u->numofjobs; i++) + case 1: { - bufsize_required += spoolss_size_job_info_1(&(info[i])); + for (i=0; i<r_u->numofjobs; i++) + { + JOB_INFO_1 *info; + info=r_u->job.job_info_1[i]; + bufsize_required += spoolss_size_job_info_1(&(info[i])); + } + break; } - break; + case 2: + { + for (i=0; i<r_u->numofjobs; i++) + { + JOB_INFO_2 *info; + info=r_u->job.job_info_2[i]; + + bufsize_required += spoolss_size_job_info_2(&(info[i])); + } + break; + } } - case 2: - { - JOB_INFO_2 *info; - info=r_u->job.job_info_2; + + DEBUG(4,("spoolss_io_r_enumjobs, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_enumjobs, size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offered<bufsize_required) + { + /* it's too small */ + r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ - for (i=0; i<r_u->numofjobs; i++) - { - bufsize_required += spoolss_size_job_info_2(&(info[i])); - } - break; - } + DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n")); + + } + mem_grow_data(&(ps->data), ps->io, r_u->offered, 0); } + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + + beginning=ps->offset; + start_offset=ps->offset; + end_offset=start_offset+r_u->offered; - DEBUG(4,("spoolss_io_r_enumjobs, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_enumjobs, size offered: %d\n",r_u->offered)); + tmp_ct = 0; - /* check if the buffer is big enough for the datas */ - if (r_u->offered<bufsize_required) - { - /* it's too small */ - r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ - - DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n")); + if (ps->io) + { + /* reading */ + ps->offset = beginning + r_u->offered; - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + prs_align(ps); + prs_uint32("buffer size", ps, depth, &(bufsize_required)); + prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); + + ps->offset = beginning; } - else - { - mem_grow_data(&(ps->data), ps->io, r_u->offered, 0); - - DEBUG(4,("spoolss_io_r_enumjobs, buffer large enough\n")); - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=ps->offset; - start_offset=ps->offset; - end_offset=start_offset+r_u->offered; - - switch (r_u->level) + switch (r_u->level) + { + case 1: { - case 1: + JOB_INFO_1 *info; + for (i=0; i<r_u->numofjobs; i++) { - JOB_INFO_1 *info; - for (i=0; i<r_u->numofjobs; i++) + if (ps->io) { - info = &(r_u->job.job_info_1[i]); - smb_io_job_info_1(desc, - info, - ps, - depth, - &start_offset, - &end_offset); + /* reading */ + r_u->job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->job.job_info_1, NULL); } - break; + info = r_u->job.job_info_1[i]; + smb_io_job_info_1(desc, + info, + ps, + depth, + &start_offset, + &end_offset); } - case 2: + break; + } + case 2: + { + JOB_INFO_2 *info; + for (i=0; i<r_u->numofjobs; i++) { - JOB_INFO_2 *info; - for (i=0; i<r_u->numofjobs; i++) + if (ps->io) { - info = &(r_u->job.job_info_2[i]); - smb_io_job_info_2(desc, - info, - ps, - depth, - &start_offset, - &end_offset); + /* reading */ + r_u->job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->job.job_info_2, NULL); } - break; + info = r_u->job.job_info_2[i]; + smb_io_job_info_2(desc, + info, + ps, + depth, + &start_offset, + &end_offset); } - - } - ps->offset=beginning+r_u->offered; - prs_align(ps); - } + break; + } + + } + ps->offset=beginning+r_u->offered; + prs_align(ps); /* * if the buffer was too small, send the minimum required size * if it was too large, send the real needed size */ - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("buffer size", ps, depth, &(bufsize_required)); prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); prs_uint32("status", ps, depth, &(r_u->status)); + if (ps->io) + { + /* writing */ + free_r_enumjobs(r_u); + } + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, PRINTER_HND *hnd, + uint32 firstjob, + uint32 numofjobs, + uint32 level, + uint32 buf_size) +{ + if (q_u == NULL) + { + return False; + } + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + q_u->firstjob = firstjob; + q_u->numofjobs = numofjobs; + q_u->level = level; + + if (!make_spoolss_buffer(&q_u->buffer, buf_size)) + { + return False; + } + q_u->buf_size = buf_size; + return True; } @@ -2616,8 +2724,6 @@ BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, in spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); - prs_align(ps); - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); return True; diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 5883c9baac..1f9d8a19d5 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -1748,77 +1748,6 @@ static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number, } } -/**************************************************************************** -****************************************************************************/ -static void free_devmode(DEVICEMODE *devmode) -{ - if (devmode->private!=NULL) - free(devmode->private); - if (devmode!=NULL) - free(devmode); -} - -/**************************************************************************** -****************************************************************************/ -static void free_printer_info_2(PRINTER_INFO_2 *printer) -{ - free_devmode(printer->devmode); - if (printer!=NULL) - free(printer); -} - -/**************************************************************************** -****************************************************************************/ -static void free_enum_printers_info_1(PRINTER_INFO_1 **printers, uint32 total) -{ - int number=0; - if (printers != NULL) - { - for (number=0; number<total; number++) - { - if (printers[number] != NULL) - { - free(printers[number]); - } - } - free(printers); - } -} - -/**************************************************************************** -****************************************************************************/ -static void free_enum_printers_info_2(PRINTER_INFO_2 **printers, uint32 total) -{ - int number=0; - if (printers != NULL) - { - for (number=0; number<total; number++) - { - if (printers[number] != NULL) - { - free_printer_info_2(printers[number]); - } - } - free(printers); - } -} - -/**************************************************************************** -****************************************************************************/ -static void free_enum_printers_info(SPOOL_R_ENUMPRINTERS *r_u) -{ - DEBUG(4,("free_enum_printers_info: [%d] structs to free at level [%d]\n", r_u->returned, r_u->level)); - switch (r_u->level) - { - case 1: - free_enum_printers_info_1(r_u->printer.printers_1, r_u->returned); - break; - case 2: - free_enum_printers_info_2(r_u->printer.printers_2, r_u->returned); - break; - } -} - /******************************************************************** * api_spoolss_reply_enumprinters * @@ -1864,7 +1793,6 @@ static void spoolss_reply_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *rd r_u.status=0x0000; spoolss_io_r_enumprinters("",&r_u,rdata,0); - free_enum_printers_info(&r_u); } /******************************************************************** @@ -2827,7 +2755,7 @@ static void spoolss_reply_enumjobs(SPOOL_Q_ENUMJOBS *q_u, prs_struct *rdata, con if (get_printer_snum(&(q_u->handle), &snum)) { count=get_printqueue(snum, conn, &queue, &status); - r_u.numofjobs=count; + r_u.numofjobs=0; r_u.level=q_u->level; @@ -2837,48 +2765,38 @@ static void spoolss_reply_enumjobs(SPOOL_Q_ENUMJOBS *q_u, prs_struct *rdata, con { case 1: { - job_info_1=(JOB_INFO_1 *)malloc(count*sizeof(JOB_INFO_1)); - for (i=0; i<count; i++) { - fill_job_info_1(&(job_info_1[i]), &(queue[i]), i, snum); + job_info_1=(JOB_INFO_1 *)malloc(count*sizeof(JOB_INFO_1)); + add_job1_to_array(&r_u.numofjobs, + &r_u.job.job_info_1, + job_info_1); + + fill_job_info_1(r_u.job.job_info_1[i], &(queue[i]), i, snum); } - r_u.job.job_info_1=job_info_1; break; } case 2: { - job_info_2=(JOB_INFO_2 *)malloc(count*sizeof(JOB_INFO_2)); - for (i=0; i<count; i++) { - fill_job_info_2(&(job_info_2[i]), &(queue[i]), i, snum); + job_info_2=(JOB_INFO_2 *)malloc(count*sizeof(JOB_INFO_2)); + add_job2_to_array(&r_u.numofjobs, + &r_u.job.job_info_2, + job_info_2); + + fill_job_info_2(r_u.job.job_info_2[i], &(queue[i]), i, snum); } - r_u.job.job_info_2=job_info_2; break; } } } - r_u.status=0x0; + r_u.status = 0x0; spoolss_io_r_enumjobs("",&r_u,rdata,0); - switch (r_u.level) - { - case 1: - { - free(job_info_1); - break; - } - case 2: - { - free_devmode(job_info_2->devmode); - free(job_info_2); - break; - } - } - if (queue) free(queue); + if (queue) free(queue); } /**************************************************************************** diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 9e4c7de2d6..b286e1f7db 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -94,6 +94,10 @@ END { gotstart = 1; } + if( $0 ~ /^JOB_INFO_1|^JOB_INFO_2/ ) { + gotstart = 1; + } + if( $0 ~ /^PRINTER_INFO_1|^PRINTER_INFO_2/ ) { gotstart = 1; } |