diff options
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_eventlog_lib.c | 107 | ||||
-rw-r--r-- | source3/rpc_server/srv_eventlog_nt.c | 64 |
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 ) ); |