summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_eventlog_lib.c107
-rw-r--r--source3/rpc_server/srv_eventlog_nt.c64
2 files changed, 94 insertions, 77 deletions
diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c
index b21c2a2529..ec5edf2f34 100644
--- a/source3/rpc_server/srv_eventlog_lib.c
+++ b/source3/rpc_server/srv_eventlog_lib.c
@@ -24,14 +24,7 @@
/* maintain a list of open eventlog tdbs with reference counts */
-struct elog_open_tdb {
- struct elog_open_tdb *prev, *next;
- char *name;
- TDB_CONTEXT *tdb;
- int ref_count;
-};
-
-static struct elog_open_tdb *open_elog_list;
+static ELOG_TDB *open_elog_list;
/********************************************************************
Init an Eventlog TDB, and return it. If null, something bad
@@ -317,14 +310,14 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
/*******************************************************************
*******************************************************************/
-TDB_CONTEXT *elog_open_tdb( char *logname )
+ELOG_TDB *elog_open_tdb( char *logname, BOOL force_clear )
{
- TDB_CONTEXT *tdb;
+ TDB_CONTEXT *tdb = NULL;
uint32 vers_id;
- struct elog_open_tdb *ptr;
+ ELOG_TDB *ptr;
char *tdbfilename;
pstring tdbpath;
- struct elog_open_tdb *tdb_node;
+ ELOG_TDB *tdb_node = NULL;
char *eventlogdir;
/* first see if we have an open context */
@@ -332,7 +325,19 @@ TDB_CONTEXT *elog_open_tdb( char *logname )
for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
if ( strequal( ptr->name, logname ) ) {
ptr->ref_count++;
- return ptr->tdb;
+
+ /* trick to alow clearing of the eventlog tdb.
+ The force_clear flag should imply that someone
+ has done a force close. So make sure the tdb
+ is NULL. If this is a normal open, then just
+ return the existing reference */
+
+ if ( force_clear ) {
+ SMB_ASSERT( ptr->tdb == NULL );
+ break;
+ }
+ else
+ return ptr;
}
}
@@ -348,27 +353,41 @@ TDB_CONTEXT *elog_open_tdb( char *logname )
pstrcpy( tdbpath, tdbfilename );
SAFE_FREE( tdbfilename );
- DEBUG(7,("elog_open_tdb: Opening %s...\n", tdbpath ));
+ DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n",
+ tdbpath, force_clear?"True":"False" ));
+
+ /* the tdb wasn't already open or this is a forced clear open */
- tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );
- if ( tdb ) {
- vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
+ if ( !force_clear ) {
- if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
- DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
- vers_id, tdbpath));
- tdb_close( tdb );
- tdb = elog_init_tdb( tdbpath );
+ tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 );
+ if ( tdb ) {
+ vers_id = tdb_fetch_int32( tdb, EVT_VERSION );
+
+ if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
+ DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
+ vers_id, tdbpath));
+ tdb_close( tdb );
+ tdb = elog_init_tdb( tdbpath );
+ }
}
}
- else {
+
+ if ( !tdb )
tdb = elog_init_tdb( tdbpath );
- }
/* if we got a valid context, then add it to the list */
if ( tdb ) {
- if ( !(tdb_node = TALLOC_ZERO_P( NULL, struct elog_open_tdb )) ) {
+ /* on a forced clear, just reset the tdb context if we already
+ have an open entry in the list */
+
+ if ( ptr ) {
+ ptr->tdb = tdb;
+ return ptr;
+ }
+
+ if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) {
DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
tdb_close( tdb );
return NULL;
@@ -381,42 +400,34 @@ TDB_CONTEXT *elog_open_tdb( char *logname )
DLIST_ADD( open_elog_list, tdb_node );
}
- return tdb;
+ return tdb_node;
}
/*******************************************************************
Wrapper to handle reference counts to the tdb
*******************************************************************/
-int elog_close_tdb( TDB_CONTEXT *tdb )
+int elog_close_tdb( ELOG_TDB *etdb, BOOL force_close )
{
- struct elog_open_tdb *ptr;
+ TDB_CONTEXT *tdb;
- if ( !tdb )
+ if ( !etdb )
return 0;
- /* See if we can just decrement the ref_count.
- Just compare pointer values (not names ) */
-
- for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
- if ( tdb == ptr->tdb ) {
- ptr->ref_count--;
- break;
- }
- }
+ etdb->ref_count--;
- /* if we have a NULL pointer; it means we are trying to
- close a tdb not in the list of open eventlogs */
-
- SMB_ASSERT( ptr != NULL );
- if ( !ptr )
+ SMB_ASSERT( etdb->ref_count >= 0 );
+
+ if ( etdb->ref_count == 0 ) {
+ tdb = etdb->tdb;
+ DLIST_REMOVE( open_elog_list, etdb );
+ TALLOC_FREE( etdb );
return tdb_close( tdb );
+ }
- SMB_ASSERT( ptr->ref_count >= 0 );
-
- if ( ptr->ref_count == 0 ) {
- DLIST_REMOVE( open_elog_list, ptr );
- TALLOC_FREE( ptr );
+ if ( force_close ) {
+ tdb = etdb->tdb;
+ etdb->tdb = NULL;
return tdb_close( tdb );
}
diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c
index 0f0b73029a..05feb51f95 100644
--- a/source3/rpc_server/srv_eventlog_nt.c
+++ b/source3/rpc_server/srv_eventlog_nt.c
@@ -27,7 +27,7 @@
typedef struct {
char *logname;
- TDB_CONTEXT *tdb;
+ ELOG_TDB *etdb;
uint32 current_record;
uint32 num_records;
uint32 oldest_entry;
@@ -42,8 +42,8 @@ static void free_eventlog_info( void *ptr )
{
EVENTLOG_INFO *elog = (EVENTLOG_INFO *)ptr;
- if ( elog->tdb )
- elog_close_tdb( elog->tdb );
+ if ( elog->etdb )
+ elog_close_tdb( elog->etdb, False );
TALLOC_FREE( elog );
}
@@ -139,17 +139,17 @@ static BOOL get_num_records_hook( EVENTLOG_INFO * info )
int next_record;
int oldest_record;
- if ( !info->tdb ) {
+ if ( !info->etdb ) {
DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
return False;
}
/* lock the tdb since we have to get 2 records */
- tdb_lock_bystring( info->tdb, EVT_NEXT_RECORD, 1 );
- next_record = tdb_fetch_int32( info->tdb, EVT_NEXT_RECORD);
- oldest_record = tdb_fetch_int32( info->tdb, EVT_OLDEST_ENTRY);
- tdb_unlock_bystring( info->tdb, EVT_NEXT_RECORD);
+ tdb_lock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
+ next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
+ oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
+ tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
DEBUG( 8,
( "Oldest Record %d; Next Record %d\n", oldest_record,
@@ -193,10 +193,10 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
in a single process */
become_root();
- elog->tdb = elog_open_tdb( elog->logname );
+ elog->etdb = elog_open_tdb( elog->logname, False );
unbecome_root();
- if ( !elog->tdb ) {
+ if ( !elog->etdb ) {
/* according to MSDN, if the logfile cannot be found, we should
default to the "Application" log */
@@ -213,11 +213,11 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
}
become_root();
- elog->tdb = elog_open_tdb( elog->logname );
+ elog->etdb = elog_open_tdb( elog->logname, False );
unbecome_root();
}
- if ( !elog->tdb ) {
+ if ( !elog->etdb ) {
TALLOC_FREE( elog );
return NT_STATUS_ACCESS_DENIED; /* ??? */
}
@@ -226,7 +226,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
/* now do the access check. Close the tdb if we fail here */
if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
- elog_close_tdb( elog->tdb );
+ elog_close_tdb( elog->etdb, False );
TALLOC_FREE( elog );
return NT_STATUS_ACCESS_DENIED;
}
@@ -268,12 +268,12 @@ static NTSTATUS elog_close( pipes_struct *p, POLICY_HND *hnd )
static int elog_size( EVENTLOG_INFO *info )
{
- if ( !info || !info->tdb ) {
+ if ( !info || !info->etdb ) {
DEBUG(0,("elog_size: Invalid info* structure!\n"));
return 0;
}
- return elog_tdb_size( info->tdb, NULL, NULL );
+ return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
}
/********************************************************************
@@ -397,7 +397,7 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info )
DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
- if ( !info->tdb ) {
+ if ( !info->etdb ) {
DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
return False;
}
@@ -440,8 +440,8 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info )
regkey_close_internal( keyinfo );
- tdb_store_int32( info->tdb, EVT_MAXSIZE, uiMaxSize );
- tdb_store_int32( info->tdb, EVT_RETENTION, uiRetention );
+ tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
+ tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
return True;
}
@@ -610,7 +610,7 @@ NTSTATUS _eventlog_open_eventlog( pipes_struct * p,
DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info )));
sync_eventlog_params( info );
- prune_eventlog( info->tdb );
+ prune_eventlog( ELOG_TDB_CTX(info->etdb) );
return NT_STATUS_OK;
}
@@ -634,20 +634,26 @@ NTSTATUS _eventlog_clear_eventlog( pipes_struct * p,
rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer,
sizeof( backup_file_name ),
q_u->backupfile.string->uni_str_len * 2, 0 );
+
+ DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup "
+ "file name for log [%s].",
+ backup_file_name, info->logname ) );
}
- DEBUG( 8,
- ( "_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
- backup_file_name, info->logname ) );
+ /* check for WRITE access to the file */
+
+ if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) )
+ return NT_STATUS_ACCESS_DENIED;
-#if 0
- /* close the current one, reinit */
+ /* Force a close and reopen */
- tdb_close( info->tdb );
+ elog_close_tdb( info->etdb, True );
+ become_root();
+ info->etdb = elog_open_tdb( info->logname, True );
+ unbecome_root();
- if ( !(info->tdb = elog_init_tdb( ttdb[i].tdbfname )) )
+ if ( !info->etdb )
return NT_STATUS_ACCESS_DENIED;
-#endif
return NT_STATUS_OK;
}
@@ -680,7 +686,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
bytes_left = q_u->max_read_size;
- if ( !info->tdb )
+ if ( !info->etdb )
return NT_STATUS_ACCESS_DENIED;
/* check for valid flags. Can't use the sequential and seek flags together */
@@ -706,7 +712,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
/* assume that when the record fetch fails, that we are done */
- if ( !get_eventlog_record ( ps, info->tdb, record_number, &entry ) )
+ if ( !get_eventlog_record ( ps, ELOG_TDB_CTX(info->etdb), record_number, &entry ) )
break;
DEBUG( 8, ( "Retrieved record %d\n", record_number ) );