2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Marcin Krzysztof Porwit 2005,
5 * Copyright (C) Brian Moran 2005,
6 * Copyright (C) Gerald (Jerry) Carter 2005.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 #define DBGC_CLASS DBGC_RPC_SRV
30 uint32 current_record
;
34 uint32 access_granted
;
37 /********************************************************************
38 ********************************************************************/
40 static void free_eventlog_info( void *ptr
)
42 EVENTLOG_INFO
*elog
= (EVENTLOG_INFO
*)ptr
;
45 elog_close_tdb( elog
->etdb
, False
);
50 /********************************************************************
51 ********************************************************************/
53 static EVENTLOG_INFO
*find_eventlog_info_by_hnd( pipes_struct
* p
,
58 if ( !find_policy_by_hnd( p
, handle
, (void **)(void *)&info
) ) {
60 ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
67 /********************************************************************
68 ********************************************************************/
70 static bool elog_check_access( EVENTLOG_INFO
*info
, NT_USER_TOKEN
*token
)
72 char *tdbname
= elog_tdbname(talloc_tos(), info
->logname
);
79 /* get the security descriptor for the file */
81 sec_desc
= get_nt_acl_no_snum( info
, tdbname
);
82 TALLOC_FREE( tdbname
);
85 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
92 if ( geteuid() == sec_initial_uid() ) {
93 DEBUG(5,("elog_check_access: using root's token\n"));
94 token
= get_root_nt_token();
97 /* run the check, try for the max allowed */
99 status
= se_access_check( sec_desc
, token
, MAXIMUM_ALLOWED_ACCESS
,
100 &info
->access_granted
);
103 TALLOC_FREE( sec_desc
);
105 if (!NT_STATUS_IS_OK(status
)) {
106 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
111 /* we have to have READ permission for a successful open */
113 return ( info
->access_granted
& SA_RIGHT_FILE_READ_DATA
);
116 /********************************************************************
117 ********************************************************************/
119 static bool elog_validate_logname( const char *name
)
122 const char **elogs
= lp_eventlog_list();
128 for ( i
=0; elogs
[i
]; i
++ ) {
129 if ( strequal( name
, elogs
[i
] ) )
136 /********************************************************************
137 ********************************************************************/
139 static bool get_num_records_hook( EVENTLOG_INFO
* info
)
145 DEBUG( 10, ( "No open tdb for %s\n", info
->logname
) );
149 /* lock the tdb since we have to get 2 records */
151 tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
, 1 );
152 next_record
= tdb_fetch_int32( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
);
153 oldest_record
= tdb_fetch_int32( ELOG_TDB_CTX(info
->etdb
), EVT_OLDEST_ENTRY
);
154 tdb_unlock_bystring( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
);
157 ( "Oldest Record %d; Next Record %d\n", oldest_record
,
160 info
->num_records
= ( next_record
- oldest_record
);
161 info
->oldest_entry
= oldest_record
;
166 /********************************************************************
167 ********************************************************************/
169 static bool get_oldest_entry_hook( EVENTLOG_INFO
* info
)
171 /* it's the same thing */
172 return get_num_records_hook( info
);
175 /********************************************************************
176 ********************************************************************/
178 static NTSTATUS
elog_open( pipes_struct
* p
, const char *logname
, POLICY_HND
*hnd
)
182 /* first thing is to validate the eventlog name */
184 if ( !elog_validate_logname( logname
) )
185 return NT_STATUS_OBJECT_PATH_INVALID
;
187 if ( !(elog
= TALLOC_ZERO_P( NULL
, EVENTLOG_INFO
)) )
188 return NT_STATUS_NO_MEMORY
;
190 elog
->logname
= talloc_strdup( elog
, logname
);
192 /* Open the tdb first (so that we can create any new tdbs if necessary).
193 We have to do this as root and then use an internal access check
194 on the file permissions since you can only have a tdb open once
195 in a single process */
198 elog
->etdb
= elog_open_tdb( elog
->logname
, False
);
202 /* according to MSDN, if the logfile cannot be found, we should
203 default to the "Application" log */
205 if ( !strequal( logname
, ELOG_APPL
) ) {
207 TALLOC_FREE( elog
->logname
);
209 elog
->logname
= talloc_strdup( elog
, ELOG_APPL
);
211 /* do the access check */
212 if ( !elog_check_access( elog
, p
->pipe_user
.nt_user_token
) ) {
214 return NT_STATUS_ACCESS_DENIED
;
218 elog
->etdb
= elog_open_tdb( elog
->logname
, False
);
224 return NT_STATUS_ACCESS_DENIED
; /* ??? */
228 /* now do the access check. Close the tdb if we fail here */
230 if ( !elog_check_access( elog
, p
->pipe_user
.nt_user_token
) ) {
231 elog_close_tdb( elog
->etdb
, False
);
233 return NT_STATUS_ACCESS_DENIED
;
236 /* create the policy handle */
238 if ( !create_policy_hnd
239 ( p
, hnd
, free_eventlog_info
, ( void * ) elog
) ) {
240 free_eventlog_info( elog
);
241 return NT_STATUS_NO_MEMORY
;
244 /* set the initial current_record pointer */
246 if ( !get_oldest_entry_hook( elog
) ) {
247 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
248 "get any information on internal records!\n"));
251 elog
->current_record
= elog
->oldest_entry
;
256 /********************************************************************
257 ********************************************************************/
259 static NTSTATUS
elog_close( pipes_struct
*p
, POLICY_HND
*hnd
)
261 if ( !( close_policy_hnd( p
, hnd
) ) ) {
262 return NT_STATUS_INVALID_HANDLE
;
268 /*******************************************************************
269 *******************************************************************/
271 static int elog_size( EVENTLOG_INFO
*info
)
273 if ( !info
|| !info
->etdb
) {
274 DEBUG(0,("elog_size: Invalid info* structure!\n"));
278 return elog_tdb_size( ELOG_TDB_CTX(info
->etdb
), NULL
, NULL
);
281 /********************************************************************
282 For the given tdb, get the next eventlog record into the passed
283 Eventlog_entry. returns NULL if it can't get the record for some reason.
284 ********************************************************************/
286 static Eventlog_entry
*get_eventlog_record(prs_struct
*ps
,
290 Eventlog_entry
*ee
= NULL
;
297 char *wpsource
= NULL
;
298 char *wpcomputer
= NULL
;
301 char *puserdata
= NULL
;
303 key
.dsize
= sizeof(int32_t);
306 key
.dptr
= (unsigned char *)&srecno
;
308 ret
= tdb_fetch( tdb
, key
);
310 if ( ret
.dsize
== 0 ) {
312 ( "Can't find a record for the key, record %d\n",
317 len
= tdb_unpack( ret
.dptr
, ret
.dsize
, "d", &reclen
);
319 DEBUG( 10, ( "Unpacking record %d, size is %d\n", srecno
, len
) );
324 ee
= TALLOC_ARRAY(ps
->mem_ctx
, Eventlog_entry
, 1);
330 len
= tdb_unpack( ret
.dptr
, ret
.dsize
, "ddddddwwwwddddddBBdBBBd",
331 &ee
->record
.length
, &ee
->record
.reserved1
,
332 &ee
->record
.record_number
,
333 &ee
->record
.time_generated
,
334 &ee
->record
.time_written
, &ee
->record
.event_id
,
335 &ee
->record
.event_type
, &ee
->record
.num_strings
,
336 &ee
->record
.event_category
, &ee
->record
.reserved2
,
337 &ee
->record
.closing_record_number
,
338 &ee
->record
.string_offset
,
339 &ee
->record
.user_sid_length
,
340 &ee
->record
.user_sid_offset
,
341 &ee
->record
.data_length
, &ee
->record
.data_offset
,
342 &ee
->data_record
.source_name_len
, &wpsource
,
343 &ee
->data_record
.computer_name_len
, &wpcomputer
,
344 &ee
->data_record
.sid_padding
,
345 &ee
->record
.user_sid_length
, &wpsid
,
346 &ee
->data_record
.strings_len
, &wpstrs
,
347 &ee
->data_record
.user_data_len
, &puserdata
,
348 &ee
->data_record
.data_padding
);
350 ( "Read record %d, len in tdb was %d\n",
351 ee
->record
.record_number
, len
) );
353 /* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff
354 into it's 2nd argment for 'B' */
357 ee
->data_record
.computer_name
= (smb_ucs2_t
*)TALLOC_MEMDUP(
358 ee
, wpcomputer
, ee
->data_record
.computer_name_len
);
359 if (!ee
->data_record
.computer_name
) {
365 ee
->data_record
.source_name
= (smb_ucs2_t
*)TALLOC_MEMDUP(
366 ee
, wpsource
, ee
->data_record
.source_name_len
);
367 if (!ee
->data_record
.source_name
) {
374 ee
->data_record
.sid
= (smb_ucs2_t
*)TALLOC_MEMDUP(
375 ee
, wpsid
, ee
->record
.user_sid_length
);
376 if (!ee
->data_record
.sid
) {
382 ee
->data_record
.strings
= (smb_ucs2_t
*)TALLOC_MEMDUP(
383 ee
, wpstrs
, ee
->data_record
.strings_len
);
384 if (!ee
->data_record
.strings
) {
391 ee
->data_record
.user_data
= (char *)TALLOC_MEMDUP(
392 ee
, puserdata
, ee
->data_record
.user_data_len
);
393 if (!ee
->data_record
.user_data
) {
401 SAFE_FREE(wpcomputer
);
405 SAFE_FREE(puserdata
);
407 DEBUG( 10, ( "get_eventlog_record: read back %d\n", len
) );
409 ( "get_eventlog_record: computer_name %d is ",
410 ee
->data_record
.computer_name_len
) );
415 /********************************************************************
416 note that this can only be called AFTER the table is constructed,
417 since it uses the table to find the tdb handle
418 ********************************************************************/
420 static bool sync_eventlog_params( EVENTLOG_INFO
*info
)
425 struct registry_key
*key
;
426 struct registry_value
*value
;
428 char *elogname
= info
->logname
;
429 TALLOC_CTX
*ctx
= talloc_stackframe();
432 DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname
) );
435 DEBUG( 4, ( "No open tdb! (%s)\n", info
->logname
) );
438 /* set resonable defaults. 512Kb on size and 1 week on time */
441 uiRetention
= 604800;
443 /* the general idea is to internally open the registry
444 key and retrieve the values. That way we can continue
445 to use the same fetch/store api that we use in
448 path
= talloc_asprintf(ctx
, "%s/%s", KEY_EVENTLOG
, elogname
);
453 wresult
= reg_open_path(ctx
, path
, REG_KEY_READ
, get_root_nt_token(),
456 if ( !W_ERROR_IS_OK( wresult
) ) {
458 ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
459 path
, dos_errstr( wresult
) ) );
463 wresult
= reg_queryvalue(key
, key
, "Retention", &value
);
464 if (!W_ERROR_IS_OK(wresult
)) {
465 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
466 dos_errstr(wresult
)));
469 uiRetention
= value
->v
.dword
;
471 wresult
= reg_queryvalue(key
, key
, "MaxSize", &value
);
472 if (!W_ERROR_IS_OK(wresult
)) {
473 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
474 dos_errstr(wresult
)));
477 uiMaxSize
= value
->v
.dword
;
479 tdb_store_int32( ELOG_TDB_CTX(info
->etdb
), EVT_MAXSIZE
, uiMaxSize
);
480 tdb_store_int32( ELOG_TDB_CTX(info
->etdb
), EVT_RETENTION
, uiRetention
);
489 /********************************************************************
490 ********************************************************************/
492 static Eventlog_entry
*read_package_entry( prs_struct
* ps
,
493 Eventlog_entry
* entry
)
496 Eventlog_entry
*ee_new
= NULL
;
498 ee_new
= PRS_ALLOC_MEM( ps
, Eventlog_entry
, 1 );
499 if ( ee_new
== NULL
) {
503 entry
->data_record
.sid_padding
=
505 ( ( entry
->data_record
.source_name_len
+
506 entry
->data_record
.computer_name_len
) % 4 ) ) % 4 );
507 entry
->data_record
.data_padding
=
509 ( ( entry
->data_record
.strings_len
+
510 entry
->data_record
.user_data_len
) % 4 ) ) % 4;
511 entry
->record
.length
= sizeof( Eventlog_record
);
512 entry
->record
.length
+= entry
->data_record
.source_name_len
;
513 entry
->record
.length
+= entry
->data_record
.computer_name_len
;
514 if ( entry
->record
.user_sid_length
== 0 ) {
515 /* Should not pad to a DWORD boundary for writing out the sid if there is
516 no SID, so just propagate the padding to pad the data */
517 entry
->data_record
.data_padding
+=
518 entry
->data_record
.sid_padding
;
519 entry
->data_record
.sid_padding
= 0;
522 ( "sid_padding is [%d].\n", entry
->data_record
.sid_padding
) );
524 ( "data_padding is [%d].\n",
525 entry
->data_record
.data_padding
) );
527 entry
->record
.length
+= entry
->data_record
.sid_padding
;
528 entry
->record
.length
+= entry
->record
.user_sid_length
;
529 entry
->record
.length
+= entry
->data_record
.strings_len
;
530 entry
->record
.length
+= entry
->data_record
.user_data_len
;
531 entry
->record
.length
+= entry
->data_record
.data_padding
;
532 /* need another copy of length at the end of the data */
533 entry
->record
.length
+= sizeof( entry
->record
.length
);
535 ( "entry->record.length is [%d].\n", entry
->record
.length
) );
537 PRS_ALLOC_MEM( ps
, uint8
,
538 entry
->record
.length
-
539 sizeof( Eventlog_record
) -
540 sizeof( entry
->record
.length
) );
541 if ( entry
->data
== NULL
) {
544 offset
= entry
->data
;
545 memcpy( offset
, entry
->data_record
.source_name
,
546 entry
->data_record
.source_name_len
);
547 offset
+= entry
->data_record
.source_name_len
;
548 memcpy( offset
, entry
->data_record
.computer_name
,
549 entry
->data_record
.computer_name_len
);
550 offset
+= entry
->data_record
.computer_name_len
;
551 /* SID needs to be DWORD-aligned */
552 offset
+= entry
->data_record
.sid_padding
;
553 entry
->record
.user_sid_offset
=
554 sizeof( Eventlog_record
) + ( offset
- entry
->data
);
555 memcpy( offset
, entry
->data_record
.sid
,
556 entry
->record
.user_sid_length
);
557 offset
+= entry
->record
.user_sid_length
;
558 /* Now do the strings */
559 entry
->record
.string_offset
=
560 sizeof( Eventlog_record
) + ( offset
- entry
->data
);
561 memcpy( offset
, entry
->data_record
.strings
,
562 entry
->data_record
.strings_len
);
563 offset
+= entry
->data_record
.strings_len
;
564 /* Now do the data */
565 entry
->record
.data_length
= entry
->data_record
.user_data_len
;
566 entry
->record
.data_offset
=
567 sizeof( Eventlog_record
) + ( offset
- entry
->data
);
568 memcpy( offset
, entry
->data_record
.user_data
,
569 entry
->data_record
.user_data_len
);
570 offset
+= entry
->data_record
.user_data_len
;
572 memcpy( &( ee_new
->record
), &entry
->record
,
573 sizeof( Eventlog_record
) );
574 memcpy( &( ee_new
->data_record
), &entry
->data_record
,
575 sizeof( Eventlog_data_record
) );
576 ee_new
->data
= entry
->data
;
581 /********************************************************************
582 ********************************************************************/
584 static bool add_record_to_resp( EVENTLOG_R_READ_EVENTLOG
* r_u
,
585 Eventlog_entry
* ee_new
)
587 Eventlog_entry
*insert_point
;
589 insert_point
= r_u
->entry
;
591 if ( NULL
== insert_point
) {
595 while ( ( NULL
!= insert_point
->next
) ) {
596 insert_point
= insert_point
->next
;
599 insert_point
->next
= ee_new
;
602 r_u
->num_bytes_in_resp
+= ee_new
->record
.length
;
607 /********************************************************************
608 _eventlog_OpenEventLogW
609 ********************************************************************/
611 NTSTATUS
_eventlog_OpenEventLogW(pipes_struct
*p
,
612 struct eventlog_OpenEventLogW
*r
)
614 const char *servername
= "";
615 const char *logname
= "";
619 if (r
->in
.servername
->string
) {
620 servername
= r
->in
.servername
->string
;
623 if (r
->in
.logname
->string
) {
624 logname
= r
->in
.logname
->string
;
627 DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n",
628 servername
, logname
));
630 /* according to MSDN, if the logfile cannot be found, we should
631 default to the "Application" log */
633 if ( !NT_STATUS_IS_OK( result
= elog_open( p
, logname
, r
->out
.handle
)) )
636 if ( !(info
= find_eventlog_info_by_hnd( p
, r
->out
.handle
)) ) {
637 DEBUG(0,("_eventlog_open_eventlog: eventlog (%s) opened but unable to find handle!\n",
639 elog_close( p
, r
->out
.handle
);
640 return NT_STATUS_INVALID_HANDLE
;
643 DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info
)));
645 sync_eventlog_params( info
);
646 prune_eventlog( ELOG_TDB_CTX(info
->etdb
) );
651 /********************************************************************
652 _eventlog_ClearEventLogW
653 This call still needs some work
654 ********************************************************************/
655 /** The windows client seems to be doing something funny with the file name
657 ClearEventLog(handle, "backup_file")
658 on the client side will result in the backup file name looking like this on the
660 \??\${CWD of client}\backup_file
661 If an absolute path gets specified, such as
662 ClearEventLog(handle, "C:\\temp\\backup_file")
663 then it is still mangled by the client into this:
664 \??\C:\temp\backup_file
665 when it is on the wire.
666 I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
667 would be added in given that the backup file gets written on the server side. */
669 NTSTATUS
_eventlog_ClearEventLogW(pipes_struct
*p
,
670 struct eventlog_ClearEventLogW
*r
)
672 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
673 const char *backup_file_name
= NULL
;
676 return NT_STATUS_INVALID_HANDLE
;
678 if (r
->in
.backupfile
&& r
->in
.backupfile
->string
) {
680 backup_file_name
= r
->in
.backupfile
->string
;
682 DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup "
683 "file name for log [%s].",
684 backup_file_name
, info
->logname
) );
687 /* check for WRITE access to the file */
689 if ( !(info
->access_granted
&SA_RIGHT_FILE_WRITE_DATA
) )
690 return NT_STATUS_ACCESS_DENIED
;
692 /* Force a close and reopen */
694 elog_close_tdb( info
->etdb
, True
);
696 info
->etdb
= elog_open_tdb( info
->logname
, True
);
700 return NT_STATUS_ACCESS_DENIED
;
705 /********************************************************************
706 ********************************************************************/
708 NTSTATUS
_eventlog_CloseEventLog( pipes_struct
* p
, struct eventlog_CloseEventLog
*r
)
710 return elog_close( p
, r
->in
.handle
);
713 /********************************************************************
714 ********************************************************************/
716 NTSTATUS
_eventlog_read_eventlog( pipes_struct
* p
,
717 EVENTLOG_Q_READ_EVENTLOG
* q_u
,
718 EVENTLOG_R_READ_EVENTLOG
* r_u
)
720 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, &q_u
->handle
);
721 Eventlog_entry
*entry
= NULL
, *ee_new
= NULL
;
722 uint32 num_records_read
= 0;
724 int bytes_left
, record_number
;
725 uint32 elog_read_type
, elog_read_dir
;
728 return NT_STATUS_INVALID_HANDLE
;
731 info
->flags
= q_u
->flags
;
732 ps
= &p
->out_data
.rdata
;
734 bytes_left
= q_u
->max_read_size
;
737 return NT_STATUS_ACCESS_DENIED
;
739 /* check for valid flags. Can't use the sequential and seek flags together */
741 elog_read_type
= q_u
->flags
& (EVENTLOG_SEQUENTIAL_READ
|EVENTLOG_SEEK_READ
);
742 elog_read_dir
= q_u
->flags
& (EVENTLOG_FORWARDS_READ
|EVENTLOG_BACKWARDS_READ
);
744 if ( elog_read_type
== (EVENTLOG_SEQUENTIAL_READ
|EVENTLOG_SEEK_READ
)
745 || elog_read_dir
== (EVENTLOG_FORWARDS_READ
|EVENTLOG_BACKWARDS_READ
) )
747 DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u
->flags
));
748 return NT_STATUS_INVALID_PARAMETER
;
751 /* a sequential read should ignore the offset */
753 if ( elog_read_type
& EVENTLOG_SEQUENTIAL_READ
)
754 record_number
= info
->current_record
;
756 record_number
= q_u
->offset
;
758 while ( bytes_left
> 0 ) {
760 /* assume that when the record fetch fails, that we are done */
762 entry
= get_eventlog_record (ps
, ELOG_TDB_CTX(info
->etdb
), record_number
);
767 DEBUG( 8, ( "Retrieved record %d\n", record_number
) );
769 /* Now see if there is enough room to add */
771 if ( !(ee_new
= read_package_entry( ps
, entry
)) )
772 return NT_STATUS_NO_MEMORY
;
774 if ( r_u
->num_bytes_in_resp
+ ee_new
->record
.length
> q_u
->max_read_size
) {
775 r_u
->bytes_in_next_record
= ee_new
->record
.length
;
777 /* response would be too big to fit in client-size buffer */
783 add_record_to_resp( r_u
, ee_new
);
784 bytes_left
-= ee_new
->record
.length
;
786 num_records_read
= r_u
->num_records
- num_records_read
;
788 DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total "
789 "of [%d] records using [%d] bytes out of a max of [%d].\n",
790 num_records_read
, r_u
->num_records
,
791 r_u
->num_bytes_in_resp
,
792 q_u
->max_read_size
) );
794 if ( info
->flags
& EVENTLOG_FORWARDS_READ
)
799 /* update the eventlog record pointer */
801 info
->current_record
= record_number
;
804 /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to
805 say when there are no more records */
807 return (num_records_read
? NT_STATUS_OK
: NT_STATUS_BUFFER_TOO_SMALL
);
810 /********************************************************************
811 _eventlog_GetOldestRecord
812 ********************************************************************/
814 NTSTATUS
_eventlog_GetOldestRecord(pipes_struct
*p
,
815 struct eventlog_GetOldestRecord
*r
)
817 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
820 return NT_STATUS_INVALID_HANDLE
;
823 if ( !( get_oldest_entry_hook( info
) ) )
824 return NT_STATUS_ACCESS_DENIED
;
826 *r
->out
.oldest_entry
= info
->oldest_entry
;
831 /********************************************************************
832 _eventlog_GetNumRecords
833 ********************************************************************/
835 NTSTATUS
_eventlog_GetNumRecords(pipes_struct
*p
,
836 struct eventlog_GetNumRecords
*r
)
838 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
841 return NT_STATUS_INVALID_HANDLE
;
844 if ( !( get_num_records_hook( info
) ) )
845 return NT_STATUS_ACCESS_DENIED
;
847 *r
->out
.number
= info
->num_records
;
852 NTSTATUS
_eventlog_BackupEventLogW(pipes_struct
*p
, struct eventlog_BackupEventLogW
*r
)
854 p
->rng_fault_state
= True
;
855 return NT_STATUS_NOT_IMPLEMENTED
;
858 NTSTATUS
_eventlog_DeregisterEventSource(pipes_struct
*p
, struct eventlog_DeregisterEventSource
*r
)
860 p
->rng_fault_state
= True
;
861 return NT_STATUS_NOT_IMPLEMENTED
;
864 NTSTATUS
_eventlog_ChangeNotify(pipes_struct
*p
, struct eventlog_ChangeNotify
*r
)
866 p
->rng_fault_state
= True
;
867 return NT_STATUS_NOT_IMPLEMENTED
;
870 NTSTATUS
_eventlog_RegisterEventSourceW(pipes_struct
*p
, struct eventlog_RegisterEventSourceW
*r
)
872 p
->rng_fault_state
= True
;
873 return NT_STATUS_NOT_IMPLEMENTED
;
876 NTSTATUS
_eventlog_OpenBackupEventLogW(pipes_struct
*p
, struct eventlog_OpenBackupEventLogW
*r
)
878 p
->rng_fault_state
= True
;
879 return NT_STATUS_NOT_IMPLEMENTED
;
882 NTSTATUS
_eventlog_ReadEventLogW(pipes_struct
*p
, struct eventlog_ReadEventLogW
*r
)
884 p
->rng_fault_state
= True
;
885 return NT_STATUS_NOT_IMPLEMENTED
;
888 NTSTATUS
_eventlog_ReportEventW(pipes_struct
*p
, struct eventlog_ReportEventW
*r
)
890 p
->rng_fault_state
= True
;
891 return NT_STATUS_NOT_IMPLEMENTED
;
894 NTSTATUS
_eventlog_ClearEventLogA(pipes_struct
*p
, struct eventlog_ClearEventLogA
*r
)
896 p
->rng_fault_state
= True
;
897 return NT_STATUS_NOT_IMPLEMENTED
;
900 NTSTATUS
_eventlog_BackupEventLogA(pipes_struct
*p
, struct eventlog_BackupEventLogA
*r
)
902 p
->rng_fault_state
= True
;
903 return NT_STATUS_NOT_IMPLEMENTED
;
906 NTSTATUS
_eventlog_OpenEventLogA(pipes_struct
*p
, struct eventlog_OpenEventLogA
*r
)
908 p
->rng_fault_state
= True
;
909 return NT_STATUS_NOT_IMPLEMENTED
;
912 NTSTATUS
_eventlog_RegisterEventSourceA(pipes_struct
*p
, struct eventlog_RegisterEventSourceA
*r
)
914 p
->rng_fault_state
= True
;
915 return NT_STATUS_NOT_IMPLEMENTED
;
918 NTSTATUS
_eventlog_OpenBackupEventLogA(pipes_struct
*p
, struct eventlog_OpenBackupEventLogA
*r
)
920 p
->rng_fault_state
= True
;
921 return NT_STATUS_NOT_IMPLEMENTED
;
924 NTSTATUS
_eventlog_ReadEventLogA(pipes_struct
*p
, struct eventlog_ReadEventLogA
*r
)
926 p
->rng_fault_state
= True
;
927 return NT_STATUS_NOT_IMPLEMENTED
;
930 NTSTATUS
_eventlog_ReportEventA(pipes_struct
*p
, struct eventlog_ReportEventA
*r
)
932 p
->rng_fault_state
= True
;
933 return NT_STATUS_NOT_IMPLEMENTED
;
936 NTSTATUS
_eventlog_RegisterClusterSvc(pipes_struct
*p
, struct eventlog_RegisterClusterSvc
*r
)
938 p
->rng_fault_state
= True
;
939 return NT_STATUS_NOT_IMPLEMENTED
;
942 NTSTATUS
_eventlog_DeregisterClusterSvc(pipes_struct
*p
, struct eventlog_DeregisterClusterSvc
*r
)
944 p
->rng_fault_state
= True
;
945 return NT_STATUS_NOT_IMPLEMENTED
;
948 NTSTATUS
_eventlog_WriteClusterEvents(pipes_struct
*p
, struct eventlog_WriteClusterEvents
*r
)
950 p
->rng_fault_state
= True
;
951 return NT_STATUS_NOT_IMPLEMENTED
;
954 NTSTATUS
_eventlog_GetLogIntormation(pipes_struct
*p
, struct eventlog_GetLogIntormation
*r
)
956 p
->rng_fault_state
= True
;
957 return NT_STATUS_NOT_IMPLEMENTED
;
960 NTSTATUS
_eventlog_FlushEventLog(pipes_struct
*p
, struct eventlog_FlushEventLog
*r
)
962 p
->rng_fault_state
= True
;
963 return NT_STATUS_NOT_IMPLEMENTED
;