diff options
-rw-r--r-- | source3/include/proto.h | 3 | ||||
-rwxr-xr-x | source3/include/rpc_spoolss.h | 14 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 52 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 32 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 42 |
5 files changed, 137 insertions, 6 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 3a43907b4b..737053a2a3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2726,6 +2726,8 @@ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, const POLICY_HND *handle, UNISTR2 *valuename, uint32 size); BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_deleteprinterdata(char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd); BOOL spoolss_io_q_abortprinter(char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth); @@ -3187,6 +3189,7 @@ uint32 _spoolss_setprinterdata( POLICY_HND *handle, const uint8 *data, uint32 real_len, uint32 numeric_data); +uint32 _spoolss_deleteprinterdata( POLICY_HND *handle, const UNISTR2 *value); uint32 _spoolss_addform( POLICY_HND *handle, uint32 level, const FORM *form); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index f581c381f9..43e81914d0 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -106,6 +106,7 @@ #define SPOOLSS_OPENPRINTEREX 0x45 #define SPOOLSS_ADDPRINTEREX 0x46 #define SPOOLSS_ENUMPRINTERDATA 0x48 +#define SPOOLSS_DELETEPRINTERDATA 0x49 #define PRINTER_CONTROL_UNPAUSE 0x00000000 #define PRINTER_CONTROL_PAUSE 0x00000001 @@ -515,6 +516,19 @@ typedef struct spool_r_getprinterdata } SPOOL_R_GETPRINTERDATA; +typedef struct spool_q_deleteprinterdata +{ + POLICY_HND handle; + UNISTR2 valuename; +} +SPOOL_Q_DELETEPRINTERDATA; + +typedef struct spool_r_deleteprinterdata +{ + uint32 status; +} +SPOOL_R_DELETEPRINTERDATA; + typedef struct spool_q_closeprinter { POLICY_HND handle; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 3b0ddaac9f..953124ebe4 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -954,7 +954,8 @@ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, ********************************************************************/ BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth) { - if (q_u == NULL) return False; + if (q_u == NULL) + return False; prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata"); depth++; @@ -976,6 +977,44 @@ BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_st } /******************************************************************* + * read a structure. + * called from spoolss_q_deleteprinterdata (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_deleteprinterdata(char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata"); + depth++; + + if (!prs_align(ps)) + return False; + if (!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("valuename", &(q_u->valuename),True,ps,depth)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_deleteprinterdata (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata"); + depth++; + if(!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; +} + +/******************************************************************* * write a structure. * called from spoolss_r_getprinterdata (srv_spoolss.c) ********************************************************************/ @@ -5167,11 +5206,12 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, (*param)->data_len=len; - (*param)->data=(uint8 *)malloc(len * sizeof(uint8)); - if((*param)->data == NULL) - return False; - - memcpy((*param)->data, data, len); + if (len) { + (*param)->data=(uint8 *)malloc(len * sizeof(uint8)); + if((*param)->data == NULL) + return False; + memcpy((*param)->data, data, len); + } DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len)); diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index fd6cf11746..72ce17fee1 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -100,6 +100,37 @@ static BOOL api_spoolss_getprinterdata(pipes_struct *p) } /******************************************************************** + * api_spoolss_deleteprinterdata + * + * called from the spoolss dispatcher + ********************************************************************/ +static BOOL api_spoolss_deleteprinterdata(pipes_struct *p) +{ + SPOOL_Q_DELETEPRINTERDATA q_u; + SPOOL_R_DELETEPRINTERDATA r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* read the stream and fill the struct */ + if (!spoolss_io_q_deleteprinterdata("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_deleteprinterdata: unable to unmarshall SPOOL_Q_DELETEPRINTERDATA.\n")); + return False; + } + + r_u.status = _spoolss_deleteprinterdata( &q_u.handle, &q_u.valuename); + + if (!spoolss_io_r_deleteprinterdata("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_deleteprinterdata: unable to marshall SPOOL_R_DELETEPRINTERDATA.\n")); + return False; + } + + return True; +} + +/******************************************************************** * api_spoolss_closeprinter * * called from the spoolss dispatcher @@ -1328,6 +1359,7 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory }, {"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata }, {"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata }, + {"SPOOLSS_DELETEPRINTERDATA", SPOOLSS_DELETEPRINTERDATA, api_spoolss_deleteprinterdata }, {"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform }, {"SPOOLSS_DELETEFORM", SPOOLSS_DELETEFORM, api_spoolss_deleteform }, {"SPOOLSS_GETFORM", SPOOLSS_GETFORM, api_spoolss_getform }, diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 52a677fbe0..2c0dc79fb2 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4681,6 +4681,48 @@ uint32 _spoolss_setprinterdata( POLICY_HND *handle, /**************************************************************************** ****************************************************************************/ +uint32 _spoolss_deleteprinterdata( POLICY_HND *handle, const UNISTR2 *value) +{ + NT_PRINTER_INFO_LEVEL *printer = NULL; + NT_PRINTER_PARAM param; + int snum=0; + uint32 status = 0x0; + Printer_entry *Printer=find_printer_index_by_hnd(handle); + + DEBUG(5,("spoolss_deleteprinterdata\n")); + + if (!OPEN_HANDLE(Printer)) { + DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle))); + return ERROR_INVALID_HANDLE; + } + + if (!get_printer_snum(handle, &snum)) + return ERROR_INVALID_HANDLE; + + if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) { + DEBUG(3, ("_spoolss_deleteprinterdata: security descriptor change denied by existing " + "security descriptor\n")); + return ERROR_ACCESS_DENIED; + } + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (status != 0x0) + return ERROR_INVALID_NAME; + + ZERO_STRUCTP(¶m); + unistr2_to_ascii(param.value, value, sizeof(param.value)-1); + + if(!unlink_specific_param_if_exist(printer->info_2, ¶m)) + status = ERROR_INVALID_PARAMETER; + else + status = add_a_printer(*printer, 2); + + free_a_printer(&printer, 2); + return status; +} + +/**************************************************************************** +****************************************************************************/ uint32 _spoolss_addform( POLICY_HND *handle, uint32 level, const FORM *form) |