2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Marcin Krzysztof Porwit 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #define DBGC_CLASS DBGC_RPC_PARSE
25 /********************************************************************
26 ********************************************************************/
28 bool prs_ev_open_unknown0( const char *desc
, prs_struct
*ps
, int depth
, EVENTLOG_OPEN_UNKNOWN0
*u
)
33 if ( !prs_uint16("", ps
, depth
, &u
->unknown1
) )
35 if ( !prs_uint16("", ps
, depth
, &u
->unknown2
) )
41 /********************************************************************
42 ********************************************************************/
44 bool eventlog_io_q_open_eventlog(const char *desc
, EVENTLOG_Q_OPEN_EVENTLOG
*q_u
,
45 prs_struct
*ps
, int depth
)
50 prs_debug(ps
, depth
, desc
, "eventlog_io_q_open_eventlog");
56 if ( !prs_pointer("", ps
, depth
, (void*)&q_u
->unknown0
, sizeof(EVENTLOG_OPEN_UNKNOWN0
), (PRS_POINTER_CAST
)prs_ev_open_unknown0
))
59 if ( !prs_unistr4("logname", ps
, depth
, &q_u
->logname
) )
64 if ( !prs_unistr4("servername", ps
, depth
, &q_u
->servername
) )
69 if ( !prs_uint32("unknown1", ps
, depth
, &q_u
->unknown1
) )
71 if ( !prs_uint32("unknown2", ps
, depth
, &q_u
->unknown2
) )
77 bool eventlog_io_r_open_eventlog(const char *desc
, EVENTLOG_R_OPEN_EVENTLOG
*r_u
,
78 prs_struct
*ps
, int depth
)
83 prs_debug(ps
, depth
, desc
, "eventlog_io_r_open_eventlog");
89 if(!(smb_io_pol_hnd("log handle", &(r_u
->handle
), ps
, depth
)))
92 if(!(prs_ntstatus("status code", ps
, depth
, &r_u
->status
)))
98 bool eventlog_io_q_get_num_records(const char *desc
, EVENTLOG_Q_GET_NUM_RECORDS
*q_u
,
99 prs_struct
*ps
, int depth
)
104 prs_debug(ps
, depth
, desc
, "eventlog_io_q_get_num_records");
110 if(!(smb_io_pol_hnd("log handle", &(q_u
->handle
), ps
, depth
)))
116 bool eventlog_io_r_get_num_records(const char *desc
, EVENTLOG_R_GET_NUM_RECORDS
*r_u
,
117 prs_struct
*ps
, int depth
)
122 prs_debug(ps
, depth
, desc
, "eventlog_io_r_get_num_records");
128 if(!(prs_uint32("num records", ps
, depth
, &(r_u
->num_records
))))
131 if(!(prs_ntstatus("status code", ps
, depth
, &r_u
->status
)))
137 bool eventlog_io_q_get_oldest_entry(const char *desc
, EVENTLOG_Q_GET_OLDEST_ENTRY
*q_u
,
138 prs_struct
*ps
, int depth
)
143 prs_debug(ps
, depth
, desc
, "eventlog_io_q_get_oldest_entry");
149 if(!(smb_io_pol_hnd("log handle", &(q_u
->handle
), ps
, depth
)))
155 bool eventlog_io_r_get_oldest_entry(const char *desc
, EVENTLOG_R_GET_OLDEST_ENTRY
*r_u
,
156 prs_struct
*ps
, int depth
)
161 prs_debug(ps
, depth
, desc
, "eventlog_io_r_get_oldest_entry");
167 if(!(prs_uint32("oldest entry", ps
, depth
, &(r_u
->oldest_entry
))))
170 if(!(prs_ntstatus("status code", ps
, depth
, &r_u
->status
)))
176 bool eventlog_io_q_read_eventlog(const char *desc
, EVENTLOG_Q_READ_EVENTLOG
*q_u
,
177 prs_struct
*ps
, int depth
)
182 prs_debug(ps
, depth
, desc
, "eventlog_io_q_read_eventlog");
188 if(!(smb_io_pol_hnd("log handle", &(q_u
->handle
), ps
, depth
)))
191 if(!(prs_uint32("read flags", ps
, depth
, &(q_u
->flags
))))
194 if(!(prs_uint32("read offset", ps
, depth
, &(q_u
->offset
))))
197 if(!(prs_uint32("read buf size", ps
, depth
, &(q_u
->max_read_size
))))
202 /** Structure of response seems to be:
203 DWORD num_bytes_in_resp -- MUST be the same as q_u->max_read_size
205 EVENTLOGRECORD record
206 DWORD sent_size -- sum of EVENTLOGRECORD lengths if records returned, 0 otherwise
207 DWORD real_size -- 0 if records returned, otherwise length of next record to be returned
209 bool eventlog_io_r_read_eventlog(const char *desc
,
210 EVENTLOG_Q_READ_EVENTLOG
*q_u
,
211 EVENTLOG_R_READ_EVENTLOG
*r_u
,
215 Eventlog_entry
*entry
;
216 uint32 record_written
= 0;
217 uint32 record_total
= 0;
222 prs_debug(ps
, depth
, desc
, "eventlog_io_r_read_eventlog");
225 /* First, see if we've read more logs than we can output */
227 if(r_u
->num_bytes_in_resp
> q_u
->max_read_size
) {
230 /* remove the size of the last entry from the list */
232 while(entry
->next
!= NULL
)
235 r_u
->num_bytes_in_resp
-= entry
->record
.length
;
237 /* do not output the last log entry */
243 record_total
= r_u
->num_records
;
245 if(r_u
->num_bytes_in_resp
!= 0)
246 r_u
->sent_size
= r_u
->num_bytes_in_resp
;
248 r_u
->real_size
= r_u
->bytes_in_next_record
;
252 if(!(prs_uint32("bytes in resp", ps
, depth
, &(q_u
->max_read_size
))))
255 while(entry
!= NULL
&& record_written
< record_total
)
257 DEBUG(11, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written
, record_total
));
259 /* Encode the actual eventlog record record */
261 if(!(prs_uint32("length", ps
, depth
, &(entry
->record
.length
))))
263 if(!(prs_uint32("reserved", ps
, depth
, &(entry
->record
.reserved1
))))
265 if(!(prs_uint32("record number", ps
, depth
, &(entry
->record
.record_number
))))
267 if(!(prs_uint32("time generated", ps
, depth
, &(entry
->record
.time_generated
))))
269 if(!(prs_uint32("time written", ps
, depth
, &(entry
->record
.time_written
))))
271 if(!(prs_uint32("event id", ps
, depth
, &(entry
->record
.event_id
))))
273 if(!(prs_uint16("event type", ps
, depth
, &(entry
->record
.event_type
))))
275 if(!(prs_uint16("num strings", ps
, depth
, &(entry
->record
.num_strings
))))
277 if(!(prs_uint16("event category", ps
, depth
, &(entry
->record
.event_category
))))
279 if(!(prs_uint16("reserved2", ps
, depth
, &(entry
->record
.reserved2
))))
281 if(!(prs_uint32("closing record", ps
, depth
, &(entry
->record
.closing_record_number
))))
283 if(!(prs_uint32("string offset", ps
, depth
, &(entry
->record
.string_offset
))))
285 if(!(prs_uint32("user sid length", ps
, depth
, &(entry
->record
.user_sid_length
))))
287 if(!(prs_uint32("user sid offset", ps
, depth
, &(entry
->record
.user_sid_offset
))))
289 if(!(prs_uint32("data length", ps
, depth
, &(entry
->record
.data_length
))))
291 if(!(prs_uint32("data offset", ps
, depth
, &(entry
->record
.data_offset
))))
296 /* Now encoding data */
298 if(!(prs_uint8s(False
, "buffer", ps
, depth
, entry
->data
,
299 entry
->record
.length
- sizeof(Eventlog_record
) - sizeof(entry
->record
.length
))))
306 if(!(prs_uint32("length 2", ps
, depth
, &(entry
->record
.length
))))
312 } /* end of encoding EVENTLOGRECORD */
314 /* Now pad with whitespace until the end of the response buffer */
316 if (q_u
->max_read_size
- r_u
->num_bytes_in_resp
) {
317 if (!r_u
->end_of_entries_padding
) {
321 if(!(prs_uint8s(False
, "end of entries padding", ps
,
322 depth
, r_u
->end_of_entries_padding
,
323 (q_u
->max_read_size
- r_u
->num_bytes_in_resp
)))) {
324 free(r_u
->end_of_entries_padding
);
328 free(r_u
->end_of_entries_padding
);
331 /* We had better be DWORD aligned here */
333 if(!(prs_uint32("sent size", ps
, depth
, &(r_u
->sent_size
))))
335 if(!(prs_uint32("real size", ps
, depth
, &(r_u
->real_size
))))
337 if(!(prs_ntstatus("status code", ps
, depth
, &r_u
->status
)))
343 /** The windows client seems to be doing something funny with the file name
345 ClearEventLog(handle, "backup_file")
346 on the client side will result in the backup file name looking like this on the
348 \??\${CWD of client}\backup_file
349 If an absolute path gets specified, such as
350 ClearEventLog(handle, "C:\\temp\\backup_file")
351 then it is still mangled by the client into this:
352 \??\C:\temp\backup_file
353 when it is on the wire.
354 I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
355 would be added in given that the backup file gets written on the server side. */
357 bool eventlog_io_q_clear_eventlog(const char *desc
, EVENTLOG_Q_CLEAR_EVENTLOG
*q_u
,
358 prs_struct
*ps
, int depth
)
363 prs_debug(ps
, depth
, desc
, "eventlog_io_q_clear_eventlog");
368 if(!(smb_io_pol_hnd("log handle", &(q_u
->handle
), ps
, depth
)))
371 if ( !prs_unistr4("backupfile", ps
, depth
, &q_u
->backupfile
) )
378 bool eventlog_io_r_clear_eventlog(const char *desc
, EVENTLOG_R_CLEAR_EVENTLOG
*r_u
,
379 prs_struct
*ps
, int depth
)
384 prs_debug(ps
, depth
, desc
, "eventlog_io_r_clear_eventlog");
389 if(!(prs_ntstatus("status code", ps
, depth
, &r_u
->status
)))