debugging rpcclient spoolenum and spooljobs commands. oh, did i forget
authorLuke Leighton <lkcl@samba.org>
Tue, 9 Nov 1999 19:35:30 +0000 (19:35 +0000)
committerLuke Leighton <lkcl@samba.org>
Tue, 9 Nov 1999 19:35:30 +0000 (19:35 +0000)
to mention, there's a spooljobs <printer name> 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
source3/include/nterr.h
source3/include/proto.h
source3/include/rpc_spoolss.h
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_spoolss.c
source3/rpc_parse/parse_spoolss.c
source3/rpcclient/cmd_spoolss.c
source3/rpcclient/display.c
source3/rpcclient/rpcclient.c

index 1b7a7b55a6a2ddd438548956a1d4396409ac9ce9..c36f619ef25a1920f81180c93ce370d696ed605f 100644 (file)
@@ -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 */
 
index 21e245d287f1c0e09c3f8d56bebeda368599890a..86c049495c959936e21e221bc4cc7da1c985b443 100644 (file)
@@ -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
index f98dffad2af46a063b0ab72536ca3f8b6dd62474..0b0ca16c546fcad6dd99b30049669331bd45baec 100644 (file)
@@ -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  */
 
index 8eb0c7efb1ee732be7e6ac24c56c639fb9f09a00..8b3410e87c0e72202b11928678f95fd92bc307a4 100755 (executable)
@@ -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;
index 7e2bf426fa83900dd006135349ba162a7bc3981c..df09f023983622b2805a6a2f1fa4a4376e44d5ab 100644 (file)
@@ -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 */
                {
index 1875ae5400cc5aa9e41df5225f6c51b6f38bf568..09780b24771f56f53a389addd4cc8ac5469544e3 100644 (file)
@@ -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;
index 059b21644fbe7b71e729d752b102402e53f40ce9..6f1cfdc63c2dff0eed78e57afd5765bca4816370 100644 (file)
@@ -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;i<r_u->returned;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->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 */
+                       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; i<r_u->numofjobs; i++)
+                       case 1:
                        {
-                               if (ps->io)
+                               JOB_INFO_1 *info;
+                               for (i=0; i<r_u->numofjobs; 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; i<r_u->numofjobs; i++)
+                       case 2:
                        {
-                               if (ps->io)
+                               JOB_INFO_2 *info;
+                               for (i=0; i<r_u->numofjobs; 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);
index 073ee244956be3ed956f62d8653193d747acf559..9b5aa5b3e07b712d80a1b72ec77e06114d39a2be 100644 (file)
@@ -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 <printer name>\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);
+}
+
index 5bd4fb324bcc5fd60eff4e576ccdd82d57b072af..d1dfbd117d3d1983b27716a1fa900d7df174cdbb 100644 (file)
@@ -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
index e465a637672e4b403b5d7b2675f2855e44c43984..06e6d0c089b0835d6f9e697cfe126e807b8a3428 100644 (file)
@@ -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,
+               "<printer name> 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;