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
);
80 /* get the security descriptor for the file */
82 sec_desc
= get_nt_acl_no_snum( info
, tdbname
);
86 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
93 if ( geteuid() == sec_initial_uid() ) {
94 DEBUG(5,("elog_check_access: using root's token\n"));
95 token
= get_root_nt_token();
98 /* run the check, try for the max allowed */
100 ret
= se_access_check( sec_desc
, token
, MAXIMUM_ALLOWED_ACCESS
,
101 &info
->access_granted
, &ntstatus
);
104 TALLOC_FREE( sec_desc
);
107 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
108 nt_errstr( ntstatus
)));
112 /* we have to have READ permission for a successful open */
114 return ( info
->access_granted
& SA_RIGHT_FILE_READ_DATA
);
117 /********************************************************************
118 ********************************************************************/
120 static bool elog_validate_logname( const char *name
)
123 const char **elogs
= lp_eventlog_list();
129 for ( i
=0; elogs
[i
]; i
++ ) {
130 if ( strequal( name
, elogs
[i
] ) )
137 /********************************************************************
138 ********************************************************************/
140 static bool get_num_records_hook( EVENTLOG_INFO
* info
)
146 DEBUG( 10, ( "No open tdb for %s\n", info
->logname
) );
150 /* lock the tdb since we have to get 2 records */
152 tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
, 1 );
153 next_record
= tdb_fetch_int32( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
);
154 oldest_record
= tdb_fetch_int32( ELOG_TDB_CTX(info
->etdb
), EVT_OLDEST_ENTRY
);
155 tdb_unlock_bystring( ELOG_TDB_CTX(info
->etdb
), EVT_NEXT_RECORD
);
158 ( "Oldest Record %d; Next Record %d\n", oldest_record
,
161 info
->num_records
= ( next_record
- oldest_record
);
162 info
->oldest_entry
= oldest_record
;
167 /********************************************************************
168 ********************************************************************/
170 static bool get_oldest_entry_hook( EVENTLOG_INFO
* info
)
172 /* it's the same thing */
173 return get_num_records_hook( info
);
176 /********************************************************************
177 ********************************************************************/
179 static NTSTATUS
elog_open( pipes_struct
* p
, const char *logname
, POLICY_HND
*hnd
)
183 /* first thing is to validate the eventlog name */
185 if ( !elog_validate_logname( logname
) )
186 return NT_STATUS_OBJECT_PATH_INVALID
;
188 if ( !(elog
= TALLOC_ZERO_P( NULL
, EVENTLOG_INFO
)) )
189 return NT_STATUS_NO_MEMORY
;
191 elog
->logname
= talloc_strdup( elog
, logname
);
193 /* Open the tdb first (so that we can create any new tdbs if necessary).
194 We have to do this as root and then use an internal access check
195 on the file permissions since you can only have a tdb open once
196 in a single process */
199 elog
->etdb
= elog_open_tdb( elog
->logname
, False
);
203 /* according to MSDN, if the logfile cannot be found, we should
204 default to the "Application" log */
206 if ( !strequal( logname
, ELOG_APPL
) ) {
208 TALLOC_FREE( elog
->logname
);
210 elog
->logname
= talloc_strdup( elog
, ELOG_APPL
);
212 /* do the access check */
213 if ( !elog_check_access( elog
, p
->pipe_user
.nt_user_token
) ) {
215 return NT_STATUS_ACCESS_DENIED
;
219 elog
->etdb
= elog_open_tdb( elog
->logname
, False
);
225 return NT_STATUS_ACCESS_DENIED
; /* ??? */
229 /* now do the access check. Close the tdb if we fail here */
231 if ( !elog_check_access( elog
, p
->pipe_user
.nt_user_token
) ) {
232 elog_close_tdb( elog
->etdb
, False
);
234 return NT_STATUS_ACCESS_DENIED
;
237 /* create the policy handle */
239 if ( !create_policy_hnd
240 ( p
, hnd
, free_eventlog_info
, ( void * ) elog
) ) {
241 free_eventlog_info( elog
);
242 return NT_STATUS_NO_MEMORY
;
245 /* set the initial current_record pointer */
247 if ( !get_oldest_entry_hook( elog
) ) {
248 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
249 "get any information on internal records!\n"));
252 elog
->current_record
= elog
->oldest_entry
;
257 /********************************************************************
258 ********************************************************************/
260 static NTSTATUS
elog_close( pipes_struct
*p
, POLICY_HND
*hnd
)
262 if ( !( close_policy_hnd( p
, hnd
) ) ) {
263 return NT_STATUS_INVALID_HANDLE
;
269 /*******************************************************************
270 *******************************************************************/
272 static int elog_size( EVENTLOG_INFO
*info
)
274 if ( !info
|| !info
->etdb
) {
275 DEBUG(0,("elog_size: Invalid info* structure!\n"));
279 return elog_tdb_size( ELOG_TDB_CTX(info
->etdb
), NULL
, NULL
);
282 /********************************************************************
283 For the given tdb, get the next eventlog record into the passed
284 Eventlog_entry. returns NULL if it can't get the record for some reason.
285 ********************************************************************/
287 static Eventlog_entry
*get_eventlog_record(prs_struct
*ps
,
291 Eventlog_entry
*ee
= NULL
;
298 char *wpsource
= NULL
;
299 char *wpcomputer
= NULL
;
302 char *puserdata
= NULL
;
304 key
.dsize
= sizeof(int32
);
307 key
.dptr
= ( uint8
* ) &srecno
;
309 ret
= tdb_fetch( tdb
, key
);
311 if ( ret
.dsize
== 0 ) {
313 ( "Can't find a record for the key, record %d\n",
318 len
= tdb_unpack( ret
.dptr
, ret
.dsize
, "d", &reclen
);
320 DEBUG( 10, ( "Unpacking record %d, size is %d\n", srecno
, len
) );
325 ee
= TALLOC_ARRAY(ps
->mem_ctx
, Eventlog_entry
, 1);
331 len
= tdb_unpack( ret
.dptr
, ret
.dsize
, "ddddddwwwwddddddBBdBBBd",
332 &ee
->record
.length
, &ee
->record
.reserved1
,
333 &ee
->record
.record_number
,
334 &ee
->record
.time_generated
,
335 &ee
->record
.time_written
, &ee
->record
.event_id
,
336 &ee
->record
.event_type
, &ee
->record
.num_strings
,
337 &ee
->record
.event_category
, &ee
->record
.reserved2
,
338 &ee
->record
.closing_record_number
,
339 &ee
->record
.string_offset
,
340 &ee
->record
.user_sid_length
,
341 &ee
->record
.user_sid_offset
,
342 &ee
->record
.data_length
, &ee
->record
.data_offset
,
343 &ee
->data_record
.source_name_len
, &wpsource
,
344 &ee
->data_record
.computer_name_len
, &wpcomputer
,
345 &ee
->data_record
.sid_padding
,
346 &ee
->record
.user_sid_length
, &wpsid
,
347 &ee
->data_record
.strings_len
, &wpstrs
,
348 &ee
->data_record
.user_data_len
, &puserdata
,
349 &ee
->data_record
.data_padding
);
351 ( "Read record %d, len in tdb was %d\n",
352 ee
->record
.record_number
, len
) );
354 /* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff
355 into it's 2nd argment for 'B' */
358 ee
->data_record
.computer_name
= (smb_ucs2_t
*)TALLOC_MEMDUP(
359 ee
, wpcomputer
, ee
->data_record
.computer_name_len
);
360 if (!ee
->data_record
.computer_name
) {
366 ee
->data_record
.source_name
= (smb_ucs2_t
*)TALLOC_MEMDUP(
367 ee
, wpsource
, ee
->data_record
.source_name_len
);
368 if (!ee
->data_record
.source_name
) {
375 ee
->data_record
.sid
= (smb_ucs2_t
*)TALLOC_MEMDUP(
376 ee
, wpsid
, ee
->record
.user_sid_length
);
377 if (!ee
->data_record
.sid
) {
383 ee
->data_record
.strings
= (smb_ucs2_t
*)TALLOC_MEMDUP(
384 ee
, wpstrs
, ee
->data_record
.strings_len
);
385 if (!ee
->data_record
.strings
) {
392 ee
->data_record
.user_data
= (char *)TALLOC_MEMDUP(
393 ee
, puserdata
, ee
->data_record
.user_data_len
);
394 if (!ee
->data_record
.user_data
) {
402 SAFE_FREE(wpcomputer
);
406 SAFE_FREE(puserdata
);
408 DEBUG( 10, ( "get_eventlog_record: read back %d\n", len
) );
410 ( "get_eventlog_record: computer_name %d is ",
411 ee
->data_record
.computer_name_len
) );
416 /********************************************************************
417 note that this can only be called AFTER the table is constructed,
418 since it uses the table to find the tdb handle
419 ********************************************************************/
421 static bool sync_eventlog_params( EVENTLOG_INFO
*info
)
426 struct registry_key
*key
;
427 struct registry_value
*value
;
429 char *elogname
= info
->logname
;
430 TALLOC_CTX
*ctx
= talloc_tos();
433 DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname
) );
436 DEBUG( 4, ( "No open tdb! (%s)\n", info
->logname
) );
439 /* set resonable defaults. 512Kb on size and 1 week on time */
442 uiRetention
= 604800;
444 /* the general idea is to internally open the registry
445 key and retrieve the values. That way we can continue
446 to use the same fetch/store api that we use in
449 path
= talloc_asprintf(ctx
, "%s/%s", KEY_EVENTLOG
, elogname
);
454 wresult
= reg_open_path(ctx
, path
, REG_KEY_READ
, get_root_nt_token(),
457 if ( !W_ERROR_IS_OK( wresult
) ) {
459 ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
460 path
, dos_errstr( wresult
) ) );
464 wresult
= reg_queryvalue(key
, key
, "Retention", &value
);
465 if (!W_ERROR_IS_OK(wresult
)) {
466 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
467 dos_errstr(wresult
)));
471 uiRetention
= value
->v
.dword
;
473 wresult
= reg_queryvalue(key
, key
, "MaxSize", &value
);
474 if (!W_ERROR_IS_OK(wresult
)) {
475 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
476 dos_errstr(wresult
)));
480 uiMaxSize
= value
->v
.dword
;
482 tdb_store_int32( ELOG_TDB_CTX(info
->etdb
), EVT_MAXSIZE
, uiMaxSize
);
483 tdb_store_int32( ELOG_TDB_CTX(info
->etdb
), EVT_RETENTION
, uiRetention
);
492 /********************************************************************
493 ********************************************************************/
495 static Eventlog_entry
*read_package_entry( prs_struct
* ps
,
496 Eventlog_entry
* entry
)
499 Eventlog_entry
*ee_new
= NULL
;
501 ee_new
= PRS_ALLOC_MEM( ps
, Eventlog_entry
, 1 );
502 if ( ee_new
== NULL
) {
506 entry
->data_record
.sid_padding
=
508 ( ( entry
->data_record
.source_name_len
+
509 entry
->data_record
.computer_name_len
) % 4 ) ) % 4 );
510 entry
->data_record
.data_padding
=
512 ( ( entry
->data_record
.strings_len
+
513 entry
->data_record
.user_data_len
) % 4 ) ) % 4;
514 entry
->record
.length
= sizeof( Eventlog_record
);
515 entry
->record
.length
+= entry
->data_record
.source_name_len
;
516 entry
->record
.length
+= entry
->data_record
.computer_name_len
;
517 if ( entry
->record
.user_sid_length
== 0 ) {
518 /* Should not pad to a DWORD boundary for writing out the sid if there is
519 no SID, so just propagate the padding to pad the data */
520 entry
->data_record
.data_padding
+=
521 entry
->data_record
.sid_padding
;
522 entry
->data_record
.sid_padding
= 0;
525 ( "sid_padding is [%d].\n", entry
->data_record
.sid_padding
) );
527 ( "data_padding is [%d].\n",
528 entry
->data_record
.data_padding
) );
530 entry
->record
.length
+= entry
->data_record
.sid_padding
;
531 entry
->record
.length
+= entry
->record
.user_sid_length
;
532 entry
->record
.length
+= entry
->data_record
.strings_len
;
533 entry
->record
.length
+= entry
->data_record
.user_data_len
;
534 entry
->record
.length
+= entry
->data_record
.data_padding
;
535 /* need another copy of length at the end of the data */
536 entry
->record
.length
+= sizeof( entry
->record
.length
);
538 ( "entry->record.length is [%d].\n", entry
->record
.length
) );
540 PRS_ALLOC_MEM( ps
, uint8
,
541 entry
->record
.length
-
542 sizeof( Eventlog_record
) -
543 sizeof( entry
->record
.length
) );
544 if ( entry
->data
== NULL
) {
547 offset
= entry
->data
;
548 memcpy( offset
, &( entry
->data_record
.source_name
),
549 entry
->data_record
.source_name_len
);
550 offset
+= entry
->data_record
.source_name_len
;
551 memcpy( offset
, &( entry
->data_record
.computer_name
),
552 entry
->data_record
.computer_name_len
);
553 offset
+= entry
->data_record
.computer_name_len
;
554 /* SID needs to be DWORD-aligned */
555 offset
+= entry
->data_record
.sid_padding
;
556 entry
->record
.user_sid_offset
=
557 sizeof( Eventlog_record
) + ( offset
- entry
->data
);
558 memcpy( offset
, &( entry
->data_record
.sid
),
559 entry
->record
.user_sid_length
);
560 offset
+= entry
->record
.user_sid_length
;
561 /* Now do the strings */
562 entry
->record
.string_offset
=
563 sizeof( Eventlog_record
) + ( offset
- entry
->data
);
564 memcpy( offset
, &( entry
->data_record
.strings
),
565 entry
->data_record
.strings_len
);
566 offset
+= entry
->data_record
.strings_len
;
567 /* Now do the data */
568 entry
->record
.data_length
= entry
->data_record
.user_data_len
;
569 entry
->record
.data_offset
=
570 sizeof( Eventlog_record
) + ( offset
- entry
->data
);
571 memcpy( offset
, &( entry
->data_record
.user_data
),
572 entry
->data_record
.user_data_len
);
573 offset
+= entry
->data_record
.user_data_len
;
575 memcpy( &( ee_new
->record
), &entry
->record
,
576 sizeof( Eventlog_record
) );
577 memcpy( &( ee_new
->data_record
), &entry
->data_record
,
578 sizeof( Eventlog_data_record
) );
579 ee_new
->data
= entry
->data
;
584 /********************************************************************
585 ********************************************************************/
587 static bool add_record_to_resp( EVENTLOG_R_READ_EVENTLOG
* r_u
,
588 Eventlog_entry
* ee_new
)
590 Eventlog_entry
*insert_point
;
592 insert_point
= r_u
->entry
;
594 if ( NULL
== insert_point
) {
598 while ( ( NULL
!= insert_point
->next
) ) {
599 insert_point
= insert_point
->next
;
602 insert_point
->next
= ee_new
;
605 r_u
->num_bytes_in_resp
+= ee_new
->record
.length
;
610 /********************************************************************
611 _eventlog_OpenEventLogW
612 ********************************************************************/
614 NTSTATUS
_eventlog_OpenEventLogW(pipes_struct
*p
,
615 struct eventlog_OpenEventLogW
*r
)
617 const char *servername
= "";
618 const char *logname
= "";
622 if (r
->in
.servername
->string
) {
623 servername
= r
->in
.servername
->string
;
626 if (r
->in
.logname
->string
) {
627 logname
= r
->in
.logname
->string
;
630 DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n",
631 servername
, logname
));
633 /* according to MSDN, if the logfile cannot be found, we should
634 default to the "Application" log */
636 if ( !NT_STATUS_IS_OK( result
= elog_open( p
, logname
, r
->out
.handle
)) )
639 if ( !(info
= find_eventlog_info_by_hnd( p
, r
->out
.handle
)) ) {
640 DEBUG(0,("_eventlog_open_eventlog: eventlog (%s) opened but unable to find handle!\n",
642 elog_close( p
, r
->out
.handle
);
643 return NT_STATUS_INVALID_HANDLE
;
646 DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info
)));
648 sync_eventlog_params( info
);
649 prune_eventlog( ELOG_TDB_CTX(info
->etdb
) );
654 /********************************************************************
655 _eventlog_ClearEventLogW
656 This call still needs some work
657 ********************************************************************/
658 /** The windows client seems to be doing something funny with the file name
660 ClearEventLog(handle, "backup_file")
661 on the client side will result in the backup file name looking like this on the
663 \??\${CWD of client}\backup_file
664 If an absolute path gets specified, such as
665 ClearEventLog(handle, "C:\\temp\\backup_file")
666 then it is still mangled by the client into this:
667 \??\C:\temp\backup_file
668 when it is on the wire.
669 I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
670 would be added in given that the backup file gets written on the server side. */
672 NTSTATUS
_eventlog_ClearEventLogW(pipes_struct
*p
,
673 struct eventlog_ClearEventLogW
*r
)
675 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
676 const char *backup_file_name
= NULL
;
679 return NT_STATUS_INVALID_HANDLE
;
681 if (r
->in
.backupfile
&& r
->in
.backupfile
->string
) {
683 backup_file_name
= r
->in
.backupfile
->string
;
685 DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup "
686 "file name for log [%s].",
687 backup_file_name
, info
->logname
) );
690 /* check for WRITE access to the file */
692 if ( !(info
->access_granted
&SA_RIGHT_FILE_WRITE_DATA
) )
693 return NT_STATUS_ACCESS_DENIED
;
695 /* Force a close and reopen */
697 elog_close_tdb( info
->etdb
, True
);
699 info
->etdb
= elog_open_tdb( info
->logname
, True
);
703 return NT_STATUS_ACCESS_DENIED
;
708 /********************************************************************
709 ********************************************************************/
711 NTSTATUS
_eventlog_CloseEventLog( pipes_struct
* p
, struct eventlog_CloseEventLog
*r
)
713 return elog_close( p
, r
->in
.handle
);
716 /********************************************************************
717 ********************************************************************/
719 NTSTATUS
_eventlog_read_eventlog( pipes_struct
* p
,
720 EVENTLOG_Q_READ_EVENTLOG
* q_u
,
721 EVENTLOG_R_READ_EVENTLOG
* r_u
)
723 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, &q_u
->handle
);
724 Eventlog_entry
*entry
= NULL
, *ee_new
= NULL
;
725 uint32 num_records_read
= 0;
727 int bytes_left
, record_number
;
728 uint32 elog_read_type
, elog_read_dir
;
731 return NT_STATUS_INVALID_HANDLE
;
734 info
->flags
= q_u
->flags
;
735 ps
= &p
->out_data
.rdata
;
737 bytes_left
= q_u
->max_read_size
;
740 return NT_STATUS_ACCESS_DENIED
;
742 /* check for valid flags. Can't use the sequential and seek flags together */
744 elog_read_type
= q_u
->flags
& (EVENTLOG_SEQUENTIAL_READ
|EVENTLOG_SEEK_READ
);
745 elog_read_dir
= q_u
->flags
& (EVENTLOG_FORWARDS_READ
|EVENTLOG_BACKWARDS_READ
);
747 if ( elog_read_type
== (EVENTLOG_SEQUENTIAL_READ
|EVENTLOG_SEEK_READ
)
748 || elog_read_dir
== (EVENTLOG_FORWARDS_READ
|EVENTLOG_BACKWARDS_READ
) )
750 DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u
->flags
));
751 return NT_STATUS_INVALID_PARAMETER
;
754 /* a sequential read should ignore the offset */
756 if ( elog_read_type
& EVENTLOG_SEQUENTIAL_READ
)
757 record_number
= info
->current_record
;
759 record_number
= q_u
->offset
;
761 while ( bytes_left
> 0 ) {
763 /* assume that when the record fetch fails, that we are done */
765 entry
= get_eventlog_record (ps
, ELOG_TDB_CTX(info
->etdb
), record_number
);
770 DEBUG( 8, ( "Retrieved record %d\n", record_number
) );
772 /* Now see if there is enough room to add */
774 if ( !(ee_new
= read_package_entry( ps
, entry
)) )
775 return NT_STATUS_NO_MEMORY
;
777 if ( r_u
->num_bytes_in_resp
+ ee_new
->record
.length
> q_u
->max_read_size
) {
778 r_u
->bytes_in_next_record
= ee_new
->record
.length
;
780 /* response would be too big to fit in client-size buffer */
786 add_record_to_resp( r_u
, ee_new
);
787 bytes_left
-= ee_new
->record
.length
;
789 num_records_read
= r_u
->num_records
- num_records_read
;
791 DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total "
792 "of [%d] records using [%d] bytes out of a max of [%d].\n",
793 num_records_read
, r_u
->num_records
,
794 r_u
->num_bytes_in_resp
,
795 q_u
->max_read_size
) );
797 if ( info
->flags
& EVENTLOG_FORWARDS_READ
)
802 /* update the eventlog record pointer */
804 info
->current_record
= record_number
;
807 /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to
808 say when there are no more records */
810 return (num_records_read
? NT_STATUS_OK
: NT_STATUS_BUFFER_TOO_SMALL
);
813 /********************************************************************
814 _eventlog_GetOldestRecord
815 ********************************************************************/
817 NTSTATUS
_eventlog_GetOldestRecord(pipes_struct
*p
,
818 struct eventlog_GetOldestRecord
*r
)
820 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
823 return NT_STATUS_INVALID_HANDLE
;
826 if ( !( get_oldest_entry_hook( info
) ) )
827 return NT_STATUS_ACCESS_DENIED
;
829 *r
->out
.oldest_entry
= info
->oldest_entry
;
834 /********************************************************************
835 _eventlog_GetNumRecords
836 ********************************************************************/
838 NTSTATUS
_eventlog_GetNumRecords(pipes_struct
*p
,
839 struct eventlog_GetNumRecords
*r
)
841 EVENTLOG_INFO
*info
= find_eventlog_info_by_hnd( p
, r
->in
.handle
);
844 return NT_STATUS_INVALID_HANDLE
;
847 if ( !( get_num_records_hook( info
) ) )
848 return NT_STATUS_ACCESS_DENIED
;
850 *r
->out
.number
= info
->num_records
;
855 NTSTATUS
_eventlog_BackupEventLogW(pipes_struct
*p
, struct eventlog_BackupEventLogW
*r
)
857 p
->rng_fault_state
= True
;
858 return NT_STATUS_NOT_IMPLEMENTED
;
861 NTSTATUS
_eventlog_DeregisterEventSource(pipes_struct
*p
, struct eventlog_DeregisterEventSource
*r
)
863 p
->rng_fault_state
= True
;
864 return NT_STATUS_NOT_IMPLEMENTED
;
867 NTSTATUS
_eventlog_ChangeNotify(pipes_struct
*p
, struct eventlog_ChangeNotify
*r
)
869 p
->rng_fault_state
= True
;
870 return NT_STATUS_NOT_IMPLEMENTED
;
873 NTSTATUS
_eventlog_RegisterEventSourceW(pipes_struct
*p
, struct eventlog_RegisterEventSourceW
*r
)
875 p
->rng_fault_state
= True
;
876 return NT_STATUS_NOT_IMPLEMENTED
;
879 NTSTATUS
_eventlog_OpenBackupEventLogW(pipes_struct
*p
, struct eventlog_OpenBackupEventLogW
*r
)
881 p
->rng_fault_state
= True
;
882 return NT_STATUS_NOT_IMPLEMENTED
;
885 NTSTATUS
_eventlog_ReadEventLogW(pipes_struct
*p
, struct eventlog_ReadEventLogW
*r
)
887 p
->rng_fault_state
= True
;
888 return NT_STATUS_NOT_IMPLEMENTED
;
891 NTSTATUS
_eventlog_ReportEventW(pipes_struct
*p
, struct eventlog_ReportEventW
*r
)
893 p
->rng_fault_state
= True
;
894 return NT_STATUS_NOT_IMPLEMENTED
;
897 NTSTATUS
_eventlog_ClearEventLogA(pipes_struct
*p
, struct eventlog_ClearEventLogA
*r
)
899 p
->rng_fault_state
= True
;
900 return NT_STATUS_NOT_IMPLEMENTED
;
903 NTSTATUS
_eventlog_BackupEventLogA(pipes_struct
*p
, struct eventlog_BackupEventLogA
*r
)
905 p
->rng_fault_state
= True
;
906 return NT_STATUS_NOT_IMPLEMENTED
;
909 NTSTATUS
_eventlog_OpenEventLogA(pipes_struct
*p
, struct eventlog_OpenEventLogA
*r
)
911 p
->rng_fault_state
= True
;
912 return NT_STATUS_NOT_IMPLEMENTED
;
915 NTSTATUS
_eventlog_RegisterEventSourceA(pipes_struct
*p
, struct eventlog_RegisterEventSourceA
*r
)
917 p
->rng_fault_state
= True
;
918 return NT_STATUS_NOT_IMPLEMENTED
;
921 NTSTATUS
_eventlog_OpenBackupEventLogA(pipes_struct
*p
, struct eventlog_OpenBackupEventLogA
*r
)
923 p
->rng_fault_state
= True
;
924 return NT_STATUS_NOT_IMPLEMENTED
;
927 NTSTATUS
_eventlog_ReadEventLogA(pipes_struct
*p
, struct eventlog_ReadEventLogA
*r
)
929 p
->rng_fault_state
= True
;
930 return NT_STATUS_NOT_IMPLEMENTED
;
933 NTSTATUS
_eventlog_ReportEventA(pipes_struct
*p
, struct eventlog_ReportEventA
*r
)
935 p
->rng_fault_state
= True
;
936 return NT_STATUS_NOT_IMPLEMENTED
;
939 NTSTATUS
_eventlog_RegisterClusterSvc(pipes_struct
*p
, struct eventlog_RegisterClusterSvc
*r
)
941 p
->rng_fault_state
= True
;
942 return NT_STATUS_NOT_IMPLEMENTED
;
945 NTSTATUS
_eventlog_DeregisterClusterSvc(pipes_struct
*p
, struct eventlog_DeregisterClusterSvc
*r
)
947 p
->rng_fault_state
= True
;
948 return NT_STATUS_NOT_IMPLEMENTED
;
951 NTSTATUS
_eventlog_WriteClusterEvents(pipes_struct
*p
, struct eventlog_WriteClusterEvents
*r
)
953 p
->rng_fault_state
= True
;
954 return NT_STATUS_NOT_IMPLEMENTED
;
957 NTSTATUS
_eventlog_GetLogIntormation(pipes_struct
*p
, struct eventlog_GetLogIntormation
*r
)
959 p
->rng_fault_state
= True
;
960 return NT_STATUS_NOT_IMPLEMENTED
;
963 NTSTATUS
_eventlog_FlushEventLog(pipes_struct
*p
, struct eventlog_FlushEventLog
*r
)
965 p
->rng_fault_state
= True
;
966 return NT_STATUS_NOT_IMPLEMENTED
;