1/* 2 * Unix SMB/CIFS implementation. 3 * RPC Pipe client / server routines 4 * Copyright (C) Marcin Krzysztof Porwit 2005. 5 * 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 2 of the License, or 9 * (at your option) any later version. 10 * 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. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21#include "includes.h" 22 23#undef DBGC_CLASS 24#define DBGC_CLASS DBGC_RPC_PARSE 25 26/******************************************************************** 27********************************************************************/ 28 29BOOL prs_ev_open_unknown0( const char *desc, prs_struct *ps, int depth, EVENTLOG_OPEN_UNKNOWN0 *u ) 30{ 31 if ( !u ) 32 return False; 33 34 if ( !prs_uint16("", ps, depth, &u->unknown1) ) 35 return False; 36 if ( !prs_uint16("", ps, depth, &u->unknown2) ) 37 return False; 38 39 return True; 40} 41 42/******************************************************************** 43********************************************************************/ 44 45BOOL eventlog_io_q_open_eventlog(const char *desc, EVENTLOG_Q_OPEN_EVENTLOG *q_u, 46 prs_struct *ps, int depth) 47{ 48 if(q_u == NULL) 49 return False; 50 51 prs_debug(ps, depth, desc, "eventlog_io_q_open_eventlog"); 52 depth++; 53 54 if(!prs_align(ps)) 55 return False; 56 57 if ( !prs_pointer("", ps, depth, (void*)&q_u->unknown0, sizeof(EVENTLOG_OPEN_UNKNOWN0), (PRS_POINTER_CAST)prs_ev_open_unknown0)) 58 return False; 59 60 if ( !prs_unistr4("logname", ps, depth, &q_u->logname) ) 61 return False; 62 if ( !prs_align(ps) ) 63 return False; 64 65 if ( !prs_unistr4("servername", ps, depth, &q_u->servername) ) 66 return False; 67 if ( !prs_align(ps) ) 68 return False; 69 70 if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) ) 71 return False; 72 if ( !prs_uint32("unknown2", ps, depth, &q_u->unknown2) ) 73 return False; 74 75 return True; 76} 77 78BOOL eventlog_io_r_open_eventlog(const char *desc, EVENTLOG_R_OPEN_EVENTLOG *r_u, 79 prs_struct *ps, int depth) 80{ 81 if(r_u == NULL) 82 return False; 83 84 prs_debug(ps, depth, desc, "eventlog_io_r_open_eventlog"); 85 depth++; 86 87 if(!prs_align(ps)) 88 return False; 89 90 if(!(smb_io_pol_hnd("log handle", &(r_u->handle), ps, depth))) 91 return False; 92 93 if(!(prs_ntstatus("status code", ps, depth, &r_u->status))) 94 return False; 95 96 return True; 97} 98 99BOOL eventlog_io_q_get_num_records(const char *desc, EVENTLOG_Q_GET_NUM_RECORDS *q_u, 100 prs_struct *ps, int depth) 101{ 102 if(q_u == NULL) 103 return False; 104 105 prs_debug(ps, depth, desc, "eventlog_io_q_get_num_records"); 106 depth++; 107 108 if(!(prs_align(ps))) 109 return False; 110 111 if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth))) 112 return False; 113 114 return True; 115} 116 117BOOL eventlog_io_r_get_num_records(const char *desc, EVENTLOG_R_GET_NUM_RECORDS *r_u, 118 prs_struct *ps, int depth) 119{ 120 if(r_u == NULL) 121 return False; 122 123 prs_debug(ps, depth, desc, "eventlog_io_r_get_num_records"); 124 depth++; 125 126 if(!(prs_align(ps))) 127 return False; 128 129 if(!(prs_uint32("num records", ps, depth, &(r_u->num_records)))) 130 return False; 131 132 if(!(prs_ntstatus("status code", ps, depth, &r_u->status))) 133 return False; 134 135 return True; 136} 137 138BOOL eventlog_io_q_get_oldest_entry(const char *desc, EVENTLOG_Q_GET_OLDEST_ENTRY *q_u, 139 prs_struct *ps, int depth) 140{ 141 if(q_u == NULL) 142 return False; 143 144 prs_debug(ps, depth, desc, "eventlog_io_q_get_oldest_entry"); 145 depth++; 146 147 if(!(prs_align(ps))) 148 return False; 149 150 if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth))) 151 return False; 152 153 return True; 154} 155 156BOOL eventlog_io_r_get_oldest_entry(const char *desc, EVENTLOG_R_GET_OLDEST_ENTRY *r_u, 157 prs_struct *ps, int depth) 158{ 159 if(r_u == NULL) 160 return False; 161 162 prs_debug(ps, depth, desc, "eventlog_io_r_get_oldest_entry"); 163 depth++; 164 165 if(!(prs_align(ps))) 166 return False; 167 168 if(!(prs_uint32("oldest entry", ps, depth, &(r_u->oldest_entry)))) 169 return False; 170 171 if(!(prs_ntstatus("status code", ps, depth, &r_u->status))) 172 return False; 173 174 return True; 175} 176 177BOOL eventlog_io_q_close_eventlog(const char *desc, EVENTLOG_Q_CLOSE_EVENTLOG *q_u, 178 prs_struct *ps, int depth) 179{ 180 if(q_u == NULL) 181 return False; 182 183 prs_debug(ps, depth, desc, "eventlog_io_q_close_eventlog"); 184 depth++; 185 186 if(!(prs_align(ps))) 187 return False; 188 189 if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth))) 190 return False; 191 192 return True; 193} 194 195BOOL eventlog_io_r_close_eventlog(const char *desc, EVENTLOG_R_CLOSE_EVENTLOG *r_u, 196 prs_struct *ps, int depth) 197{ 198 if(r_u == NULL) 199 return False; 200 201 prs_debug(ps, depth, desc, "eventlog_io_r_close_eventlog"); 202 depth++; 203 204 if(!(prs_align(ps))) 205 return False; 206 207 if(!(smb_io_pol_hnd("log handle", &(r_u->handle), ps, depth))) 208 return False; 209 210 if(!(prs_ntstatus("status code", ps, depth, &r_u->status))) 211 return False; 212 213 return True; 214} 215 216BOOL eventlog_io_q_read_eventlog(const char *desc, EVENTLOG_Q_READ_EVENTLOG *q_u, 217 prs_struct *ps, int depth) 218{ 219 if(q_u == NULL) 220 return False; 221 222 prs_debug(ps, depth, desc, "eventlog_io_q_read_eventlog"); 223 depth++; 224 225 if(!(prs_align(ps))) 226 return False; 227 228 if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth))) 229 return False; 230 231 if(!(prs_uint32("read flags", ps, depth, &(q_u->flags)))) 232 return False; 233 234 if(!(prs_uint32("read offset", ps, depth, &(q_u->offset)))) 235 return False; 236 237 if(!(prs_uint32("read buf size", ps, depth, &(q_u->max_read_size)))) 238 return False; 239 240 return True; 241} 242/** Structure of response seems to be: 243 DWORD num_bytes_in_resp -- MUST be the same as q_u->max_read_size 244 for i=0..n 245 EVENTLOGRECORD record 246 DWORD sent_size -- sum of EVENTLOGRECORD lengths if records returned, 0 otherwise 247 DWORD real_size -- 0 if records returned, otherwise length of next record to be returned 248 WERROR status */ 249BOOL eventlog_io_r_read_eventlog(const char *desc, 250 EVENTLOG_Q_READ_EVENTLOG *q_u, 251 EVENTLOG_R_READ_EVENTLOG *r_u, 252 prs_struct *ps, 253 int depth) 254{ 255 Eventlog_entry *entry; 256 uint32 record_written = 0; 257 uint32 record_total = 0; 258 259 if(r_u == NULL) 260 return False; 261 262 prs_debug(ps, depth, desc, "eventlog_io_r_read_eventlog"); 263 depth++; 264 265 /* First, see if we've read more logs than we can output */ 266 267 if(r_u->num_bytes_in_resp > q_u->max_read_size) { 268 entry = r_u->entry; 269 270 /* remove the size of the last entry from the list */ 271 272 while(entry->next != NULL) 273 entry = entry->next; 274 275 r_u->num_bytes_in_resp -= entry->record.length; 276 277 /* do not output the last log entry */ 278 279 r_u->num_records--; 280 } 281 282 entry = r_u->entry; 283 record_total = r_u->num_records; 284 285 if(r_u->num_bytes_in_resp != 0) 286 r_u->sent_size = r_u->num_bytes_in_resp; 287 else 288 r_u->real_size = r_u->bytes_in_next_record; 289 290 if(!(prs_align(ps))) 291 return False; 292 if(!(prs_uint32("bytes in resp", ps, depth, &(q_u->max_read_size)))) 293 return False; 294 295 while(entry != NULL && record_written < record_total) 296 { 297 DEBUG(11, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total)); 298 299 /* Encode the actual eventlog record record */ 300 301 if(!(prs_uint32("length", ps, depth, &(entry->record.length)))) 302 return False; 303 if(!(prs_uint32("reserved", ps, depth, &(entry->record.reserved1)))) 304 return False; 305 if(!(prs_uint32("record number", ps, depth, &(entry->record.record_number)))) 306 return False; 307 if(!(prs_uint32("time generated", ps, depth, &(entry->record.time_generated)))) 308 return False; 309 if(!(prs_uint32("time written", ps, depth, &(entry->record.time_written)))) 310 return False; 311 if(!(prs_uint32("event id", ps, depth, &(entry->record.event_id)))) 312 return False; 313 if(!(prs_uint16("event type", ps, depth, &(entry->record.event_type)))) 314 return False; 315 if(!(prs_uint16("num strings", ps, depth, &(entry->record.num_strings)))) 316 return False; 317 if(!(prs_uint16("event category", ps, depth, &(entry->record.event_category)))) 318 return False; 319 if(!(prs_uint16("reserved2", ps, depth, &(entry->record.reserved2)))) 320 return False; 321 if(!(prs_uint32("closing record", ps, depth, &(entry->record.closing_record_number)))) 322 return False; 323 if(!(prs_uint32("string offset", ps, depth, &(entry->record.string_offset)))) 324 return False; 325 if(!(prs_uint32("user sid length", ps, depth, &(entry->record.user_sid_length)))) 326 return False; 327 if(!(prs_uint32("user sid offset", ps, depth, &(entry->record.user_sid_offset)))) 328 return False; 329 if(!(prs_uint32("data length", ps, depth, &(entry->record.data_length)))) 330 return False; 331 if(!(prs_uint32("data offset", ps, depth, &(entry->record.data_offset)))) 332 return False; 333 if(!(prs_align(ps))) 334 return False; 335 336 /* Now encoding data */ 337 338 if(!(prs_uint8s(False, "buffer", ps, depth, entry->data, 339 entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length)))) 340 { 341 return False; 342 } 343 344 if(!(prs_align(ps))) 345 return False; 346 if(!(prs_uint32("length 2", ps, depth, &(entry->record.length)))) 347 return False; 348 349 entry = entry->next; 350 record_written++; 351 352 } /* end of encoding EVENTLOGRECORD */ 353 354 /* Now pad with whitespace until the end of the response buffer */ 355 356 if (q_u->max_read_size - r_u->num_bytes_in_resp) { 357 if (!r_u->end_of_entries_padding) { 358 return False; 359 } 360 361 if(!(prs_uint8s(False, "end of entries padding", ps, 362 depth, r_u->end_of_entries_padding, 363 (q_u->max_read_size - r_u->num_bytes_in_resp)))) { 364 free(r_u->end_of_entries_padding); 365 return False; 366 } 367 368 free(r_u->end_of_entries_padding); 369 } 370 371 /* We had better be DWORD aligned here */ 372 373 if(!(prs_uint32("sent size", ps, depth, &(r_u->sent_size)))) 374 return False; 375 if(!(prs_uint32("real size", ps, depth, &(r_u->real_size)))) 376 return False; 377 if(!(prs_ntstatus("status code", ps, depth, &r_u->status))) 378 return False; 379 380 return True; 381} 382 383/** The windows client seems to be doing something funny with the file name 384 A call like 385 ClearEventLog(handle, "backup_file") 386 on the client side will result in the backup file name looking like this on the 387 server side: 388 \??\${CWD of client}\backup_file 389 If an absolute path gets specified, such as 390 ClearEventLog(handle, "C:\\temp\\backup_file") 391 then it is still mangled by the client into this: 392 \??\C:\temp\backup_file 393 when it is on the wire. 394 I'm not sure where the \?? is coming from, or why the ${CWD} of the client process 395 would be added in given that the backup file gets written on the server side. */ 396 397BOOL eventlog_io_q_clear_eventlog(const char *desc, EVENTLOG_Q_CLEAR_EVENTLOG *q_u, 398 prs_struct *ps, int depth) 399{ 400 if(q_u == NULL) 401 return False; 402 403 prs_debug(ps, depth, desc, "eventlog_io_q_clear_eventlog"); 404 depth++; 405 406 if(!prs_align(ps)) 407 return False; 408 if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth))) 409 return False; 410 411 if ( !prs_unistr4("backupfile", ps, depth, &q_u->backupfile) ) 412 return False; 413 414 return True; 415 416} 417 418BOOL eventlog_io_r_clear_eventlog(const char *desc, EVENTLOG_R_CLEAR_EVENTLOG *r_u, 419 prs_struct *ps, int depth) 420{ 421 if(r_u == NULL) 422 return False; 423 424 prs_debug(ps, depth, desc, "eventlog_io_r_clear_eventlog"); 425 depth++; 426 427 if(!prs_align(ps)) 428 return False; 429 if(!(prs_ntstatus("status code", ps, depth, &r_u->status))) 430 return False; 431 432 return True; 433} 434