From 826ad16b363accc4029178cf9087b02362245e11 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 9 Nov 1999 19:35:30 +0000 Subject: debugging rpcclient spoolenum and spooljobs commands. oh, did i forget to mention, there's a spooljobs command, and it uses command-line completion? prints out NT print jobs really nicely, too. (This used to be commit e6e5caf16c8d120f0c11fa63061f2786098e3357) --- source3/include/ntdomain.h | 2 + source3/include/nterr.h | 4 + source3/include/proto.h | 44 +++++-- source3/include/rpc_spoolss.h | 5 +- source3/rpc_client/cli_pipe.c | 4 +- source3/rpc_client/cli_spoolss.c | 83 ++++++++++++- source3/rpc_parse/parse_spoolss.c | 159 +++++++++++++------------ source3/rpcclient/cmd_spoolss.c | 127 +++++++++++++++++++- source3/rpcclient/display.c | 238 ++++++++++++++++++++++++++++++++++++++ source3/rpcclient/rpcclient.c | 17 ++- 10 files changed, 580 insertions(+), 103 deletions(-) (limited to 'source3') diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 1b7a7b55a6..c36f619ef2 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -194,6 +194,8 @@ struct acct_info #define PRINT_INFO_FN(fn)\ void (*fn)(const char*, uint32, uint32, void *const *const) +#define JOB_INFO_FN(fn)\ + void (*fn)(const char*, const char*, uint32, uint32, void *const *const) #endif /* _NT_DOMAIN_H */ diff --git a/source3/include/nterr.h b/source3/include/nterr.h index 21e245d287..86c049495c 100644 --- a/source3/include/nterr.h +++ b/source3/include/nterr.h @@ -2,6 +2,10 @@ #define STATUS_BUFFER_OVERFLOW (5) #define STATUS_MORE_ENTRIES (0x105) +#define ERROR_INVALID_HANDLE (6) +#define ERROR_INVALID_PARAMETER (87) +#define ERROR_INSUFFICIENT_BUFFER (122) + /* these are the NT error codes less than 1000. They are here for when we start supporting NT error codes in Samba. They were extracted diff --git a/source3/include/proto.h b/source3/include/proto.h index f98dffad2a..0b0ca16c54 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -490,6 +490,7 @@ 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_devmode(DEVICEMODE *devmode); 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, @@ -2059,11 +2060,19 @@ BOOL spoolss_enum_printers(struct cli_state *cli, uint16 fnum, uint32 level, uint32 *count, void ***printers); +uint32 spoolss_enum_jobs(struct cli_state *cli, uint16 fnum, + const PRINTER_HND *hnd, + uint32 firstjob, + uint32 numofjobs, + uint32 level, + uint32 *buf_size, + uint32 *count, + void ***jobs); BOOL spoolss_open_printer_ex(struct cli_state *cli, uint16 fnum, - char *printername, + const char *printername, uint32 cbbuf, uint32 devmod, uint32 des_access, - char *station, - char *username, + const char *station, + const char *username, PRINTER_HND *hnd); BOOL spoolss_closeprinter(struct cli_state *cli, uint16 fnum, PRINTER_HND *hnd); @@ -2952,10 +2961,10 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth); BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, - char *printername, + const char *printername, uint32 cbbuf, uint32 devmod, uint32 des_access, - char *station, - char *username); + const char *station, + const char *username); BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth); BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, PRINTER_HND *handle, @@ -3019,7 +3028,7 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de 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, +BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const PRINTER_HND *hnd, uint32 firstjob, uint32 numofjobs, uint32 level, @@ -3460,12 +3469,22 @@ void cmd_sam_enum_groups(struct client_info *info); /*The following definitions come from rpcclient/cmd_spoolss.c */ BOOL msrpc_spoolss_enum_printers(struct cli_state *cli, + const char* srv_name, uint32 level, uint32 *num, void ***ctr, PRINT_INFO_FN(fn)); void cmd_spoolss_enum_printers(struct client_info *info); void cmd_spoolss_open_printer_ex(struct client_info *info); +BOOL msrpc_spoolss_enum_jobs(struct cli_state *cli, + const char* srv_name, + const char* user_name, + const char* printer_name, + uint32 level, + uint32 *num, + void ***ctr, + JOB_INFO_FN(fn)); +void cmd_spoolss_enum_jobs(struct client_info *info); /*The following definitions come from rpcclient/cmd_srvsvc.c */ @@ -3632,6 +3651,17 @@ void display_printer_info_1_ctr(FILE *out_hnd, enum action_type action, void display_printer_info_ctr(FILE *out_hnd, enum action_type action, uint32 level, uint32 count, void *const *const ctr); +void display_job_info_2(FILE *out_hnd, enum action_type action, + JOB_INFO_2 *const i2); +void display_job_info_1(FILE *out_hnd, enum action_type action, + JOB_INFO_1 *const i1); +void display_job_info_2_ctr(FILE *out_hnd, enum action_type action, + uint32 count, JOB_INFO_2 *const *const ctr); +void display_job_info_1_ctr(FILE *out_hnd, enum action_type action, + uint32 count, JOB_INFO_1 *const *const ctr); +void display_job_info_ctr(FILE *out_hnd, enum action_type action, + uint32 level, uint32 count, + void *const *const ctr); /*The following definitions come from rpcclient/rpcclient.c */ diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 8eb0c7efb1..8b3410e87c 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -478,10 +478,6 @@ typedef struct devicemode_container #define COLLATE_FALSE 0 #define COLLATE_TRUE 1 -#define ERROR_INVALID_HANDLE 6 -#define ERROR_INVALID_PARAMETER 87 -#define ERROR_INSUFFICIENT_BUFFER 122 - typedef struct s_header_type { uint32 type; @@ -1015,6 +1011,7 @@ typedef struct spool_r_enumjobs union { JOB_INFO_1 **job_info_1; JOB_INFO_2 **job_info_2; + void *info; } job; uint32 offered; uint32 numofjobs; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7e2bf426fa..df09f02398 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -283,7 +283,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum, setup[0] = cmd; setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */ - if (data_len > 1024 && !bind_rq) + if (data_len > 2048 && !bind_rq) { ssize_t written; @@ -314,7 +314,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum, if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, setup, 2, 0, /* Setup, length, max */ pparams, params_len, 0, /* Params, length, max */ - pdata, data_len, 1024, /* data, length, max */ + pdata, data_len, 2048, /* data, length, max */ pp_ret_params, p_ret_params_len, /* return params, len */ pp_ret_data, p_ret_data_len)) /* return data, len */ { diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 1875ae5400..09780b2477 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -56,7 +56,7 @@ BOOL spoolss_enum_printers(struct cli_state *cli, uint16 fnum, DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n", servername, level)); - make_spoolss_q_enumprinters(&q_o, flags, servername, level, 0x400); + make_spoolss_q_enumprinters(&q_o, flags, servername, level, 0x50); /* turn parameters into data stream */ spoolss_io_q_enumprinters("", &q_o, &buf, 0); @@ -69,7 +69,7 @@ BOOL spoolss_enum_printers(struct cli_state *cli, uint16 fnum, ZERO_STRUCT(r_o); - r_o.level = level; + r_o.level = level; /* i can't believe you have to this */ spoolss_io_r_enumprinters("", &r_o, &rbuf, 0); p = rbuf.offset != 0; @@ -96,14 +96,87 @@ BOOL spoolss_enum_printers(struct cli_state *cli, uint16 fnum, return valid_pol; } +/**************************************************************************** +do a SPOOLSS Enum Jobs +****************************************************************************/ +uint32 spoolss_enum_jobs(struct cli_state *cli, uint16 fnum, + const PRINTER_HND *hnd, + uint32 firstjob, + uint32 numofjobs, + uint32 level, + uint32 *buf_size, + uint32 *count, + void ***jobs) +{ + prs_struct rbuf; + prs_struct buf; + SPOOL_Q_ENUMJOBS q_o; + uint32 status = 0x0; + + if (hnd == NULL || count == NULL || jobs == NULL) + { + return NT_STATUS_INVALID_PARAMETER; + } + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */ + + DEBUG(5,("SPOOLSS Enum Jobs level: %d)\n", level)); + + make_spoolss_q_enumjobs(&q_o, hnd, + firstjob, numofjobs, + level, *buf_size); + + /* turn parameters into data stream */ + spoolss_io_q_enumjobs("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SPOOLSS_ENUMJOBS, &buf, &rbuf)) + { + SPOOL_R_ENUMJOBS r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + r_o.level = level; /* i can't believe you have to this */ + + spoolss_io_r_enumjobs("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + status = r_o.status; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(5,("SPOOLSS_ENUM_JOBS: %s\n", get_nt_error_msg(r_o.status))); + p = status = ERROR_INSUFFICIENT_BUFFER; + } + + if (p) + { + /* ok, at last: we're happy. return the policy handle */ + (*count) = r_o.numofjobs; + (*jobs) = r_o.job.info; + (*buf_size) = r_o.offered; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return status; +} + /**************************************************************************** do a SPOOLSS Open Printer Ex ****************************************************************************/ BOOL spoolss_open_printer_ex(struct cli_state *cli, uint16 fnum, - char *printername, + const char *printername, uint32 cbbuf, uint32 devmod, uint32 des_access, - char *station, - char *username, + const char *station, + const char *username, PRINTER_HND *hnd) { prs_struct rbuf; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 059b21644f..6f1cfdc63c 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -418,10 +418,10 @@ BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_ * make a structure. ********************************************************************/ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, - char *printername, + const char *printername, uint32 cbbuf, uint32 devmod, uint32 des_access, - char *station, - char *username) + const char *station, + const char *username) { int len_name = printername != NULL ? strlen(printername) : 0; int len_sta = station != NULL ? strlen(station ) : 0; @@ -1722,7 +1722,7 @@ static BOOL spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER if (ps->io) { /* reading */ - buffer->data=(uint8 *)malloc( buffer->size * sizeof(uint8) ); + buffer->data=(uint8 *)Realloc(NULL, buffer->size * sizeof(uint8) ); } if (buffer->data == NULL) { @@ -2022,6 +2022,7 @@ 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; @@ -2102,7 +2103,6 @@ BOOL spoolss_io_r_enumprinters(char *desc, for(i=0;ireturned;i++) { - uint32 tmp_ct = 0; switch (r_u->level) { @@ -2113,7 +2113,7 @@ BOOL spoolss_io_r_enumprinters(char *desc, /* reading */ r_u->printer.printers_1[i] = add_print1_to_array(&tmp_ct, &r_u->printer.printers_1, NULL); } - info1=r_u->printer.printers_1[i]; + info1 = r_u->printer.printers_1[i]; if (info1 == NULL) { return False; @@ -2129,7 +2129,7 @@ BOOL spoolss_io_r_enumprinters(char *desc, /* reading */ r_u->printer.printers_2[i] = add_print2_to_array(&tmp_ct, &r_u->printer.printers_2, NULL); } - info2=r_u->printer.printers_2[i]; + info2 = r_u->printer.printers_2[i]; if (info2 == NULL) { return False; @@ -2148,7 +2148,7 @@ 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) + if (!ps->io) { /* writing */ free_r_enumprinters(r_u); @@ -2539,7 +2539,7 @@ 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) { - uint32 useless_ptr=0xADDE0FF0; + uint32 useless_ptr = 0; uint32 start_offset, end_offset, beginning; uint32 bufsize_required=0; uint32 tmp_ct = 0; @@ -2550,8 +2550,6 @@ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, in prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - if (!ps->io) { /* writing */ @@ -2587,92 +2585,102 @@ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, in if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ + r_u->status = ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered = bufsize_required; + useless_ptr = 0; DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n")); } + else + { + useless_ptr = 1; + } mem_grow_data(&(ps->data), ps->io, r_u->offered, 0); } + prs_uint32("pointer", ps, depth, &useless_ptr); prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=ps->offset; - start_offset=ps->offset; - end_offset=start_offset+r_u->offered; - - tmp_ct = 0; - - if (ps->io) + if (useless_ptr != 0) { - /* reading */ - ps->offset = beginning + r_u->offered; + beginning=ps->offset; + start_offset=ps->offset; + end_offset=start_offset+r_u->offered; + + tmp_ct = 0; - prs_align(ps); - prs_uint32("buffer size", ps, depth, &(bufsize_required)); - prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); + if (ps->io) + { + /* reading */ + ps->offset = beginning + r_u->offered; - ps->offset = beginning; - } - - switch (r_u->level) - { - case 1: + prs_align(ps); + prs_uint32("buffer size", ps, depth, &(bufsize_required)); + prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); + + ps->offset = beginning; + } + + switch (r_u->level) { - JOB_INFO_1 *info; - for (i=0; inumofjobs; i++) + case 1: { - if (ps->io) + JOB_INFO_1 *info; + for (i=0; inumofjobs; i++) { - /* reading */ - r_u->job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->job.job_info_1, NULL); + if (ps->io) + { + /* reading */ + r_u->job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->job.job_info_1, NULL); + } + info = r_u->job.job_info_1[i]; + smb_io_job_info_1(desc, + info, + ps, + depth, + &start_offset, + &end_offset); } - info = r_u->job.job_info_1[i]; - smb_io_job_info_1(desc, - info, - ps, - depth, - &start_offset, - &end_offset); + break; } - break; - } - case 2: - { - JOB_INFO_2 *info; - for (i=0; inumofjobs; i++) + case 2: { - if (ps->io) + JOB_INFO_2 *info; + for (i=0; inumofjobs; i++) { - /* reading */ - r_u->job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->job.job_info_2, NULL); + if (ps->io) + { + /* reading */ + r_u->job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->job.job_info_2, NULL); + } + info = r_u->job.job_info_2[i]; + smb_io_job_info_2(desc, + info, + ps, + depth, + &start_offset, + &end_offset); } - info = r_u->job.job_info_2[i]; - smb_io_job_info_2(desc, - info, - ps, - depth, - &start_offset, - &end_offset); + break; } - 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("buffer size", ps, depth, &(bufsize_required)); + + } + 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("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) + if (!ps->io) { /* writing */ free_r_enumjobs(r_u); @@ -2683,7 +2691,7 @@ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, in /******************************************************************* ********************************************************************/ -BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, PRINTER_HND *hnd, +BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const PRINTER_HND *hnd, uint32 firstjob, uint32 numofjobs, uint32 level, @@ -2711,8 +2719,7 @@ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, PRINTER_HND *hnd, ********************************************************************/ BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth) { - - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs"); depth++; prs_align(ps); diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 073ee24495..9b5aa5b3e0 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -41,19 +41,15 @@ extern int smb_tidx; nt spoolss query ****************************************************************************/ BOOL msrpc_spoolss_enum_printers(struct cli_state *cli, + const char* srv_name, uint32 level, uint32 *num, void ***ctr, PRINT_INFO_FN(fn)) { uint16 nt_pipe_fnum; - fstring srv_name; BOOL res = True; - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, smb_cli->desthost); - strupper(srv_name); - /* open SPOOLSS session. */ res = cli_nt_session_open(cli, PIPE_SPOOLSS, &nt_pipe_fnum); @@ -88,7 +84,12 @@ void cmd_spoolss_enum_printers(struct client_info *info) uint32 num = 0; uint32 level = 1; - if (msrpc_spoolss_enum_printers(smb_cli, level, &num, &ctr, + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, smb_cli->desthost); + strupper(srv_name); + + if (msrpc_spoolss_enum_printers(smb_cli, srv_name, level, &num, &ctr, spool_print_info_ctr)) { DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n")); @@ -153,3 +154,117 @@ void cmd_spoolss_open_printer_ex(struct client_info *info) } } +/**************************************************************************** +nt spoolss query +****************************************************************************/ +BOOL msrpc_spoolss_enum_jobs(struct cli_state *cli, + const char* srv_name, + const char* user_name, + const char* printer_name, + uint32 level, + uint32 *num, + void ***ctr, + JOB_INFO_FN(fn)) +{ + uint16 nt_pipe_fnum; + PRINTER_HND hnd; + uint32 buf_size = 0x0; + uint32 status = 0x0; + + BOOL res = True; + BOOL res1 = True; + + DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n", + printer_name, srv_name, user_name)); + + DEBUG(5, ("cmd_spoolss_open_printer_ex: smb_cli->fd:%d\n", smb_cli->fd)); + + /* open SPOOLSS session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_SPOOLSS, &nt_pipe_fnum) : False; + + res = res ? spoolss_open_printer_ex(smb_cli, nt_pipe_fnum, + printer_name, + 0, 0, 0, + srv_name, user_name, + &hnd) : False; + + if (status == 0x0) + { + status = spoolss_enum_jobs(smb_cli, nt_pipe_fnum, + &hnd, + 0, 1000, level, &buf_size, + num, ctr); + } + + if (status == ERROR_INSUFFICIENT_BUFFER) + { + status = spoolss_enum_jobs(smb_cli, nt_pipe_fnum, + &hnd, + 0, 1000, level, &buf_size, + num, ctr); + } + + res1 = (status == 0x0); + + res = res ? spoolss_closeprinter(smb_cli, nt_pipe_fnum, &hnd) : False; + + /* close the session */ + cli_nt_session_close(smb_cli, nt_pipe_fnum); + + if (res1 && fn != NULL) + { + fn(srv_name, printer_name, level, *num, *ctr); + } + + return res1; +} + +static void spool_job_info_ctr(const char* srv_name, const char* printer_name, + uint32 level, + uint32 num, void *const *const ctr) +{ + display_job_info_ctr(out_hnd, ACTION_HEADER , level, num, ctr); + display_job_info_ctr(out_hnd, ACTION_ENUMERATE, level, num, ctr); + display_job_info_ctr(out_hnd, ACTION_FOOTER , level, num, ctr); +} + +/**************************************************************************** +nt spoolss query +****************************************************************************/ +void cmd_spoolss_enum_jobs(struct client_info *info) +{ + fstring srv_name; + fstring printer_name; + + void **ctr = NULL; + uint32 num = 0; + uint32 level = 1; + + if (!next_token(NULL, printer_name, NULL, sizeof(printer_name))) + { + report(out_hnd, "spoolopen \n"); + return; + } + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->myhostname); + strupper(srv_name); + + DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n", + printer_name, srv_name, smb_cli->user_name)); + + if (msrpc_spoolss_enum_jobs(smb_cli, + srv_name, smb_cli->user_name, printer_name, + level, &num, &ctr, + spool_job_info_ctr)) + { + DEBUG(5,("cmd_spoolss_enum_jobs: query succeeded\n")); + } + else + { + report(out_hnd, "FAILED\n"); + } + + free_void_array(num, ctr, free); +} + diff --git a/source3/rpcclient/display.c b/source3/rpcclient/display.c index 5bd4fb324b..d1dfbd117d 100644 --- a/source3/rpcclient/display.c +++ b/source3/rpcclient/display.c @@ -2724,6 +2724,244 @@ void display_printer_info_ctr(FILE *out_hnd, enum action_type action, } } +/**************************************************************************** +job info level 2 display function +****************************************************************************/ +void display_job_info_2(FILE *out_hnd, enum action_type action, + JOB_INFO_2 *const i2) +{ + if (i2 == NULL) + { + return; + } + + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "Job Info Level 2:\n"); + + break; + } + case ACTION_ENUMERATE: + { + fstring tmp; + + fprintf(out_hnd, "\tjob id:\t%d\n", i2->jobid); + unistr_to_ascii(tmp, i2->printername.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tprinter name:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->machinename.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tmachine name:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->username.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tusername:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->document.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tdocument:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->notifyname.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tnotify name:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->datatype.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tdata type:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->printprocessor.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tprint processor:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->parameters.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tparameters:\t%s\n", tmp); + unistr_to_ascii(tmp, i2->drivername.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tdriver name:\t%s\n", tmp); + fprintf(out_hnd, "\tDevice Mode:\tNOT DISPLAYED YET\n"); +/* + DEVICEMODE *devmode; +*/ + unistr_to_ascii(tmp, i2->text_status.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\ttext status:\t%s\n", tmp); + /* SEC_DESC sec_desc;*/ + fprintf(out_hnd, "\tstatus:\t%d\n", i2->status); + fprintf(out_hnd, "\tpriority:\t%d\n", i2->priority); + fprintf(out_hnd, "\tposition:\t%d\n", i2->position); + fprintf(out_hnd, "\tstarttime:\t%d\n", i2->starttime); + fprintf(out_hnd, "\tuntiltime:\t%d\n", i2->untiltime); + fprintf(out_hnd, "\ttotalpages:\t%d\n", i2->totalpages); + fprintf(out_hnd, "\tsize:\t%d\n", i2->size); +/* + SYSTEMTIME submitted; +*/ + fprintf(out_hnd, "\tsubmitted:\tNOT DISPLAYED YET\n"); + fprintf(out_hnd, "\ttimeelapsed:\t%d\n", i2->timeelapsed); + fprintf(out_hnd, "\tpagesprinted:\t%d\n", i2->pagesprinted); + } + case ACTION_FOOTER: + { + fprintf(out_hnd, "\n"); + break; + } + } + +} + +/**************************************************************************** +job info level 1 display function +****************************************************************************/ +void display_job_info_1(FILE *out_hnd, enum action_type action, + JOB_INFO_1 *const i1) +{ + if (i1 == NULL) + { + return; + } + + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "Job Info Level 1:\n"); + + break; + } + case ACTION_ENUMERATE: + { + fstring tmp; + + fprintf(out_hnd, "\tjob id:\t%d\n", i1->jobid); + unistr_to_ascii(tmp, i1->printername.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tprinter name:\t%s\n", tmp); + unistr_to_ascii(tmp, i1->machinename.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tmachine name:\t%s\n", tmp); + unistr_to_ascii(tmp, i1->username.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tusername:\t%s\n", tmp); + unistr_to_ascii(tmp, i1->document.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tdocument:\t%s\n", tmp); + unistr_to_ascii(tmp, i1->datatype.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\tdata type:\t%s\n", tmp); + unistr_to_ascii(tmp, i1->text_status.buffer, sizeof(tmp)-1); + fprintf(out_hnd, "\ttext status:\t%s\n", tmp); + fprintf(out_hnd, "\tstatus:\t%d\n", i1->status); + fprintf(out_hnd, "\tpriority:\t%d\n", i1->priority); + fprintf(out_hnd, "\tposition:\t%d\n", i1->position); + fprintf(out_hnd, "\ttotalpages:\t%d\n", i1->totalpages); +/* + SYSTEMTIME submitted; +*/ + fprintf(out_hnd, "\tsubmitted:\tNOT DISPLAYED YET\n"); + fprintf(out_hnd, "\tpagesprinted:\t%d\n", i1->pagesprinted); + + break; + } + case ACTION_FOOTER: + { + fprintf(out_hnd, "\n"); + break; + } + } + +} + +/**************************************************************************** +connection info level 2 container display function +****************************************************************************/ +void display_job_info_2_ctr(FILE *out_hnd, enum action_type action, + uint32 count, JOB_INFO_2 *const *const ctr) +{ + if (ctr == NULL) + { + fprintf(out_hnd, "display_job_info_2_ctr: unavailable due to an internal error\n"); + return; + } + + switch (action) + { + case ACTION_HEADER: + { + break; + } + case ACTION_ENUMERATE: + { + int i; + + for (i = 0; i < count; i++) + { + display_job_info_2(out_hnd, ACTION_HEADER , ctr[i]); + display_job_info_2(out_hnd, ACTION_ENUMERATE, ctr[i]); + display_job_info_2(out_hnd, ACTION_FOOTER , ctr[i]); + } + break; + } + case ACTION_FOOTER: + { + break; + } + } +} + +/**************************************************************************** +connection info level 1 container display function +****************************************************************************/ +void display_job_info_1_ctr(FILE *out_hnd, enum action_type action, + uint32 count, JOB_INFO_1 *const *const ctr) +{ + if (ctr == NULL) + { + fprintf(out_hnd, "display_job_info_1_ctr: unavailable due to an internal error\n"); + return; + } + + switch (action) + { + case ACTION_HEADER: + { + break; + } + case ACTION_ENUMERATE: + { + int i; + + for (i = 0; i < count; i++) + { + display_job_info_1(out_hnd, ACTION_HEADER , ctr[i]); + display_job_info_1(out_hnd, ACTION_ENUMERATE, ctr[i]); + display_job_info_1(out_hnd, ACTION_FOOTER , ctr[i]); + } + break; + } + case ACTION_FOOTER: + { + break; + } + } +} + +/**************************************************************************** +connection info container display function +****************************************************************************/ +void display_job_info_ctr(FILE *out_hnd, enum action_type action, + uint32 level, uint32 count, + void *const *const ctr) +{ + if (ctr == NULL) + { + fprintf(out_hnd, "display_job_info_ctr: unavailable due to an internal error\n"); + return; + } + + switch (level) + { + case 1: + { + display_job_info_1_ctr(out_hnd, action, + count, (JOB_INFO_1*const*const)ctr); + break; + } + case 2: + { + display_job_info_2_ctr(out_hnd, action, + count, (JOB_INFO_2*const*const)ctr); + break; + } + default: + { + fprintf(out_hnd, "display_job_info_ctr: Unknown Info Level\n"); + break; + } + } +} + #if COPY_THIS_TEMPLATE /**************************************************************************** display structure diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index e465a63767..06e6d0c089 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -239,9 +239,15 @@ commands[] = { "spoolenum", cmd_spoolss_enum_printers, - "Spool Printer Enum Test", + "Enumerate Printers", {COMPL_NONE, COMPL_NONE} }, + { + "spooljobs", + cmd_spoolss_enum_jobs, + " Enumerate Printer Jobs", + {COMPL_PRTLST, COMPL_NONE} + }, { "spoolopen", cmd_spoolss_open_printer_ex, @@ -1152,13 +1158,18 @@ static char *complete_printersenum(char *text, int state) if (state == 0) { + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, smb_cli->desthost); + strupper(srv_name); + free_print1_array(num, ctr); ctr = NULL; num = 0; /* Iterate all users */ - if (!msrpc_spoolss_enum_printers(smb_cli, 1, &num, - (void***)&ctr, + if (!msrpc_spoolss_enum_printers(smb_cli, srv_name, + 1, &num, (void***)&ctr, NULL)) { return NULL; -- cgit