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 2 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, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define DBGC_CLASS DBGC_RPC_SRV
26 typedef struct eventlog_info
28 /* for use by the \PIPE\eventlog policy */
29 fstring source_log_file_name
;
30 fstring source_server_name
;
31 fstring handle_string
;
36 static void free_eventlog_info(void *ptr
)
38 struct eventlog_info
*info
= (struct eventlog_info
*)ptr
;
39 memset(info
->source_log_file_name
, '0', sizeof(*(info
->source_log_file_name
)));
40 memset(info
->source_server_name
, '0', sizeof(*(info
->source_server_name
)));
41 memset(info
->handle_string
, '0', sizeof(*(info
->handle_string
)));
42 memset(info
, 0, sizeof(*(info
)));
46 static Eventlog_info
*find_eventlog_info_by_hnd(pipes_struct
*p
,
49 Eventlog_info
*info
= NULL
;
51 if(!(find_policy_by_hnd(p
,handle
,(void **)&info
)))
53 DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
59 void policy_handle_to_string(POLICY_HND
*handle
, fstring
*dest
)
61 memset(dest
, 0, sizeof(*dest
));
62 snprintf((char *)dest
, sizeof(*dest
), "%08X-%08X-%04X-%04X-%02X%02X%02X%02X%02X",
75 * Callout to open the specified event log
77 * smbrun calling convention --
78 * INPUT: <open_cmd> <log name> <policy handle>
79 * OUTPUT: the string "SUCCESS" if the command succeeded
80 * no such string if there was a failure.
82 static BOOL
_eventlog_open_eventlog_hook(Eventlog_info
*info
)
84 char *cmd
= lp_eventlog_open_cmd();
91 if(cmd
== NULL
|| strlen(cmd
) == 0)
93 DEBUG(0, ("Must define an \"eventlog open command\" entry in the config.\n"));
97 memset(command
, 0, sizeof(command
));
98 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\"",
100 info
->source_log_file_name
,
101 info
->handle_string
);
103 DEBUG(10, ("Running [%s]\n", command
));
104 ret
= smbrun(command
, &fd
);
105 DEBUGADD(10, ("returned [%d]\n", ret
));
114 qlines
= fd_lines_load(fd
, &numlines
);
115 DEBUGADD(10, ("Lines returned = [%d]\n", numlines
));
120 DEBUGADD(10, ("Line[0] = [%s]\n", qlines
[0]));
121 if(0 == strncmp(qlines
[0], "SUCCESS", strlen("SUCCESS")))
123 DEBUGADD(10, ("Able to open [%s].\n", info
->source_log_file_name
));
124 file_lines_free(qlines
);
129 file_lines_free(qlines
);
133 WERROR
_eventlog_open_eventlog(pipes_struct
*p
,
134 EVENTLOG_Q_OPEN_EVENTLOG
*q_u
,
135 EVENTLOG_R_OPEN_EVENTLOG
*r_u
)
137 Eventlog_info
*info
= NULL
;
142 if((info
= SMB_MALLOC_P(Eventlog_info
)) == NULL
)
147 if(q_u
->servername_ptr
!= 0)
149 unistr2_to_ascii(info
->source_server_name
, &(q_u
->servername
), sizeof(info
->source_server_name
));
153 /* if servername == NULL, use the local computer */
154 fstrcpy(info
->source_server_name
, global_myname());
156 DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the server name.\n", info
->source_server_name
));
158 if(q_u
->sourcename_ptr
!= 0)
160 unistr2_to_ascii(info
->source_log_file_name
, &(q_u
->sourcename
), sizeof(info
->source_log_file_name
));
164 /* if sourcename == NULL, default to "Application" log */
165 fstrcpy(info
->source_log_file_name
, "Application");
167 DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info
->source_log_file_name
));
169 if(!create_policy_hnd(p
, &(r_u
->handle
), free_eventlog_info
, (void *)info
))
172 policy_handle_to_string(&r_u
->handle
, &info
->handle_string
);
174 if(!(_eventlog_open_eventlog_hook(info
)))
180 * Callout to get the number of records in the specified event log
182 * smbrun calling convention --
183 * INPUT: <get_num_records_cmd> <log name> <policy handle>
184 * OUTPUT: A single line with a single integer containing the number of
185 * entries in the log. If there are no entries in the log, return 0.
187 static BOOL
_eventlog_get_num_records_hook(Eventlog_info
*info
)
189 char *cmd
= lp_eventlog_num_records_cmd();
196 if(cmd
== NULL
|| strlen(cmd
) == 0)
198 DEBUG(0, ("Must define an \"eventlog num records command\" entry in the config.\n"));
202 memset(command
, 0, sizeof(command
));
203 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\"",
205 info
->source_log_file_name
,
206 info
->handle_string
);
208 DEBUG(10, ("Running [%s]\n", command
));
209 ret
= smbrun(command
, &fd
);
210 DEBUGADD(10, ("returned [%d]\n", ret
));
219 qlines
= fd_lines_load(fd
, &numlines
);
220 DEBUGADD(10, ("Lines returned = [%d]\n", numlines
));
225 DEBUGADD(10, ("Line[0] = [%s]\n", qlines
[0]));
226 sscanf(qlines
[0], "%d", &(info
->num_records
));
227 file_lines_free(qlines
);
231 file_lines_free(qlines
);
235 WERROR
_eventlog_get_num_records(pipes_struct
*p
,
236 EVENTLOG_Q_GET_NUM_RECORDS
*q_u
,
237 EVENTLOG_R_GET_NUM_RECORDS
*r_u
)
239 Eventlog_info
*info
= NULL
;
240 POLICY_HND
*handle
= NULL
;
245 handle
= &(q_u
->handle
);
246 info
= find_eventlog_info_by_hnd(p
, handle
);
248 if(!(_eventlog_get_num_records_hook(info
)))
251 r_u
->num_records
= info
->num_records
;
256 * Callout to find the oldest record in the log
258 * smbrun calling convention --
259 * INPUT: <oldest_entry_cmd> <log name> <policy handle>
260 * OUTPUT: If there are entries in the event log, the index of the
261 * oldest entry. Must be 1 or greater.
262 * If there are no entries in the log, returns a 0
264 static BOOL
_eventlog_get_oldest_entry_hook(Eventlog_info
*info
)
266 char *cmd
= lp_eventlog_oldest_record_cmd();
273 if(cmd
== NULL
|| strlen(cmd
) == 0)
275 DEBUG(0, ("Must define an \"eventlog oldest record command\" entry in the config.\n"));
279 memset(command
, 0, sizeof(command
));
280 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\"",
282 info
->source_log_file_name
,
283 info
->handle_string
);
285 DEBUG(10, ("Running [%s]\n", command
));
286 ret
= smbrun(command
, &fd
);
287 DEBUGADD(10, ("returned [%d]\n", ret
));
296 qlines
= fd_lines_load(fd
, &numlines
);
297 DEBUGADD(10, ("Lines returned = [%d]\n", numlines
));
302 DEBUGADD(10, ("Line[0] = [%s]\n", qlines
[0]));
303 sscanf(qlines
[0], "%d", &(info
->oldest_entry
));
304 file_lines_free(qlines
);
308 file_lines_free(qlines
);
312 WERROR
_eventlog_get_oldest_entry(pipes_struct
*p
,
313 EVENTLOG_Q_GET_OLDEST_ENTRY
*q_u
,
314 EVENTLOG_R_GET_OLDEST_ENTRY
*r_u
)
316 Eventlog_info
*info
= NULL
;
317 POLICY_HND
*handle
= NULL
;
322 handle
= &(q_u
->handle
);
323 info
= find_eventlog_info_by_hnd(p
, handle
);
325 if(!(_eventlog_get_oldest_entry_hook(info
)))
328 r_u
->oldest_entry
= info
->oldest_entry
;
334 * Callout to close the specified event log
336 * smbrun calling convention --
337 * INPUT: <close_cmd> <log name> <policy handle>
338 * OUTPUT: the string "SUCCESS" if the command succeeded
339 * no such string if there was a failure.
341 static BOOL
_eventlog_close_eventlog_hook(Eventlog_info
*info
)
343 char *cmd
= lp_eventlog_close_cmd();
350 if(cmd
== NULL
|| strlen(cmd
) == 0)
352 DEBUG(0, ("Must define an \"eventlog close command\" entry in the config.\n"));
356 memset(command
, 0, sizeof(command
));
357 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\"",
359 info
->source_log_file_name
,
360 info
->handle_string
);
362 DEBUG(10, ("Running [%s]\n", command
));
363 ret
= smbrun(command
, &fd
);
364 DEBUGADD(10, ("returned [%d]\n", ret
));
373 qlines
= fd_lines_load(fd
, &numlines
);
374 DEBUGADD(10, ("Lines returned = [%d]\n", numlines
));
379 DEBUGADD(10, ("Line[0] = [%s]\n", qlines
[0]));
380 if(0 == strncmp(qlines
[0], "SUCCESS", strlen("SUCCESS")))
382 DEBUGADD(10, ("Able to close [%s].\n", info
->source_log_file_name
));
383 file_lines_free(qlines
);
388 file_lines_free(qlines
);
392 WERROR
_eventlog_close_eventlog(pipes_struct
*p
,
393 EVENTLOG_Q_CLOSE_EVENTLOG
*q_u
,
394 EVENTLOG_R_CLOSE_EVENTLOG
*r_u
)
396 Eventlog_info
*info
= NULL
;
402 handle
= &(q_u
->handle
);
404 info
= find_eventlog_info_by_hnd(p
, handle
);
405 if(!(_eventlog_close_eventlog_hook(info
)))
408 if(!(close_policy_hnd(p
, handle
)))
410 /* WERR_NOMEM is probably not the correct error, but until I figure out a better
411 one it will have to do */
418 static BOOL
_eventlog_read_parse_line(char *line
, Eventlog_entry
*entry
)
420 char *start
= NULL
, *stop
= NULL
;
426 if(start
== NULL
|| strlen(start
) == 0)
428 if(!(stop
= strchr(line
, ':')))
431 DEBUG(6, ("_eventlog_read_parse_line: trying to parse [%s].\n", line
));
433 if(0 == strncmp(start
, "LEN", stop
- start
))
435 /* This will get recomputed later anyway -- probably not necessary */
436 entry
->record
.length
= atoi(stop
+ 1);
438 else if(0 == strncmp(start
, "RS1", stop
- start
))
440 /* For now all these reserved entries seem to have the same value,
441 which can be hardcoded to int(1699505740) for now */
442 entry
->record
.reserved1
= atoi(stop
+ 1);
444 else if(0 == strncmp(start
, "RCN", stop
- start
))
446 entry
->record
.record_number
= atoi(stop
+ 1);
448 else if(0 == strncmp(start
, "TMG", stop
- start
))
450 entry
->record
.time_generated
= atoi(stop
+ 1);
452 else if(0 == strncmp(start
, "TMW", stop
- start
))
454 entry
->record
.time_written
= atoi(stop
+ 1);
456 else if(0 == strncmp(start
, "EID", stop
- start
))
458 entry
->record
.event_id
= atoi(stop
+ 1);
460 else if(0 == strncmp(start
, "ETP", stop
- start
))
462 if(strstr(start
, "ERROR"))
464 entry
->record
.event_type
= EVENTLOG_ERROR_TYPE
;
466 else if(strstr(start
, "WARNING"))
468 entry
->record
.event_type
= EVENTLOG_WARNING_TYPE
;
470 else if(strstr(start
, "INFO"))
472 entry
->record
.event_type
= EVENTLOG_INFORMATION_TYPE
;
474 else if(strstr(start
, "AUDIT_SUCCESS"))
476 entry
->record
.event_type
= EVENTLOG_AUDIT_SUCCESS
;
478 else if(strstr(start
, "AUDIT_FAILURE"))
480 entry
->record
.event_type
= EVENTLOG_AUDIT_FAILURE
;
482 else if(strstr(start
, "SUCCESS"))
484 entry
->record
.event_type
= EVENTLOG_SUCCESS
;
488 /* some other eventlog type -- currently not defined in MSDN docs, so error out */
493 else if(0 == strncmp(start, "NST", stop - start))
495 entry->record.num_strings = atoi(stop + 1);
498 else if(0 == strncmp(start
, "ECT", stop
- start
))
500 entry
->record
.event_category
= atoi(stop
+ 1);
502 else if(0 == strncmp(start
, "RS2", stop
- start
))
504 entry
->record
.reserved2
= atoi(stop
+ 1);
506 else if(0 == strncmp(start
, "CRN", stop
- start
))
508 entry
->record
.closing_record_number
= atoi(stop
+ 1);
510 else if(0 == strncmp(start
, "USL", stop
- start
))
512 entry
->record
.user_sid_length
= atoi(stop
+ 1);
514 else if(0 == strncmp(start
, "SRC", stop
- start
))
516 memset(temp
, 0, sizeof(temp
));
517 sscanf(stop
+1, "%s", temp
);
518 temp_len
= strlen(temp
);
519 rpcstr_push((void *)(entry
->data_record
.source_name
), temp
,
520 sizeof(entry
->data_record
.source_name
), STR_TERMINATE
);
521 entry
->data_record
.source_name_len
= (strlen_w(entry
->data_record
.source_name
)* 2) + 2;
523 else if(0 == strncmp(start
, "SRN", stop
- start
))
525 memset(temp
, 0, sizeof(temp
));
526 sscanf(stop
+1, "%s", temp
);
527 temp_len
= strlen(temp
);
528 rpcstr_push((void *)(entry
->data_record
.computer_name
), temp
,
529 sizeof(entry
->data_record
.computer_name
), STR_TERMINATE
);
530 entry
->data_record
.computer_name_len
= (strlen_w(entry
->data_record
.computer_name
)* 2) + 2;
532 else if(0 == strncmp(start
, "SID", stop
- start
))
534 memset(temp
, 0, sizeof(temp
));
535 sscanf(stop
+1, "%s", temp
);
536 temp_len
= strlen(temp
);
537 rpcstr_push((void *)(entry
->data_record
.sid
), temp
,
538 sizeof(entry
->data_record
.sid
), STR_TERMINATE
);
539 entry
->record
.user_sid_length
= (strlen_w(entry
->data_record
.sid
) * 2) + 2;
541 else if(0 == strncmp(start
, "STR", stop
- start
))
543 /* skip past initial ":" */
545 /* now skip any other leading whitespace */
546 while(isspace(stop
[0]))
548 temp_len
= strlen(stop
);
549 memset(temp
, 0, sizeof(temp
));
550 strncpy(temp
, stop
, temp_len
);
551 rpcstr_push((void *)(entry
->data_record
.strings
+ entry
->data_record
.strings_len
),
553 sizeof(entry
->data_record
.strings
) - entry
->data_record
.strings_len
,
555 entry
->data_record
.strings_len
+= temp_len
+ 1;
556 fprintf(stderr
, "Dumping strings:\n");
557 for(i
= 0; i
< entry
->data_record
.strings_len
; i
++)
559 fputc((char)entry
->data_record
.strings
[i
], stderr
);
561 fprintf(stderr
, "\nDone\n");
562 entry
->record
.num_strings
++;
564 else if(0 == strncmp(start
, "DAT", stop
- start
))
566 /* Now that we're done processing the STR data, adjust the length to account for
567 unicode, then proceed with the DAT data. */
568 entry
->data_record
.strings_len
*= 2;
569 /* skip past initial ":" */
571 /* now skip any other leading whitespace */
572 while(isspace(stop
[0]))
574 memset(temp
, 0, sizeof(temp
));
575 temp_len
= strlen(stop
);
576 strncpy(temp
, stop
, temp_len
);
577 rpcstr_push((void *)(entry
->data_record
.user_data
), temp
,
578 sizeof(entry
->data_record
.user_data
), STR_TERMINATE
);
579 entry
->data_record
.user_data_len
= (strlen_w((const smb_ucs2_t
*)entry
->data_record
.user_data
) * 2) + 2;
583 /* some other eventlog entry -- not implemented, so dropping on the floor */
584 DEBUG(10, ("Unknown entry [%s]. Ignoring.\n", line
));
585 /* For now return true so that we can keep on parsing this mess. Eventually
586 we will return False here. */
592 * Callout to read entries from the specified event log
594 * smbrun calling convention --
595 * INPUT: <read_cmd> <log name> <direction> <starting record> <buffer size> <policy handle>
596 * where direction is either "forward" or "backward", the starting record is somewhere
597 * between the oldest_record and oldest_record+num_records, and the buffer size is the
598 * maximum size of the buffer that the client can accomodate.
599 * OUTPUT: A buffer containing a set of entries, one to a line, of the format:
600 * line type:line data
601 * These are the allowed line types:
602 * RS1:(uint32) - reserved. All M$ entries seem to have int(1699505740) for now
603 * RCN:(uint32) - record number of the record, however it may be calculated by the script
604 * TMG:(uint32) - time generated, seconds since January 1, 1970, 0000 UTC
605 * TMW:(uint32) - time written, seconds since January 1, 1970, 0000 UTC
606 * EID:(uint32) - eventlog source defined event identifier. If there's a stringfile for the event, it is an index into that
607 * ETP:(uint16) - eventlog type - one of ERROR, WARNING, INFO, AUDIT_SUCCESS, AUDIT_FAILURE
608 * ECT:(uint16) - event category - depends on the eventlog generator...
609 * RS2:(uint16) - reserved, make it 0000
610 * CRN:(uint32) - reserved, make it 00000000 for now
611 * USL:(uint32) - user SID length. No sid? Make this 0. Must match SID below
612 * SRC:[(uint8)] - Name of the source, for example ccPwdSvc, in hex bytes. Can not be multiline.
613 * SRN:[(uint8)] - Name of the computer on which this is generated, the short hostname usually.
614 * SID:[(uint8)] - User sid if one exists. Must be present even if there is no SID.
615 * STR:[(uint8)] - String data. One string per line. Multiple strings can be specified using consecutive "STR" lines,
616 * up to a total aggregate string length of 1024 characters.
617 * DAT:[(uint8)] - The user-defined data portion of the event log. Can not be multiple lines.
619 static BOOL
_eventlog_read_eventlog_hook(Eventlog_info
*info
, Eventlog_entry
*entry
, const char *direction
, int starting_record
, int buffer_size
, BOOL
*eof
)
621 char *cmd
= lp_eventlog_read_cmd();
632 if(cmd
== NULL
|| strlen(cmd
) == 0)
634 DEBUG(0, ("Must define an \"eventlog read command\" entry in the config.\n"));
638 slprintf(command
, sizeof(command
)-1, "%s \"%s\" %s %d %d \"%s\"",
640 info
->source_log_file_name
,
644 info
->handle_string
);
646 DEBUG(10, ("Running [%s]\n", command
));
647 ret
= smbrun(command
, &fd
);
648 DEBUGADD(10, ("returned [%d]\n", ret
));
657 qlines
= fd_lines_load(fd
, &numlines
);
658 DEBUGADD(10, ("Lines returned = [%d]\n", numlines
));
663 for(i
= 0; i
< numlines
; i
++)
665 DEBUGADD(10, ("Line[%d] = %s\n", i
, qlines
[i
]));
666 _eventlog_read_parse_line(qlines
[i
], entry
);
668 file_lines_free(qlines
);
674 file_lines_free(qlines
);
678 static BOOL
_eventlog_read_prepare_data_buffer(prs_struct
*ps
,
679 EVENTLOG_Q_READ_EVENTLOG
*q_u
,
680 EVENTLOG_R_READ_EVENTLOG
*r_u
,
681 Eventlog_entry
*entry
)
684 Eventlog_entry
*new = NULL
, *insert_point
= NULL
;
686 new = PRS_ALLOC_MEM(ps
, Eventlog_entry
, 1);
690 entry
->data_record
.sid_padding
= ((4 - ((entry
->data_record
.source_name_len
691 + entry
->data_record
.computer_name_len
) % 4)) %4);
692 entry
->data_record
.data_padding
= (4 - ((entry
->data_record
.strings_len
693 + entry
->data_record
.user_data_len
) % 4)) % 4;
694 entry
->record
.length
= sizeof(Eventlog_record
);
695 entry
->record
.length
+= entry
->data_record
.source_name_len
;
696 entry
->record
.length
+= entry
->data_record
.computer_name_len
;
697 if(entry
->record
.user_sid_length
== 0)
699 /* Should not pad to a DWORD boundary for writing out the sid if there is
700 no SID, so just propagate the padding to pad the data */
701 entry
->data_record
.data_padding
+= entry
->data_record
.sid_padding
;
702 entry
->data_record
.sid_padding
= 0;
704 DEBUG(10, ("sid_padding is [%d].\n", entry
->data_record
.sid_padding
));
705 DEBUG(10, ("data_padding is [%d].\n", entry
->data_record
.data_padding
));
707 entry
->record
.length
+= entry
->data_record
.sid_padding
;
708 entry
->record
.length
+= entry
->record
.user_sid_length
;
709 entry
->record
.length
+= entry
->data_record
.strings_len
;
710 entry
->record
.length
+= entry
->data_record
.user_data_len
;
711 entry
->record
.length
+= entry
->data_record
.data_padding
;
712 /* need another copy of length at the end of the data */
713 entry
->record
.length
+= sizeof(entry
->record
.length
);
714 DEBUG(10, ("entry->record.length is [%d].\n", entry
->record
.length
));
715 entry
->data
= PRS_ALLOC_MEM(ps
, uint8
, entry
->record
.length
- sizeof(Eventlog_record
) - sizeof(entry
->record
.length
));
716 if(entry
->data
== NULL
)
718 offset
= entry
->data
;
719 memcpy(offset
, &(entry
->data_record
.source_name
), entry
->data_record
.source_name_len
);
720 offset
+= entry
->data_record
.source_name_len
;
721 memcpy(offset
, &(entry
->data_record
.computer_name
), entry
->data_record
.computer_name_len
);
722 offset
+= entry
->data_record
.computer_name_len
;
723 /* SID needs to be DWORD-aligned */
724 offset
+= entry
->data_record
.sid_padding
;
725 entry
->record
.user_sid_offset
= sizeof(Eventlog_record
) + (offset
- entry
->data
);
726 memcpy(offset
, &(entry
->data_record
.sid
), entry
->record
.user_sid_length
);
727 offset
+= entry
->record
.user_sid_length
;
728 /* Now do the strings */
729 entry
->record
.string_offset
= sizeof(Eventlog_record
) + (offset
- entry
->data
);
730 memcpy(offset
, &(entry
->data_record
.strings
), entry
->data_record
.strings_len
);
731 offset
+= entry
->data_record
.strings_len
;
732 /* Now do the data */
733 entry
->record
.data_length
= entry
->data_record
.user_data_len
;
734 entry
->record
.data_offset
= sizeof(Eventlog_record
) + (offset
- entry
->data
);
735 memcpy(offset
, &(entry
->data_record
.user_data
), entry
->data_record
.user_data_len
);
736 offset
+= entry
->data_record
.user_data_len
;
737 /* Now that we've massaged the current entry, copy it into the new entry and add it
738 to end of the list */
739 insert_point
=r_u
->entry
;
741 if (NULL
== insert_point
)
748 while ((NULL
!= insert_point
->next
))
750 insert_point
=insert_point
->next
;
753 insert_point
->next
= new;
756 memcpy(&(new->record
), &entry
->record
, sizeof(Eventlog_record
));
757 memcpy(&(new->data_record
), &entry
->data_record
, sizeof(Eventlog_data_record
));
758 new->data
= entry
->data
;
761 r_u
->num_bytes_in_resp
+= entry
->record
.length
;
766 WERROR
_eventlog_read_eventlog(pipes_struct
*p
,
767 EVENTLOG_Q_READ_EVENTLOG
*q_u
,
768 EVENTLOG_R_READ_EVENTLOG
*r_u
)
770 Eventlog_info
*info
= NULL
;
772 Eventlog_entry entry
;
774 const char *direction
= "";
781 handle
= &(q_u
->handle
);
782 info
= find_eventlog_info_by_hnd(p
, handle
);
783 ps
= &p
->out_data
.rdata
;
784 /* Rather than checking the EVENTLOG_SEQUENTIAL_READ/EVENTLOG_SEEK_READ flags,
785 we'll just go to the offset specified in the request, or the oldest entry
786 if no offset is specified */
788 starting_record
= q_u
->offset
;
790 starting_record
= info
->oldest_entry
;
791 if(q_u
->flags
& EVENTLOG_FORWARDS_READ
)
792 direction
= "forward";
793 else if(q_u
->flags
& EVENTLOG_BACKWARDS_READ
)
794 direction
= "backward";
799 if(!(_eventlog_read_eventlog_hook(info
, &entry
, direction
, starting_record
, q_u
->max_read_size
, &eof
)))
806 /* only if the read hook returned data */
807 if(!(_eventlog_read_prepare_data_buffer(ps
, q_u
, r_u
, &entry
)))
809 DEBUG(10, ("_eventlog_read_eventlog: read [%d] bytes out of a max of [%d].\n",
810 r_u
->num_bytes_in_resp
,
811 q_u
->max_read_size
));
813 } while((r_u
->num_bytes_in_resp
<= q_u
->max_read_size
) && (eof
!= True
));
818 * Callout to clear (and optionally backup) a specified event log
820 * smbrun calling convention --
821 * INPUT: <clear_eventlog_cmd> <log name> <policy handle>
822 * OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
823 * Otherwise it is assumed to have failed
825 * INPUT: <clear_eventlog_cmd> <log name> <backup file> <policy handle>
826 * OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
827 * Otherwise it is assumed to have failed
828 * The given log is copied to that location on the server. See comments for
829 * eventlog_io_q_clear_eventlog for info about odd file name behavior
831 static BOOL
_eventlog_clear_eventlog_hook(Eventlog_info
*info
,
832 pstring backup_file_name
)
834 char *cmd
= lp_eventlog_clear_cmd();
841 if(cmd
== NULL
|| strlen(cmd
) == 0)
843 DEBUG(0, ("Must define an \"eventlog clear command\" entry in the config.\n"));
847 memset(command
, 0, sizeof(command
));
848 if(strlen(backup_file_name
) > 0)
849 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\"",
851 info
->source_log_file_name
,
853 info
->handle_string
);
855 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\"",
857 info
->source_log_file_name
,
858 info
->handle_string
);
860 DEBUG(10, ("Running [%s]\n", command
));
861 ret
= smbrun(command
, &fd
);
862 DEBUGADD(10, ("returned [%d]\n", ret
));
871 qlines
= fd_lines_load(fd
, &numlines
);
872 DEBUGADD(10, ("Lines returned = [%d]\n", numlines
));
877 DEBUGADD(10, ("Line[0] = [%s]\n", qlines
[0]));
878 if(0 == strncmp(qlines
[0], "SUCCESS", strlen("SUCCESS")))
880 DEBUGADD(10, ("Able to clear [%s].\n", info
->source_log_file_name
));
881 file_lines_free(qlines
);
886 file_lines_free(qlines
);
890 WERROR
_eventlog_clear_eventlog(pipes_struct
*p
,
891 EVENTLOG_Q_CLEAR_EVENTLOG
*q_u
,
892 EVENTLOG_R_CLEAR_EVENTLOG
*r_u
)
894 Eventlog_info
*info
= NULL
;
895 pstring backup_file_name
;
896 POLICY_HND
*handle
= NULL
;
901 handle
= &(q_u
->handle
);
902 info
= find_eventlog_info_by_hnd(p
, handle
);
903 memset(backup_file_name
, 0, sizeof(backup_file_name
));
905 if(q_u
->backup_file_ptr
!= 0)
907 unistr2_to_ascii(backup_file_name
, &(q_u
->backup_file
), sizeof(backup_file_name
));
908 DEBUG(10, ("_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
910 info
->source_log_file_name
));
914 /* if backup_file == NULL, do not back up the log before clearing it */
915 DEBUG(10, ("_eventlog_clear_eventlog: clearing [%s] log without making a backup.",
916 info
->source_log_file_name
));
919 if(!(_eventlog_clear_eventlog_hook(info
, backup_file_name
)))