From cf30a472f702d7b50c3a85e2cf2f55b46a2bd452 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 23 Apr 1999 14:47:45 +0000 Subject: [PATCH] Adding scheduler control pipe (\atsvc), client-side routines, and rpcclient command "at" (compatible with NT's "at" command - see rpcclient commit) - useful for remote NT administration. --- source/Makefile.in | 10 +- source/include/ntdomain.h | 1 + source/include/nterr.h | 2 + source/include/proto.h | 39 +++++ source/include/smb.h | 1 + source/libsmb/nterr.c | 3 +- source/rpc_client/cli_atsvc.c | 238 +++++++++++++++++++++++++++++ source/rpc_parse/parse_at.c | 275 ++++++++++++++++++++++++++++++++++ source/rpc_parse/parse_rpc.c | 11 ++ 9 files changed, 575 insertions(+), 5 deletions(-) create mode 100644 source/rpc_client/cli_atsvc.c create mode 100644 source/rpc_parse/parse_at.c diff --git a/source/Makefile.in b/source/Makefile.in index 12cf802e3cd..00fbf9d578f 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -137,7 +137,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \ rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \ rpc_parse/parse_samr.o rpc_parse/parse_srv.o \ rpc_parse/parse_wks.o rpc_parse/parse_sec.o \ - rpc_parse/parse_svc.o + rpc_parse/parse_svc.o rpc_parse/parse_at.o RPC_CLIENT_OBJ = \ rpc_client/cli_login.o \ @@ -148,7 +148,8 @@ RPC_CLIENT_OBJ = \ rpc_client/cli_wkssvc.o \ rpc_client/cli_srvsvc.o \ rpc_client/cli_svcctl.o \ - rpc_client/cli_samr.o + rpc_client/cli_samr.o \ + rpc_client/cli_atsvc.o LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \ @@ -165,8 +166,8 @@ SAMPASSDB_OBJ = passdb/sampassdb.o passdb/sampass.o passdb/sampassldap.o passdb/ PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \ passdb/pass_check.o passdb/ldap.o passdb/nispass.o \ - passdb/smbpasschange.o passdb/mysqlpass.o \ - lib/util_pwdb.o lib/domain_namemap.o lib/sids.o + passdb/smbpasschange.o passdb/mysqlpass.o \ + lib/util_pwdb.o lib/domain_namemap.o lib/sids.o PROFILE_OBJ = profile/profile.o @@ -241,6 +242,7 @@ RPCCLIENT_OBJ = rpcclient/rpcclient.o \ rpcclient/cmd_srvsvc.o \ rpcclient/cmd_svcctl.o \ rpcclient/cmd_netlogon.o \ + rpcclient/cmd_atsvc.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h index 5592a59eaa2..c4eccfc466a 100644 --- a/source/include/ntdomain.h +++ b/source/include/ntdomain.h @@ -42,6 +42,7 @@ #include "rpc_srvsvc.h" #include "rpc_svcctl.h" #include "rpc_wkssvc.h" +#include "rpc_atsvc.h" /* * A bunch of stuff that was put into smb.h diff --git a/source/include/nterr.h b/source/include/nterr.h index a94464a013e..2b5285a41ff 100644 --- a/source/include/nterr.h +++ b/source/include/nterr.h @@ -505,3 +505,5 @@ #define NT_STATUS_QUOTA_LIST_INCONSISTENT (614) #define NT_STATUS_FILE_IS_OFFLINE (615) #define NT_STATUS_NOTIFY_ENUM_DIR (0x10C) +#define NT_STATUS_MORE_ENTRIES (0x105) +#define NT_STATUS_NO_SUCH_JOB (0xEDE) /* scheduler */ diff --git a/source/include/proto.h b/source/include/proto.h index f7f3b69622c..0fb5962094d 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -1588,6 +1588,19 @@ void load_printers(void); BOOL profile_setup(BOOL rdonly); +/*The following definitions come from rpc_client/cli_atsvc.c */ + +BOOL at_add_job(struct cli_state *cli, uint16 fnum, + char *server_name, AT_JOB_INFO *info, char *command, + uint32 *jobid); +BOOL at_del_job(struct cli_state *cli, uint16 fnum, + char *server_name, uint32 min_jobid, uint32 max_jobid); +BOOL at_enum_jobs(struct cli_state *cli, uint16 fnum, + char *server_name, uint32 *num_jobs, + AT_ENUM_INFO *jobs, fstring *commands); +BOOL at_query_job(struct cli_state *cli, uint16 fnum, char *server_name, + uint32 jobid, AT_JOB_INFO *job, fstring command); + /*The following definitions come from rpc_client/cli_login.c */ BOOL cli_nt_setup_creds(struct cli_state *cli, uint16 fnum, @@ -1893,6 +1906,24 @@ BOOL do_wks_query_info(struct cli_state *cli, uint16 fnum, char *server_name, uint32 switch_value, WKS_INFO_100 *wks100); +/*The following definitions come from rpc_parse/parse_at.c */ + +void make_at_q_add_job(AT_Q_ADD_JOB *q_a, char *server, + AT_JOB_INFO *info, char *command); +void at_io_job_info(char *desc, AT_JOB_INFO *info, prs_struct *ps, int depth); +void at_io_q_add_job(char *desc, AT_Q_ADD_JOB *q_a, prs_struct *ps, int depth); +void at_io_r_add_job(char *desc, AT_R_ADD_JOB *r_a, prs_struct *ps, int depth); +void make_at_q_del_job(AT_Q_DEL_JOB *q_a, char *server, uint32 min_jobid, + uint32 max_jobid); +void at_io_q_del_job(char *desc, AT_Q_DEL_JOB *q_d, prs_struct *ps, int depth); +void at_io_r_del_job(char *desc, AT_R_DEL_JOB *r_d, prs_struct *ps, int depth); +void make_at_q_enum_jobs(AT_Q_ENUM_JOBS *q_e, char *server); +void at_io_q_enum_jobs(char *desc, AT_Q_ENUM_JOBS *q_e, prs_struct *ps, int depth); +void at_io_r_enum_jobs(char *desc, AT_R_ENUM_JOBS *r_e, prs_struct *ps, int depth); +void make_at_q_query_job(AT_Q_QUERY_JOB *q_q, char *server, uint32 jobid); +void at_io_q_query_job(char *desc, AT_Q_QUERY_JOB *q_q, prs_struct *ps, int depth); +void at_io_r_query_job(char *desc, AT_R_QUERY_JOB *r_q, prs_struct *ps, int depth); + /*The following definitions come from rpc_parse/parse_lsa.c */ void make_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name, @@ -2842,6 +2873,10 @@ BOOL api_svcctl_rpc(pipes_struct *p, prs_struct *data); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); +/*The following definitions come from rpcclient/cmd_atsvc.c */ + +void cmd_at(struct client_info *info); + /*The following definitions come from rpcclient/cmd_lsarpc.c */ void cmd_lsa_query_info(struct client_info *info); @@ -2977,6 +3012,10 @@ char *get_svc_start_type_str(uint32 type); void display_query_svc_cfg(FILE *out_hnd, enum action_type action, QUERY_SERVICE_CONFIG *cfg); void display_svc_info(FILE *out_hnd, enum action_type action, ENUM_SRVC_STATUS *svc); +void display_at_enum_info(FILE *out_hnd, enum action_type action, + uint32 num_jobs, AT_ENUM_INFO *jobs, fstring *commands); +void display_at_job_info(FILE *out_hnd, enum action_type action, + AT_JOB_INFO *job, fstring command); /*The following definitions come from rpcclient/rpcclient.c */ diff --git a/source/include/smb.h b/source/include/smb.h index 789b3a81de8..605218d51f4 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -359,6 +359,7 @@ typedef char fstring[FSTRING_LEN]; #define PIPE_NTSVCS "\\PIPE\\ntsvcs" #define PIPE_LSASS "\\PIPE\\lsass" #define PIPE_LSARPC "\\PIPE\\lsarpc" +#define PIPE_ATSVC "\\PIPE\\atsvc" /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */ diff --git a/source/libsmb/nterr.c b/source/libsmb/nterr.c index d2f9335000d..b094050a33a 100644 --- a/source/libsmb/nterr.c +++ b/source/libsmb/nterr.c @@ -514,6 +514,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB }, { NULL, 0 } }; @@ -525,7 +526,7 @@ char *get_nt_error_msg(uint32 nt_code) static pstring msg; int idx = 0; - pstrcpy(msg, "Unknown NT error"); + snprintf(msg, sizeof(msg), "%08x", nt_code); nt_code &= 0xFFFF; diff --git a/source/rpc_client/cli_atsvc.c b/source/rpc_client/cli_atsvc.c new file mode 100644 index 00000000000..bebc4d0bc76 --- /dev/null +++ b/source/rpc_client/cli_atsvc.c @@ -0,0 +1,238 @@ +/* + * Unix SMB/Netbios implementation. + * Version 2.1. + * RPC client routines: scheduler service + * Copyright (C) Matthew Chapman 1999, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1999, + * Copyright (C) Andrew Tridgell 1992-1999. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +extern int DEBUGLEVEL; + +/**************************************************************************** +add a job to the scheduler +****************************************************************************/ +BOOL at_add_job(struct cli_state *cli, uint16 fnum, + char *server_name, AT_JOB_INFO *info, char *command, + uint32 *jobid) +{ + prs_struct rbuf; + prs_struct buf; + AT_Q_ADD_JOB q_a; + BOOL p = False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api AT_ADD_JOB */ + + DEBUG(4,("Scheduler Add Job\n")); + + /* store the parameters */ + make_at_q_add_job(&q_a, server_name, info, command); + + /* turn parameters into data stream */ + at_io_q_add_job("", &q_a, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, AT_ADD_JOB, &buf, &rbuf)) + { + AT_R_ADD_JOB r_a; + + at_io_r_add_job("", &r_a, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_a.status != 0) + { + /* report error code */ + DEBUG(0,("AT_R_ADD_JOB: %s\n", get_nt_error_msg(r_a.status))); + p = False; + } + + if (p) + { + *jobid = r_a.jobid; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return p; +} + +/**************************************************************************** +dequeue a job +****************************************************************************/ +BOOL at_del_job(struct cli_state *cli, uint16 fnum, + char *server_name, uint32 min_jobid, uint32 max_jobid) +{ + prs_struct rbuf; + prs_struct buf; + AT_Q_DEL_JOB q_d; + BOOL p = False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api AT_DEL_JOB */ + + DEBUG(4,("Scheduler Delete Job\n")); + + /* store the parameters */ + make_at_q_del_job(&q_d, server_name, min_jobid, max_jobid); + + /* turn parameters into data stream */ + at_io_q_del_job("", &q_d, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, AT_DEL_JOB, &buf, &rbuf)) + { + AT_R_DEL_JOB r_d; + + at_io_r_del_job("", &r_d, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_d.status != 0) + { + /* report error code */ + DEBUG(0,("AT_R_DEL_JOB: %s\n", get_nt_error_msg(r_d.status))); + p = False; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return p; +} + +/**************************************************************************** +enumerate scheduled jobs +****************************************************************************/ +BOOL at_enum_jobs(struct cli_state *cli, uint16 fnum, + char *server_name, uint32 *num_jobs, + AT_ENUM_INFO *jobs, fstring *commands) +{ + prs_struct rbuf; + prs_struct buf; + AT_Q_ENUM_JOBS q_e; + BOOL p = False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api AT_DEL_JOB */ + + DEBUG(4,("Scheduler Enumerate Jobs\n")); + + /* store the parameters */ + make_at_q_enum_jobs(&q_e, server_name); + + /* turn parameters into data stream */ + at_io_q_enum_jobs("", &q_e, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, AT_ENUM_JOBS, &buf, &rbuf)) + { + AT_R_ENUM_JOBS r_e; + + at_io_r_enum_jobs("", &r_e, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_e.status != 0) + { + /* report error code */ + DEBUG(0,("AT_R_ENUM_JOBS: %s\n", get_nt_error_msg(r_e.status))); + p = False; + } + + if (p) + { + int i; + + *num_jobs = r_e.num_entries; + memcpy(jobs, &r_e.info, r_e.num_entries * sizeof(AT_ENUM_INFO)); + + for (i = 0; i < r_e.num_entries; i++) + { + unistr2_to_ascii(commands[i], &r_e.command[i], + sizeof(commands[i])); + } + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return p; +} + +/**************************************************************************** +query job information +****************************************************************************/ +BOOL at_query_job(struct cli_state *cli, uint16 fnum, char *server_name, + uint32 jobid, AT_JOB_INFO *job, fstring command) +{ + prs_struct rbuf; + prs_struct buf; + AT_Q_QUERY_JOB q_q; + BOOL p = False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api AT_QUERY_JOB */ + + DEBUG(4,("Scheduler Query Job\n")); + + /* store the parameters */ + make_at_q_query_job(&q_q, server_name, jobid); + + /* turn parameters into data stream */ + at_io_q_query_job("", &q_q, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, AT_QUERY_JOB, &buf, &rbuf)) + { + AT_R_QUERY_JOB r_q; + + at_io_r_query_job("", &r_q, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_q.status != 0) + { + /* report error code */ + DEBUG(0,("AT_R_QUERY_JOB: %s\n", get_nt_error_msg(r_q.status))); + p = False; + } + + if (p) + { + memcpy(job, &r_q.info, sizeof(AT_JOB_INFO)); + unistr2_to_ascii(command, &r_q.command, + sizeof(fstring)-1); + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return p; +} diff --git a/source/rpc_parse/parse_at.c b/source/rpc_parse/parse_at.c new file mode 100644 index 00000000000..2eb72c8aea1 --- /dev/null +++ b/source/rpc_parse/parse_at.c @@ -0,0 +1,275 @@ +/* + * Unix SMB/Netbios implementation. + * Version 2.1. + * RPC parsing routines: scheduler service + * Copyright (C) Matthew Chapman 1999, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1999, + * Copyright (C) Andrew Tridgell 1992-1999. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +extern int DEBUGLEVEL; + +/******************************************************************* + make_at_q_add_job + ********************************************************************/ +void make_at_q_add_job(AT_Q_ADD_JOB *q_a, char *server, + AT_JOB_INFO *info, char *command) +{ + DEBUG(5,("make_at_q_add_job\n")); + + make_buf_unistr2(&(q_a->uni_srv_name), &(q_a->ptr_srv_name), server); + memcpy(&(q_a->info), info, sizeof(q_a->info)); + make_unistr2(&(q_a->command), command, strlen(command)+1); +} + +/******************************************************************* +reads or writes a AT_JOB_INFO structure. +********************************************************************/ +void at_io_job_info(char *desc, AT_JOB_INFO *info, prs_struct *ps, int depth) +{ + if (info == NULL) return; + + prs_debug(ps, depth, desc, "at_io_job_info"); + depth++; + + prs_align(ps); + + prs_uint32("time", ps, depth, &(info->time)); + prs_uint32("monthdays", ps, depth, &(info->monthdays)); + prs_uint8("weekdays", ps, depth, &(info->weekdays)); + prs_uint8("flags", ps, depth, &(info->flags)); + prs_align(ps); + + prs_uint32("ptr_command", ps, depth, &(info->ptr_command)); +} + +/******************************************************************* +reads or writes a AT_Q_ADD_JOB structure. +********************************************************************/ +void at_io_q_add_job(char *desc, AT_Q_ADD_JOB *q_a, prs_struct *ps, int depth) +{ + if (q_a == NULL) return; + + prs_debug(ps, depth, desc, "at_q_add_job"); + depth++; + + prs_align(ps); + prs_uint32("ptr_srv_name", ps, depth, &(q_a->ptr_srv_name)); + smb_io_unistr2("", &(q_a->uni_srv_name), q_a->ptr_srv_name, ps, depth); + at_io_job_info("", &(q_a->info), ps, depth); + smb_io_unistr2("", &(q_a->command), q_a->info.ptr_command, ps, depth); +} + +/******************************************************************* +reads or writes a AT_R_ADD_JOB structure. +********************************************************************/ +void at_io_r_add_job(char *desc, AT_R_ADD_JOB *r_a, prs_struct *ps, int depth) +{ + if (r_a == NULL) return; + + prs_debug(ps, depth, desc, "at_r_add_job"); + depth++; + + prs_align(ps); + prs_uint32("jobid", ps, depth, &(r_a->jobid)); + prs_uint32("status", ps, depth, &(r_a->status)); +} + +/******************************************************************* + make_at_q_del_job + ********************************************************************/ +void make_at_q_del_job(AT_Q_DEL_JOB *q_a, char *server, uint32 min_jobid, + uint32 max_jobid) +{ + DEBUG(5,("make_at_q_del_job\n")); + + make_buf_unistr2(&(q_a->uni_srv_name), &(q_a->ptr_srv_name), server); + q_a->min_jobid = min_jobid; + q_a->max_jobid = max_jobid; +} + +/******************************************************************* +reads or writes a AT_Q_DEL_JOB structure. +********************************************************************/ +void at_io_q_del_job(char *desc, AT_Q_DEL_JOB *q_d, prs_struct *ps, int depth) +{ + if (q_d == NULL) return; + + prs_debug(ps, depth, desc, "at_q_del_job"); + depth++; + + prs_align(ps); + + prs_uint32("ptr_srv_name", ps, depth, &(q_d->ptr_srv_name)); + smb_io_unistr2("", &(q_d->uni_srv_name), q_d->ptr_srv_name, ps, depth); + prs_align(ps); + prs_uint32("min_jobid", ps, depth, &(q_d->min_jobid)); + prs_uint32("max_jobid", ps, depth, &(q_d->max_jobid)); +} + +/******************************************************************* +reads or writes a AT_R_DEL_JOB structure. +********************************************************************/ +void at_io_r_del_job(char *desc, AT_R_DEL_JOB *r_d, prs_struct *ps, int depth) +{ + if (r_d == NULL) return; + + prs_debug(ps, depth, desc, "at_r_del_job"); + depth++; + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_d->status)); +} + +/******************************************************************* + make_at_q_enum_jobs + ********************************************************************/ +void make_at_q_enum_jobs(AT_Q_ENUM_JOBS *q_e, char *server) +{ + DEBUG(5,("make_at_q_enum_jobs\n")); + + make_buf_unistr2(&(q_e->uni_srv_name), &(q_e->ptr_srv_name), server); + q_e->unknown0 = 0; + q_e->unknown1 = 0; + q_e->max_len = 0xffff; + q_e->ptr_resume = 1; + q_e->hnd_resume = 0; +} + +/******************************************************************* +reads or writes a AT_Q_ENUM_JOBS structure. +********************************************************************/ +void at_io_q_enum_jobs(char *desc, AT_Q_ENUM_JOBS *q_e, prs_struct *ps, int depth) +{ + if (q_e == NULL) return; + + prs_debug(ps, depth, desc, "at_q_enum_jobs"); + depth++; + + prs_align(ps); + prs_uint32("ptr_srv_name", ps, depth, &(q_e->ptr_srv_name)); + smb_io_unistr2("", &(q_e->uni_srv_name), q_e->ptr_srv_name, ps, depth); + prs_align(ps); + prs_uint32("unknown0", ps, depth, &(q_e->unknown0)); + prs_uint32("unknown1", ps, depth, &(q_e->unknown1)); + prs_uint32("max_len" , ps, depth, &(q_e->max_len )); + + prs_uint32("ptr_resume", ps, depth, &(q_e->ptr_resume)); + prs_uint32("hnd_resume", ps, depth, &(q_e->hnd_resume)); +} + +/******************************************************************* +reads or writes a AT_R_ENUM_JOBS structure. +********************************************************************/ +void at_io_r_enum_jobs(char *desc, AT_R_ENUM_JOBS *r_e, prs_struct *ps, int depth) +{ + if (r_e == NULL) return; + + prs_debug(ps, depth, desc, "at_r_enum_jobs"); + depth++; + + prs_align(ps); + prs_uint32("num_entries", ps, depth, &(r_e->num_entries)); + prs_uint32("ptr_entries", ps, depth, &(r_e->ptr_entries)); + + if (r_e->ptr_entries != 0) + { + int i; + + prs_uint32("num_entries2", ps, depth, &(r_e->num_entries2)); + if (r_e->num_entries2 != r_e->num_entries) + { + /* RPC fault */ + return; + } + + SMB_ASSERT_ARRAY(r_e->info, r_e->num_entries2); + + for (i = 0; i < r_e->num_entries2; i++) + { + prs_grow(ps); + prs_uint32("jobid", ps, depth, &(r_e->info[i].jobid)); + at_io_job_info("", &(r_e->info[i].info), ps, depth); + } + + for (i = 0; i < r_e->num_entries2; i++) + { + prs_grow(ps); + smb_io_unistr2("", &(r_e->command[i]), + r_e->info[i].info.ptr_command, ps, depth); + } + } + + prs_align(ps); + prs_uint32("total_entries", ps, depth, &(r_e->total_entries)); + prs_uint32("ptr_resume" , ps, depth, &(r_e->ptr_resume )); + prs_uint32("hnd_resume" , ps, depth, &(r_e->hnd_resume )); + + prs_uint32("status", ps, depth, &(r_e->status)); +} + +/******************************************************************* + make_at_q_query_job + ********************************************************************/ +void make_at_q_query_job(AT_Q_QUERY_JOB *q_q, char *server, uint32 jobid) +{ + DEBUG(5,("make_at_q_query_job\n")); + + make_buf_unistr2(&(q_q->uni_srv_name), &(q_q->ptr_srv_name), server); + q_q->jobid = jobid; +} + +/******************************************************************* +reads or writes a AT_Q_QUERY_JOB structure. +********************************************************************/ +void at_io_q_query_job(char *desc, AT_Q_QUERY_JOB *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) return; + + prs_debug(ps, depth, desc, "at_q_query_job"); + depth++; + + prs_align(ps); + prs_uint32("ptr_srv_name", ps, depth, &(q_q->ptr_srv_name)); + smb_io_unistr2("", &(q_q->uni_srv_name), q_q->ptr_srv_name, ps, depth); + prs_align(ps); + prs_uint32("jobid", ps, depth, &(q_q->jobid)); +} + +/******************************************************************* +reads or writes a AT_R_QUERY_JOB structure. +********************************************************************/ +void at_io_r_query_job(char *desc, AT_R_QUERY_JOB *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "at_r_query_job"); + depth++; + + prs_align(ps); + prs_uint32("ptr_info", ps, depth, &(r_q->ptr_info)); + if (r_q->ptr_info != 0) + { + at_io_job_info("", &(r_q->info), ps, depth); + smb_io_unistr2("", &(r_q->command), r_q->info.ptr_command, ps, depth); + } + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_q->status)); +} diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c index 9716b35b78a..81e7ffa1162 100644 --- a/source/rpc_parse/parse_rpc.c +++ b/source/rpc_parse/parse_rpc.c @@ -122,6 +122,16 @@ interface/version dce/rpc pipe identification }, 0x01 \ } \ +#define SYNT_ATSVC_V1 \ +{ \ + { \ + 0x82, 0x06, 0xf7, 0x1f, \ + 0x51, 0x0a, 0xe8, 0x30, \ + 0x07, 0x6d, 0x74, 0x0b, \ + 0xe8, 0xce, 0xe9, 0x8b \ + }, 0x01 \ +} \ + #define SYNT_NONE_V0 \ { \ { \ @@ -142,6 +152,7 @@ struct pipe_id_info pipe_names [] = { PIPE_SVCCTL , SYNT_SVCCTL_V2 , PIPE_NTSVCS , TRANS_SYNT_V2 }, { PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 }, { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 }, + { PIPE_ATSVC , SYNT_ATSVC_V1 , PIPE_ATSVC , TRANS_SYNT_V2 }, { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 } }; -- 2.34.1