2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Marcin Krzysztof Porwit 2005,
5 * Copyright (C) Gerald (Jerry) Carter 2005.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define DBGC_CLASS DBGC_RPC_SRV
36 /********************************************************************
37 Inform the external eventlog machinery of default values (on startup
39 ********************************************************************/
41 void eventlog_refresh_external_parameters( NT_USER_TOKEN *token )
43 const char **elogs = lp_eventlog_list();
49 if ( !*lp_eventlog_control_cmd() )
52 for ( i=0; elogs[i]; i++ ) {
54 DEBUG(10,("eventlog_refresh_external_parameters: Refreshing =>[%s]\n",
57 if ( !control_eventlog_hook( token, elogs[i] ) ) {
58 DEBUG(0,("eventlog_refresh_external_parameters: failed to refresh [%s]\n",
66 /********************************************************************
67 ********************************************************************/
69 static void free_eventlog_info(void *ptr)
74 /********************************************************************
75 ********************************************************************/
77 static EventlogInfo *find_eventlog_info_by_hnd(pipes_struct *p, POLICY_HND *handle)
81 if ( !find_policy_by_hnd(p,handle,(void **)&info) ) {
82 DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
89 /********************************************************************
90 Callout to control the specified event log - passing out only
91 the MaxSize and Retention values, along with eventlog name
93 INPUT: <control_cmd> <log name> <retention> <maxsize>
95 ********************************************************************/
97 BOOL control_eventlog_hook(NT_USER_TOKEN *token, const char *elogname )
99 char *cmd = lp_eventlog_control_cmd();
103 uint32 uiMaxSize, uiRetention;
105 REGISTRY_KEY *keyinfo;
110 if ( !cmd || !*cmd ) {
111 DEBUG(0, ("control_eventlog_hook: No \"eventlog control command\" defined in smb.conf!\n"));
115 /* set resonable defaults. 512Kb on size and 1 week on time */
118 uiRetention = 604800;
120 /* the general idea is to internally open the registry
121 key and retreive the values. That way we can continue
122 to use the same fetch/store api that we use in
125 pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname );
126 wresult = regkey_open_internal( &keyinfo, path, token, REG_KEY_READ );
128 if ( !W_ERROR_IS_OK( wresult ) ) {
129 DEBUG(4,("control_eventlog_hook: Failed to open key [%s] (%s)\n",
130 path, dos_errstr(wresult) ));
134 if ( !(values = TALLOC_ZERO_P( keyinfo, REGVAL_CTR )) ) {
135 TALLOC_FREE( keyinfo );
136 DEBUG(0,("control_eventlog_hook: talloc() failed!\n"));
140 fetch_reg_values( keyinfo, values );
142 if ( (val = regval_ctr_getvalue( values, "Retention" )) != NULL )
143 uiRetention = IVAL( regval_data_p(val), 0 );
145 if ( (val = regval_ctr_getvalue( values, "MaxSize" )) != NULL )
146 uiMaxSize = IVAL( regval_data_p(val), 0 );
148 TALLOC_FREE( keyinfo );
150 /* now run the command */
152 pstr_sprintf(command, "%s \"%s\" %u %u", cmd, elogname, uiRetention, uiMaxSize );
154 DEBUG(10, ("control_eventlog_hook: Running [%s]\n", command));
155 ret = smbrun(command, &fd);
156 DEBUGADD(10, ("returned [%d]\n", ret));
159 DEBUG(10,("control_eventlog_hook: Command returned [%d]\n", ret));
170 /********************************************************************
171 ********************************************************************/
174 * Callout to open the specified event log
176 * smbrun calling convention --
177 * INPUT: <open_cmd> <log name> <policy handle>
178 * OUTPUT: the string "SUCCESS" if the command succeeded
179 * no such string if there was a failure.
181 static BOOL open_eventlog_hook( EventlogInfo *info )
183 char *cmd = lp_eventlog_open_cmd();
190 if ( !cmd || !*cmd ) {
191 DEBUG(0, ("Must define an \"eventlog open command\" entry in the config.\n"));
195 pstr_sprintf(command, "%s \"%s\"", cmd, info->logname );
197 DEBUG(10, ("Running [%s]\n", command));
198 ret = smbrun(command, &fd);
199 DEBUGADD(10, ("returned [%d]\n", ret));
208 qlines = fd_lines_load(fd, &numlines);
209 DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
213 DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
214 if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS"))) {
215 DEBUGADD(10, ("Able to open [%s].\n", info->logname));
216 file_lines_free(qlines);
221 file_lines_free(qlines);
226 /********************************************************************
227 ********************************************************************/
229 * Callout to get the number of records in the specified event log
231 * smbrun calling convention --
232 * INPUT: <get_num_records_cmd> <log name> <policy handle>
233 * OUTPUT: A single line with a single integer containing the number of
234 * entries in the log. If there are no entries in the log, return 0.
237 static BOOL get_num_records_hook(EventlogInfo *info)
239 char *cmd = lp_eventlog_num_records_cmd();
246 if ( !cmd || !*cmd ) {
247 DEBUG(0, ("Must define an \"eventlog num records command\" entry in the config.\n"));
251 pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
253 DEBUG(10, ("Running [%s]\n", command));
254 ret = smbrun(command, &fd);
255 DEBUGADD(10, ("returned [%d]\n", ret));
264 qlines = fd_lines_load(fd, &numlines);
265 DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
269 DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
270 sscanf(qlines[0], "%d", &(info->num_records));
271 file_lines_free(qlines);
275 file_lines_free(qlines);
279 /********************************************************************
280 ********************************************************************/
283 * Callout to find the oldest record in the log
285 * smbrun calling convention --
286 * INPUT: <oldest_entry_cmd> <log name> <policy handle>
287 * OUTPUT: If there are entries in the event log, the index of the
288 * oldest entry. Must be 1 or greater.
289 * If there are no entries in the log, returns a 0
292 static BOOL get_oldest_entry_hook(EventlogInfo *info)
294 char *cmd = lp_eventlog_oldest_record_cmd();
301 if ( !cmd || !*cmd ) {
302 DEBUG(0, ("Must define an \"eventlog oldest record command\" entry in the config.\n"));
306 pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
308 DEBUG(10, ("Running [%s]\n", command));
309 ret = smbrun(command, &fd);
310 DEBUGADD(10, ("returned [%d]\n", ret));
319 qlines = fd_lines_load(fd, &numlines);
320 DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
324 DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
325 sscanf(qlines[0], "%d", &(info->oldest_entry));
326 file_lines_free(qlines);
330 file_lines_free(qlines);
334 /********************************************************************
335 ********************************************************************/
337 * Callout to close the specified event log
339 * smbrun calling convention --
340 * INPUT: <close_cmd> <log name> <policy handle>
341 * OUTPUT: the string "SUCCESS" if the command succeeded
342 * no such string if there was a failure.
345 static BOOL close_eventlog_hook(EventlogInfo *info)
347 char *cmd = lp_eventlog_close_cmd();
354 if ( !cmd || !*cmd ) {
355 DEBUG(0, ("Must define an \"eventlog close command\" entry in the config.\n"));
359 pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
361 DEBUG(10, ("Running [%s]\n", command));
362 ret = smbrun(command, &fd);
363 DEBUGADD(10, ("returned [%d]\n", ret));
372 qlines = fd_lines_load(fd, &numlines);
373 DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
377 DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
378 if(0 == strncmp(qlines[0], "SUCCESS", 7)) {
379 DEBUGADD(10, ("Able to close [%s].\n", info->logname));
380 file_lines_free(qlines);
385 file_lines_free(qlines);
389 /********************************************************************
390 ********************************************************************/
392 static BOOL parse_logentry(char *line, Eventlog_entry *entry, BOOL *eor)
394 char *start = NULL, *stop = NULL;
400 /* empty line signyfiying record delimeter, or we're at the end of the buffer */
401 if(start == NULL || strlen(start) == 0) {
402 DEBUG(6, ("parse_logentry: found end-of-record indicator.\n"));
406 if(!(stop = strchr(line, ':'))) {
410 DEBUG(6, ("parse_logentry: trying to parse [%s].\n", line));
412 if(0 == strncmp(start, "LEN", stop - start)) {
413 /* This will get recomputed later anyway -- probably not necessary */
414 entry->record.length = atoi(stop + 1);
415 } else if(0 == strncmp(start, "RS1", stop - start)) {
416 /* For now all these reserved entries seem to have the same value,
417 which can be hardcoded to int(1699505740) for now */
418 entry->record.reserved1 = atoi(stop + 1);
419 } else if(0 == strncmp(start, "RCN", stop - start)) {
420 entry->record.record_number = atoi(stop + 1);
421 } else if(0 == strncmp(start, "TMG", stop - start)) {
422 entry->record.time_generated = atoi(stop + 1);
423 } else if(0 == strncmp(start, "TMW", stop - start)) {
424 entry->record.time_written = atoi(stop + 1);
425 } else if(0 == strncmp(start, "EID", stop - start)) {
426 entry->record.event_id = atoi(stop + 1);
427 } else if(0 == strncmp(start, "ETP", stop - start)) {
428 if(strstr(start, "ERROR")) {
429 entry->record.event_type = EVENTLOG_ERROR_TYPE;
430 } else if(strstr(start, "WARNING")) {
431 entry->record.event_type = EVENTLOG_WARNING_TYPE;
432 } else if(strstr(start, "INFO")) {
433 entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
434 } else if(strstr(start, "AUDIT_SUCCESS")) {
435 entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
436 } else if(strstr(start, "AUDIT_FAILURE")) {
437 entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
438 } else if(strstr(start, "SUCCESS")) {
439 entry->record.event_type = EVENTLOG_SUCCESS;
441 /* some other eventlog type -- currently not defined in MSDN docs, so error out */
446 else if(0 == strncmp(start, "NST", stop - start))
448 entry->record.num_strings = atoi(stop + 1);
451 else if(0 == strncmp(start, "ECT", stop - start)) {
452 entry->record.event_category = atoi(stop + 1);
453 } else if(0 == strncmp(start, "RS2", stop - start)) {
454 entry->record.reserved2 = atoi(stop + 1);
455 } else if(0 == strncmp(start, "CRN", stop - start)) {
456 entry->record.closing_record_number = atoi(stop + 1);
457 } else if(0 == strncmp(start, "USL", stop - start)) {
458 entry->record.user_sid_length = atoi(stop + 1);
459 } else if(0 == strncmp(start, "SRC", stop - start)) {
460 memset(temp, 0, sizeof(temp));
462 while(isspace(stop[0])) {
465 temp_len = strlen(stop);
466 strncpy(temp, stop, temp_len);
467 rpcstr_push((void *)(entry->data_record.source_name), temp,
468 sizeof(entry->data_record.source_name), STR_TERMINATE);
469 entry->data_record.source_name_len = (strlen_w(entry->data_record.source_name)* 2) + 2;
470 } else if(0 == strncmp(start, "SRN", stop - start)) {
471 memset(temp, 0, sizeof(temp));
473 while(isspace(stop[0])) {
476 temp_len = strlen(stop);
477 strncpy(temp, stop, temp_len);
478 rpcstr_push((void *)(entry->data_record.computer_name), temp,
479 sizeof(entry->data_record.computer_name), STR_TERMINATE);
480 entry->data_record.computer_name_len = (strlen_w(entry->data_record.computer_name)* 2) + 2;
481 } else if(0 == strncmp(start, "SID", stop - start)) {
482 memset(temp, 0, sizeof(temp));
484 while(isspace(stop[0])) {
487 temp_len = strlen(stop);
488 strncpy(temp, stop, temp_len);
489 rpcstr_push((void *)(entry->data_record.sid), temp,
490 sizeof(entry->data_record.sid), STR_TERMINATE);
491 entry->record.user_sid_length = (strlen_w(entry->data_record.sid) * 2) + 2;
492 } else if(0 == strncmp(start, "STR", stop - start)) {
493 /* skip past initial ":" */
495 /* now skip any other leading whitespace */
496 while(isspace(stop[0])) {
499 temp_len = strlen(stop);
500 memset(temp, 0, sizeof(temp));
501 strncpy(temp, stop, temp_len);
502 rpcstr_push((void *)(entry->data_record.strings + entry->data_record.strings_len),
504 sizeof(entry->data_record.strings) - entry->data_record.strings_len,
506 entry->data_record.strings_len += temp_len + 1;
507 fprintf(stderr, "Dumping strings:\n");
508 for(i = 0; i < entry->data_record.strings_len; i++) {
509 fputc((char)entry->data_record.strings[i], stderr);
511 fprintf(stderr, "\nDone\n");
512 entry->record.num_strings++;
513 } else if(0 == strncmp(start, "DAT", stop - start)) {
514 /* Now that we're done processing the STR data, adjust the length to account for
515 unicode, then proceed with the DAT data. */
516 entry->data_record.strings_len *= 2;
517 /* skip past initial ":" */
519 /* now skip any other leading whitespace */
520 while(isspace(stop[0])) {
523 entry->data_record.user_data_len = strlen(stop);
524 memset(entry->data_record.user_data, 0, sizeof(entry->data_record.user_data));
525 if(entry->data_record.user_data_len > 0) {
526 /* copy no more than the first 1024 bytes */
527 if(entry->data_record.user_data_len > sizeof(entry->data_record.user_data))
528 entry->data_record.user_data_len = sizeof(entry->data_record.user_data);
529 memcpy(entry->data_record.user_data, stop, entry->data_record.user_data_len);
532 /* some other eventlog entry -- not implemented, so dropping on the floor */
533 DEBUG(10, ("Unknown entry [%s]. Ignoring.\n", line));
534 /* For now return true so that we can keep on parsing this mess. Eventually
535 we will return False here. */
541 /********************************************************************
542 ********************************************************************/
545 * Callout to read entries from the specified event log
547 * smbrun calling convention --
548 * INPUT: <read_cmd> <log name> <direction> <starting record> <buffer size> <policy handle>
549 * where direction is either "forward" or "backward", the starting record is somewhere
550 * between the oldest_record and oldest_record+num_records, and the buffer size is the
551 * maximum size of the buffer that the client can accomodate.
552 * OUTPUT: A buffer containing a set of entries, one to a line, of the format:
553 * Multiple log entries can be contained in the buffer, delimited by an empty line
554 * line type:line data
555 * These are the allowed line types:
556 * RS1:(uint32) - reserved. All M$ entries seem to have int(1699505740) for now
557 * RCN:(uint32) - record number of the record, however it may be calculated by the script
558 * TMG:(uint32) - time generated, seconds since January 1, 1970, 0000 UTC
559 * TMW:(uint32) - time written, seconds since January 1, 1970, 0000 UTC
560 * EID:(uint32) - eventlog source defined event identifier. If there's a stringfile for the event, it is an index into that
561 * ETP:(uint16) - eventlog type - one of ERROR, WARNING, INFO, AUDIT_SUCCESS, AUDIT_FAILURE
562 * ECT:(uint16) - event category - depends on the eventlog generator...
563 * RS2:(uint16) - reserved, make it 0000
564 * CRN:(uint32) - reserved, make it 00000000 for now
565 * USL:(uint32) - user SID length. No sid? Make this 0. Must match SID below
566 * SRC:[(uint8)] - Name of the source, for example ccPwdSvc, in hex bytes. Can not be multiline.
567 * SRN:[(uint8)] - Name of the computer on which this is generated, the short hostname usually.
568 * SID:[(uint8)] - User sid if one exists. Must be present even if there is no SID.
569 * STR:[(uint8)] - String data. One string per line. Multiple strings can be specified using consecutive "STR" lines,
570 * up to a total aggregate string length of 1024 characters.
571 * DAT:[(uint8)] - The user-defined data portion of the event log. Can not be multiple lines.
572 * <empty line> - end-of-record indicator
575 static BOOL read_eventlog_hook(EventlogInfo *info, Eventlog_entry *entry,
576 const char *direction, int starting_record,
577 int buffer_size, BOOL *eof,
578 char ***buffer, int *numlines)
580 char *cmd = lp_eventlog_read_cmd();
588 if ( !cmd || !*cmd ) {
589 DEBUG(0, ("Must define an \"eventlog read command\" entry in the config.\n"));
593 pstr_sprintf( command, "%s \"%s\" %s %d %d",
594 cmd, info->logname, direction, starting_record, buffer_size );
598 DEBUG(10, ("Running [%s]\n", command));
599 ret = smbrun(command, &fd);
600 DEBUGADD(10, ("returned [%d]\n", ret));
609 *buffer = fd_lines_load(fd, numlines);
610 DEBUGADD(10, ("Lines returned = [%d]\n", *numlines));
615 for(i = 0; i < numlines; i++)
617 DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
618 parse_logentry(qlines[i], entry);
620 file_lines_free(qlines);
627 /* file_lines_free(qlines);*/
631 /********************************************************************
632 ********************************************************************/
634 static Eventlog_entry *read_package_entry(prs_struct *ps,
635 EVENTLOG_Q_READ_EVENTLOG *q_u,
636 EVENTLOG_R_READ_EVENTLOG *r_u,
637 Eventlog_entry *entry)
640 Eventlog_entry *ee_new = NULL;
642 ee_new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1);
647 entry->data_record.sid_padding = ((4 - ((entry->data_record.source_name_len
648 + entry->data_record.computer_name_len) % 4)) %4);
649 entry->data_record.data_padding = (4 - ((entry->data_record.strings_len
650 + entry->data_record.user_data_len) % 4)) % 4;
651 entry->record.length = sizeof(Eventlog_record);
652 entry->record.length += entry->data_record.source_name_len;
653 entry->record.length += entry->data_record.computer_name_len;
654 if(entry->record.user_sid_length == 0) {
655 /* Should not pad to a DWORD boundary for writing out the sid if there is
656 no SID, so just propagate the padding to pad the data */
657 entry->data_record.data_padding += entry->data_record.sid_padding;
658 entry->data_record.sid_padding = 0;
660 DEBUG(10, ("sid_padding is [%d].\n", entry->data_record.sid_padding));
661 DEBUG(10, ("data_padding is [%d].\n", entry->data_record.data_padding));
663 entry->record.length += entry->data_record.sid_padding;
664 entry->record.length += entry->record.user_sid_length;
665 entry->record.length += entry->data_record.strings_len;
666 entry->record.length += entry->data_record.user_data_len;
667 entry->record.length += entry->data_record.data_padding;
668 /* need another copy of length at the end of the data */
669 entry->record.length += sizeof(entry->record.length);
670 DEBUG(10, ("entry->record.length is [%d].\n", entry->record.length));
671 entry->data = PRS_ALLOC_MEM(ps, uint8, entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length));
672 if(entry->data == NULL) {
675 offset = entry->data;
676 memcpy(offset, &(entry->data_record.source_name), entry->data_record.source_name_len);
677 offset += entry->data_record.source_name_len;
678 memcpy(offset, &(entry->data_record.computer_name), entry->data_record.computer_name_len);
679 offset += entry->data_record.computer_name_len;
680 /* SID needs to be DWORD-aligned */
681 offset += entry->data_record.sid_padding;
682 entry->record.user_sid_offset = sizeof(Eventlog_record) + (offset - entry->data);
683 memcpy(offset, &(entry->data_record.sid), entry->record.user_sid_length);
684 offset += entry->record.user_sid_length;
685 /* Now do the strings */
686 entry->record.string_offset = sizeof(Eventlog_record) + (offset - entry->data);
687 memcpy(offset, &(entry->data_record.strings), entry->data_record.strings_len);
688 offset += entry->data_record.strings_len;
689 /* Now do the data */
690 entry->record.data_length = entry->data_record.user_data_len;
691 entry->record.data_offset = sizeof(Eventlog_record) + (offset - entry->data);
692 memcpy(offset, &(entry->data_record.user_data), entry->data_record.user_data_len);
693 offset += entry->data_record.user_data_len;
695 memcpy(&(ee_new->record), &entry->record, sizeof(Eventlog_record));
696 memcpy(&(ee_new->data_record), &entry->data_record, sizeof(Eventlog_data_record));
697 ee_new->data = entry->data;
702 /********************************************************************
703 ********************************************************************/
705 static BOOL add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *ee_new)
707 Eventlog_entry *insert_point;
709 insert_point=r_u->entry;
711 if (NULL == insert_point) {
715 while ((NULL != insert_point->next)) {
716 insert_point=insert_point->next;
719 insert_point->next = ee_new;
722 r_u->num_bytes_in_resp += ee_new->record.length;
727 /********************************************************************
728 ********************************************************************/
731 * Callout to clear (and optionally backup) a specified event log
733 * smbrun calling convention --
734 * INPUT: <clear_eventlog_cmd> <log name> <policy handle>
735 * OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
736 * Otherwise it is assumed to have failed
738 * INPUT: <clear_eventlog_cmd> <log name> <backup file> <policy handle>
739 * OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
740 * Otherwise it is assumed to have failed
741 * The given log is copied to that location on the server. See comments for
742 * eventlog_io_q_clear_eventlog for info about odd file name behavior
745 static BOOL clear_eventlog_hook(EventlogInfo *info, pstring backup_file_name)
747 char *cmd = lp_eventlog_clear_cmd();
754 if ( !cmd || !*cmd ) {
755 DEBUG(0, ("Must define an \"eventlog clear command\" entry in the config.\n"));
759 if ( strlen(backup_file_name) )
760 pstr_sprintf( command, "%s \"%s\" \"%s\"", cmd, info->logname, backup_file_name );
762 pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
764 DEBUG(10, ("Running [%s]\n", command));
765 ret = smbrun(command, &fd);
766 DEBUGADD(10, ("returned [%d]\n", ret));
775 qlines = fd_lines_load(fd, &numlines);
776 DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
780 DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
781 if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS"))) {
782 DEBUGADD(10, ("Able to clear [%s].\n", info->logname));
783 file_lines_free(qlines);
788 file_lines_free(qlines);
792 /*******************************************************************
793 *******************************************************************/
795 WERROR _eventlog_open_eventlog(pipes_struct *p, EVENTLOG_Q_OPEN_EVENTLOG *q_u, EVENTLOG_R_OPEN_EVENTLOG *r_u)
797 EventlogInfo *info = NULL;
800 if ( !(info = TALLOC_ZERO_P(NULL, EventlogInfo)) )
803 fstrcpy( str, global_myname() );
804 if ( q_u->servername.string ) {
805 rpcstr_pull( str, q_u->servername.string->buffer,
806 sizeof(str), q_u->servername.string->uni_str_len*2, 0 );
808 info->servername = talloc_strdup( info, str );
810 fstrcpy( str, "Application" );
811 if ( q_u->logname.string ) {
812 rpcstr_pull( str, q_u->logname.string->buffer,
813 sizeof(str), q_u->logname.string->uni_str_len*2, 0 );
815 info->logname = talloc_strdup( info, str );
817 DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the server name.\n", info->servername));
818 DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info->logname));
820 if ( !create_policy_hnd(p, &r_u->handle, free_eventlog_info, (void *)info) ) {
821 free_eventlog_info(info);
825 if ( !(open_eventlog_hook(info)) ) {
826 close_policy_hnd(p, &r_u->handle);
833 /********************************************************************
834 ********************************************************************/
836 WERROR _eventlog_clear_eventlog(pipes_struct *p, EVENTLOG_Q_CLEAR_EVENTLOG *q_u, EVENTLOG_R_CLEAR_EVENTLOG *r_u)
838 EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
839 pstring backup_file_name;
841 pstrcpy( backup_file_name, "" );
843 if ( q_u->backupfile.string )
844 unistr2_to_ascii(backup_file_name, q_u->backupfile.string, sizeof(backup_file_name));
846 DEBUG(10, ("_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
847 backup_file_name, info->logname));
849 if ( !(clear_eventlog_hook(info, backup_file_name)) )
855 /********************************************************************
856 ********************************************************************/
858 WERROR _eventlog_close_eventlog(pipes_struct *p, EVENTLOG_Q_CLOSE_EVENTLOG *q_u, EVENTLOG_R_CLOSE_EVENTLOG *r_u)
860 EventlogInfo *info = find_eventlog_info_by_hnd(p,&q_u->handle);
862 if ( !(close_eventlog_hook(info)) )
865 if ( !(close_policy_hnd(p, &q_u->handle)) ) {
872 /********************************************************************
873 ********************************************************************/
875 WERROR _eventlog_read_eventlog(pipes_struct *p, EVENTLOG_Q_READ_EVENTLOG *q_u, EVENTLOG_R_READ_EVENTLOG *r_u)
877 EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
878 Eventlog_entry entry, *ee_new;
879 BOOL eof = False, eor = False;
880 const char *direction = "";
881 uint32 num_records_read = 0;
886 info->flags = q_u->flags;
887 ps = &p->out_data.rdata;
889 if ( info->flags & EVENTLOG_FORWARDS_READ )
890 direction = "forward";
891 else if ( info->flags & EVENTLOG_BACKWARDS_READ )
892 direction = "backward";
894 if ( !(read_eventlog_hook(info, &entry, direction, q_u->offset, q_u->max_read_size, &eof, &buffer, &numlines)) ) {
902 for(i = 0; i < numlines; i++) {
903 num_records_read = r_u->num_records;
904 DEBUGADD(10, ("Line[%d] = [%s]\n", i, buffer[i]));
905 parse_logentry(buffer[i], &entry, &eor);
907 /* package ee_new entry */
908 if((ee_new = read_package_entry(ps, q_u, r_u, &entry)) == NULL) {
912 /* Now see if there is enough room to add */
913 if(r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size) {
914 r_u->bytes_in_next_record = ee_new->record.length;
915 /* response would be too big to fit in client-size buffer */
918 add_record_to_resp(r_u, ee_new);
921 num_records_read = r_u->num_records - num_records_read;
922 DEBUG(10, ("_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
925 r_u->num_bytes_in_resp,
926 q_u->max_read_size));
935 /********************************************************************
936 ********************************************************************/
938 WERROR _eventlog_get_oldest_entry(pipes_struct *p, EVENTLOG_Q_GET_OLDEST_ENTRY *q_u, EVENTLOG_R_GET_OLDEST_ENTRY *r_u)
940 EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
942 if ( !(get_oldest_entry_hook(info)) )
945 r_u->oldest_entry = info->oldest_entry;
950 /********************************************************************
951 ********************************************************************/
953 WERROR _eventlog_get_num_records(pipes_struct *p, EVENTLOG_Q_GET_NUM_RECORDS *q_u, EVENTLOG_R_GET_NUM_RECORDS *r_u)
955 EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
957 if ( !(get_num_records_hook(info)) )
960 r_u->num_records = info->num_records;