r10781: merging eventlog and svcctl code from trunk
authorGerald Carter <jerry@samba.org>
Thu, 6 Oct 2005 17:48:03 +0000 (17:48 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:04:53 +0000 (11:04 -0500)
(This used to be commit f10aa9fb84bfac4f1a22b74d63999668700ffaac)

17 files changed:
source3/Makefile.in
source3/include/rpc_eventlog.h
source3/include/rpc_misc.h
source3/include/rpc_svcctl.h
source3/param/loadparm.c
source3/registry/reg_eventlog.c
source3/registry/reg_frontend.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_ntsvcs.c
source3/rpc_server/srv_eventlog_lib.c [new file with mode: 0644]
source3/rpc_server/srv_eventlog_nt.c
source3/rpc_server/srv_ntsvcs_nt.c
source3/rpc_server/srv_reg_nt.c
source3/rpc_server/srv_svcctl_nt.c
source3/services/services_db.c
source3/services/svc_rcinit.c
source3/services/svc_wins.c [new file with mode: 0644]

index 07c348bd84e598f34177c145737a7914d7489550..4310f51bd545c5c4ffde323b55d526b5fd8cc9ad 100644 (file)
@@ -283,7 +283,8 @@ RPC_WKS_OBJ =  rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
 
 RPC_SVCCTL_OBJ =  rpc_server/srv_svcctl.o rpc_server/srv_svcctl_nt.o \
                   services/svc_spoolss.o services/svc_rcinit.o services/services_db.o \
-                  services/svc_netlogon.o services/svc_winreg.o
+                  services/svc_netlogon.o services/svc_winreg.o \
+                  services/svc_wins.o
 
 RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs.o rpc_server/srv_ntsvcs_nt.o
 
@@ -291,7 +292,7 @@ RPC_DFS_OBJ =  rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o
 
 RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o 
 
-RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog.o rpc_server/srv_eventlog_nt.o
+RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog.o rpc_server/srv_eventlog_nt.o rpc_server/srv_eventlog_lib.o
 
 RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \
                rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
index 7ce1199b213ac9577887400e50478000f6bebe20..9f968fb54e1b395e9b35ed002c560de7456bc069 100644 (file)
 #define EVENTLOG_AUDIT_SUCCESS        0x0008
 #define EVENTLOG_AUDIT_FAILURE        0x0010
 
+/* Defines for TDB keys */
+#define  VN_oldest_entry  "INFO/oldest_entry"
+#define  VN_next_record   "INFO/next_record"
+#define  VN_version       "INFO/version"
+#define  VN_maxsize       "INFO/maxsize"
+#define  VN_retention     "INFO/retention"
+
+#define  EVENTLOG_DATABASE_VERSION_V1    1
 
 /***********************************/
 
index e5d91c1b6300750911fbb895981f7be3798e18ef..091ba3395e027ba4ab668f8071bae9289a57be44 100644 (file)
@@ -27,7 +27,7 @@
 #define SMB_RPC_INTERFACE_VERSION 1
 #define PRS_POINTER_CAST BOOL (*)(const char*, prs_struct*, int, void*)
 
-enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 };
+enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3, UNI_STR_DBLTERMINATE = 4 };
 
 
 
index 443a6588a661ab4a01bc79454a60765017810393..f5ad2afa1c7f9fafb51374a2685be84f31facf84 100644 (file)
@@ -175,23 +175,6 @@ typedef struct {
         SC_ACTION *actions;
 } SERVICE_FAILURE_ACTIONS;
 
-typedef struct Service_info_struct {
-       uint32  type;           /* should be SVC_HANDLE_IS_SERVICE */
-       pstring servicename;    /* the name of the service */
-       pstring servicetype;    /* internal or external */
-       pstring filename;       /* what file name we can find this in, 
-                                  as well as the "index" for what the 
-                                  service name is */
-       pstring provides;
-       pstring dependencies;
-       pstring shouldstart;
-       pstring shouldstop;
-       pstring requiredstart;
-       pstring requiredstop;
-       pstring shortdescription;
-       pstring description;
-} Service_info;
-
 /* 
  * dispatch table of functions to handle the =ServiceControl API
  */ 
index 0a4f0556ae147acb11de5f37d4f23471c21ec581..126d70939c009516dddd279442fe5372d9798279 100644 (file)
@@ -183,13 +183,6 @@ typedef struct
        char *szAddShareCommand;
        char *szChangeShareCommand;
        char *szDeleteShareCommand;
-        char *szEventLogOpenCommand;
-        char *szEventLogReadCommand;
-        char *szEventLogClearCommand;
-        char *szEventLogNumRecordsCommand;
-        char *szEventLogOldestRecordCommand;
-       char *szEventLogCloseCommand;
-        char *szEventLogControlCommand;
         char **szEventLogs;
        char *szGuestaccount;
        char *szManglingMethod;
@@ -608,7 +601,6 @@ static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr
 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
 static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
-static BOOL handle_eventlog( int snum, const char *pszParmValue, char **ptr);
 
 static void set_server_role(void);
 static void set_default_server_announce_type(void);
@@ -1154,13 +1146,6 @@ static struct parm_struct parm_table[] = {
        {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED}, 
 
        {N_("EventLog Options"), P_SEP, P_SEPARATOR}, 
-       {"eventlog open command", P_STRING, P_GLOBAL, &Globals.szEventLogOpenCommand, handle_eventlog, NULL, FLAG_ADVANCED},
-       {"eventlog read command", P_STRING, P_GLOBAL, &Globals.szEventLogReadCommand, handle_eventlog, NULL, FLAG_ADVANCED}, 
-       {"eventlog clear command", P_STRING, P_GLOBAL, &Globals.szEventLogClearCommand, handle_eventlog, NULL, FLAG_ADVANCED},
-       {"eventlog num records command", P_STRING, P_GLOBAL, &Globals.szEventLogNumRecordsCommand, handle_eventlog, NULL, FLAG_ADVANCED},
-       {"eventlog oldest record command", P_STRING, P_GLOBAL, &Globals.szEventLogOldestRecordCommand, handle_eventlog, NULL, FLAG_ADVANCED},
-       {"eventlog close command", P_STRING, P_GLOBAL, &Globals.szEventLogCloseCommand, handle_eventlog, NULL, FLAG_ADVANCED},
-       {"eventlog control command", P_STRING, P_GLOBAL, &Globals.szEventLogControlCommand, handle_eventlog, NULL, FLAG_ADVANCED},
        {"eventlog list",  P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
        
        {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, 
@@ -1581,14 +1566,6 @@ static void init_globals(void)
        string_set(&Globals.szCupsServer, "");
        string_set(&Globals.szIPrintServer, "");
 
-       string_set(&Globals.szEventLogOpenCommand, "");
-       string_set(&Globals.szEventLogReadCommand, "");
-       string_set(&Globals.szEventLogClearCommand, "");
-       string_set(&Globals.szEventLogNumRecordsCommand, "");
-       string_set(&Globals.szEventLogOldestRecordCommand, "");
-       string_set(&Globals.szEventLogCloseCommand, "");
-       string_set(&Globals.szEventLogControlCommand, "");
-
        Globals.winbind_cache_time = 300;       /* 5 minutes */
        Globals.bWinbindEnumUsers = True;
        Globals.bWinbindEnumGroups = True;
@@ -1806,14 +1783,6 @@ FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
 
-FN_GLOBAL_STRING(lp_eventlog_open_cmd, &Globals.szEventLogOpenCommand)
-FN_GLOBAL_STRING(lp_eventlog_read_cmd, &Globals.szEventLogReadCommand)
-FN_GLOBAL_STRING(lp_eventlog_clear_cmd, &Globals.szEventLogClearCommand)
-FN_GLOBAL_STRING(lp_eventlog_num_records_cmd, &Globals.szEventLogNumRecordsCommand)
-FN_GLOBAL_STRING(lp_eventlog_oldest_record_cmd, &Globals.szEventLogOldestRecordCommand)
-FN_GLOBAL_STRING(lp_eventlog_close_cmd, &Globals.szEventLogCloseCommand)
-FN_GLOBAL_STRING(lp_eventlog_control_cmd, &Globals.szEventLogControlCommand)
-
 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
 
 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
@@ -2908,11 +2877,7 @@ static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
        return True;
 }
 
-static BOOL handle_eventlog(int snum, const char *pszParmValue, char **ptr)
-{
-       string_set(ptr, pszParmValue);
-       return True;
-}
+
 
 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
 {
index bed9e1d59aec33ac8b4be8a801d29f81e8571a8c..204c4c6e1c21ef3a8da5722fc79c84b282fd51a9 100644 (file)
@@ -2,6 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  Virtual Windows Registry Layer
  *  Copyright (C) Marcin Krzysztof Porwit    2005,
+ *  Copyright (C) Brian Moran                2005.
  *  Copyright (C) Gerald (Jerry) Carter      2005.
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 #include "includes.h"
 
 
 /**********************************************************************
- Enumerate registry subkey names given a registry path.  
+ for an eventlog, add in the default values
 *********************************************************************/
 
-static int elog_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
+BOOL eventlog_init_keys( void )
 {
-       const char    **elogs = lp_eventlog_list();
-       char          *path;
-       int           i;
-    
-       path = reg_remaining_path( key + strlen(KEY_EVENTLOG) );
-       
-       DEBUG(10,("elog_fetch_keys: entire key => [%s], subkey => [%s]\n", 
-               key, path));
-    
-       if ( !path ) { 
-               
-               if ( !elogs || !*elogs ) 
-                       return 0;
-
-               DEBUG(10,("elog_fetch_keys: Adding eventlog subkeys from smb.conf\n")); 
-               
-               for ( i=0; elogs[i]; i++ ) 
-                       regsubkey_ctr_addkey( subkeys, elogs[i] );
-
-               return regsubkey_ctr_numkeys( subkeys );
-       } 
-       
-       /* if we get <logname>/<logname> then we don't add anymore */
-
-       if ( strchr( path, '\\' ) ) {
-               DEBUG(10,("elog_fetch_keys: Not adding subkey to %s\n",path));  
-               return 0;
-       }
-
-       /* add in a subkey with the same name as the eventlog... */
-
-       DEBUG(10,("elog_fetch_keys: Looking to add eventlog subkey to %s\n",path));     
-
-       /* look for a match */
-
-       if ( !elogs )
-               return -1; 
-
-       for ( i=0; elogs[i]; i++ ) { 
-               /* just verify that the keyname is a valid log name */
-               if ( strequal( path, elogs[i] ) )
-                       return 0;
-       }
-       
-       return -1;
-}
-
-/**********************************************************************
- Enumerate registry values given a registry path.  
- Caller is responsible for freeing memory 
-*********************************************************************/
-
-static int elog_fetch_values( const char *key, REGVAL_CTR *values )
-{
-       char    *path;
-       uint32  uiDisplayNameId, uiMaxSize, uiRetention;
-       char    *base, *new_path;
+       /* Find all of the eventlogs, add keys for each of them */
+       const char **elogs = lp_eventlog_list(  );
+       pstring evtlogpath;
+       REGSUBKEY_CTR *subkeys;
+       REGVAL_CTR *values;
+       uint32 uiDisplayNameId;
+       uint32 uiMaxSize;
+       uint32 uiRetention;
+       uint32 uiCategoryCount;
        UNISTR2 data;
-       
-       DEBUG(10,("elog_fetch_values: key=>[%s]\n", key));
-       
-       path = reg_remaining_path( key + strlen(KEY_EVENTLOG) );
-       
-       /* check to see if we are dealing with the top level key */
-       
-       if ( !path ) 
-               return regdb_fetch_values( KEY_EVENTLOG, values );
-               
-       /* deal with a log name */
-    
-       reg_split_path( path, &base, &new_path );
-       
-       /* MaxSize is limited to 0xFFFF0000 (UINT_MAX - USHRT_MAX) as per MSDN documentation */
-       
-    
-       if ( !new_path ) {
-               
-               /* try to fetch from the registry */
-               
-               regdb_fetch_values( key, values );
-
-               /* just verify one of the important keys.  If this 
-                  fails, then assume the values have not been initialized */
-               
-               if ( regval_ctr_getvalue( values, "Retention" ) )
-                       return regval_ctr_numvals( values );    
-
-               /* hard code some initial values */
-                               
-               uiDisplayNameId = 0x00000100;
-               uiMaxSize       = 0x00080000;   
-               uiRetention     = 0x93A80;
-               
-               regval_ctr_addvalue( values, "MaxSize", REG_DWORD, (char*)&uiMaxSize, sizeof(uint32));
-               regval_ctr_addvalue( values, "Retention", REG_DWORD, (char *)&uiRetention, sizeof(uint32));
-               
-               init_unistr2( &data, base, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( values, "PrimaryModule", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-       
-               init_unistr2( &data, base, UNI_STR_TERMINATE);
-               regval_ctr_addvalue( values, "Sources", REG_MULTI_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-               
-               /* store them for later updates.  Complain if this fails but continue on */
-               
-               if ( !regdb_store_values( key, values ) ) {
-                       DEBUG(0,("elog_fetch_values: Failed to store initial values for log [%s]\n",
-                               base ));
+
+       while ( elogs && *elogs ) {
+               if ( !( subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR ) ) ) {
+                       DEBUG( 0, ( "talloc() failure!\n" ) );
+                       return False;
                }
-       
-               return regval_ctr_numvals( values );    
-       } 
-
-#if 0
-       /* hmmm....what to do here?  A subkey underneath the log name ? */
-
-       uiDisplayNameId = 0x07;
-       regval_ctr_addvalue( values, "CategoryCount",    REG_DWORD, (char*)&uiDisplayNameId,       sizeof(uint32) ); 
-       
-       init_unistr2( &data, "%SystemRoot%\\system32\\eventlog.dll", UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "CategoryMessageFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-#endif
-       
-       return regval_ctr_numvals( values );
-}
+               regdb_fetch_keys( KEY_EVENTLOG, subkeys );
+               regsubkey_ctr_addkey( subkeys, *elogs );
+               if ( !regdb_store_keys( KEY_EVENTLOG, subkeys ) )
+                       return False;
+               TALLOC_FREE( subkeys );
+
+               /* add in the key of form KEY_EVENTLOG/Application */
+               DEBUG( 5,
+                      ( "Adding key of [%s] to path of [%s]\n", *elogs,
+                        KEY_EVENTLOG ) );
+
+               slprintf( evtlogpath, sizeof( evtlogpath ) - 1, "%s\\%s",
+                         KEY_EVENTLOG, *elogs );
+               /* add in the key of form KEY_EVENTLOG/Application/Application */
+               DEBUG( 5,
+                      ( "Adding key of [%s] to path of [%s]\n", *elogs,
+                        evtlogpath ) );
+               if ( !( subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR ) ) ) {
+                       DEBUG( 0, ( "talloc() failure!\n" ) );
+                       return False;
+               }
+               regdb_fetch_keys( evtlogpath, subkeys );
+               regsubkey_ctr_addkey( subkeys, *elogs );
 
-/**********************************************************************
-*********************************************************************/
+               if ( !regdb_store_keys( evtlogpath, subkeys ) )
+                       return False;
+               TALLOC_FREE( subkeys );
 
-static BOOL elog_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
-{
-       /* cannot create any subkeys here */
-       
-       return False;
-}
+               /* now add the values to the KEY_EVENTLOG/Application form key */
+               if ( !( values = TALLOC_ZERO_P( NULL, REGVAL_CTR ) ) ) {
+                       DEBUG( 0, ( "talloc() failure!\n" ) );
+                       return False;
+               }
+               DEBUG( 5,
+                      ( "Storing values to eventlog path of [%s]\n",
+                        evtlogpath ) );
+               regdb_fetch_values( evtlogpath, values );
+
+               if ( !regval_ctr_key_exists( values, "MaxSize" ) ) {
+                       /* assume we have none, add them all */
+
+                       /* hard code some initial values */
+
+                       uiDisplayNameId = 0x00000100;
+                       uiMaxSize = 0x00080000;
+                       uiRetention = 0x93A80;
+
+                       regval_ctr_addvalue( values, "MaxSize", REG_DWORD,
+                                            ( char * ) &uiMaxSize,
+                                            sizeof( uint32 ) );
+                       regval_ctr_addvalue( values, "Retention", REG_DWORD,
+                                            ( char * ) &uiRetention,
+                                            sizeof( uint32 ) );
+                       init_unistr2( &data, *elogs, UNI_STR_TERMINATE );
+                       regval_ctr_addvalue( values, "PrimaryModule", REG_SZ,
+                                            ( char * ) data.buffer,
+                                            data.uni_str_len *
+                                            sizeof( uint16 ) );
+                       init_unistr2( &data, *elogs, UNI_STR_TERMINATE );
+
+                       regval_ctr_addvalue( values, "Sources", REG_MULTI_SZ,
+                                            ( char * ) data.buffer,
+                                            data.uni_str_len *
+                                            sizeof( uint16 ) );
+                       regdb_store_values( evtlogpath, values );
 
-/**********************************************************************
- Allow storing of particular values related to eventlog operation. 
-*********************************************************************/
+               }
 
-static BOOL elog_store_value( const char *key, REGVAL_CTR *values )
-{
-       /* the client had to have a valid handle to get here 
-          so just hand off to the registry tdb */
-       
-       return regdb_store_values( key, values );
-}
+               TALLOC_FREE( values );
 
-/******************************************************************** 
- Table of function pointers for accessing eventlog data
- *******************************************************************/
-REGISTRY_OPS eventlog_ops = {
-       elog_fetch_keys,
-       elog_fetch_values,
-       elog_store_keys,
-       elog_store_value,
-       NULL
-};
+               /* now do the values under KEY_EVENTLOG/Application/Application */
+               slprintf( evtlogpath, sizeof( evtlogpath ) - 1, "%s\\%s\\%s",
+                         KEY_EVENTLOG, *elogs, *elogs );
+               if ( !( values = TALLOC_ZERO_P( NULL, REGVAL_CTR ) ) ) {
+                       DEBUG( 0, ( "talloc() failure!\n" ) );
+                       return False;
+               }
+               DEBUG( 5,
+                      ( "Storing values to eventlog path of [%s]\n",
+                        evtlogpath ) );
+               regdb_fetch_values( evtlogpath, values );
+               if ( !regval_ctr_key_exists( values, "CategoryCount" ) ) {
+
+                       /* hard code some initial values */
+
+                       uiCategoryCount = 0x00000007;
+                       regval_ctr_addvalue( values, "CategoryCount",
+                                            REG_DWORD,
+                                            ( char * ) &uiCategoryCount,
+                                            sizeof( uint32 ) );
+                       init_unistr2( &data,
+                                     "%SystemRoot%\\system32\\eventlog.dll",
+                                     UNI_STR_TERMINATE );
+
+                       regval_ctr_addvalue( values, "CategoryMessageFile",
+                                            REG_EXPAND_SZ,
+                                            ( char * ) data.buffer,
+                                            data.uni_str_len *
+                                            sizeof( uint16 ) );
+                       regdb_store_values( evtlogpath, values );
+               }
+               TALLOC_FREE( values );
+               elogs++;
+       }
+       return True;
+}
index f41c5885bc4d7bdc8710793790ae8ab4e3336c93..f5284e9e88f2904c6ebffafe68d76239a90f3f72 100644 (file)
@@ -38,7 +38,6 @@ REGISTRY_HOOK reg_hooks[] = {
   { KEY_PRINTING,              &printing_ops },
   { KEY_PRINTING_2K,           &printing_ops },
   { KEY_PRINTING_PORTS,        &printing_ops },
-  { KEY_EVENTLOG,              &eventlog_ops }, 
   { KEY_SHARES,                &shares_reg_ops },
 #endif
   { NULL, NULL }
@@ -128,13 +127,10 @@ BOOL init_registry( void )
        if ( DEBUGLEVEL >= 20 )
                reghook_dump_cache(20);
 
-       /* inform the external eventlog machinery of the change */
-
-       eventlog_refresh_external_parameters( get_root_nt_token() );
-
-       /* add any services keys */
+       /* add any keys for other services */
 
        svcctl_init_keys();
+       eventlog_init_keys();
 
        return True;
 }
index 8bbb97f226db7119a1c0bcf81f2b3c3d40127a32..26da87b280a03fdb90e0b9ad1a0c6a457ab26b59 100644 (file)
@@ -830,6 +830,8 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
        if (buf) {
                /* We always null terminate the copy. */
                len = strlen(buf) + 1;
+               if ( flags == UNI_STR_DBLTERMINATE )
+                       len++;
        } else {
                /* no buffer -- nothing to do */
                str->uni_max_len = 0;
@@ -859,6 +861,8 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
                if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
                        num_chars++;
                }
+               if ( flags == UNI_STR_DBLTERMINATE )
+                       num_chars += 2;
        }
 
        str->uni_max_len = num_chars;
index f2e44560252324b9cbdd1faab7e243d5d2ec2d39..24bf3a455bf317c6b1fa35bbca1c71c9574410ef 100644 (file)
@@ -79,7 +79,7 @@ BOOL ntsvcs_io_q_get_device_list_size(const char *desc, NTSVCS_Q_GET_DEVICE_LIST
 
        if ( !prs_pointer("devicename", ps, depth, (void**)&q_u->devicename, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2) )
                return False;
-       if( !prs_align(ps) )
+       if ( !prs_align(ps) )
                return False;
                
        if ( !prs_uint32("flags", ps, depth, &q_u->flags) )
diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c
new file mode 100644 (file)
index 0000000..a8c1ad5
--- /dev/null
@@ -0,0 +1,620 @@
+
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  Eventlog utility  routines
+ *  Copyright (C) Marcin Krzysztof Porwit    2005,
+ *  Copyright (C) Gerald (Jerry) Carter      2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+
+/****************************************************************
+Init an Eventlog TDB, and return it. If null, something bad happened.
+****************************************************************/
+TDB_CONTEXT *init_eventlog_tdb( char *tdbfilename )
+{
+       TDB_CONTEXT *the_tdb;
+
+       unlink( tdbfilename );
+
+       the_tdb =
+               tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDWR | O_CREAT,
+                             0664 );
+       if ( the_tdb == NULL ) {
+               DEBUG( 1, ( "Can't open tdb for [%s]\n", tdbfilename ) );
+               return NULL;
+       }
+       tdb_store_int32( the_tdb, VN_oldest_entry, 1 );
+       tdb_store_int32( the_tdb, VN_next_record, 1 );
+
+       /* initialize with defaults, copy real values in here from registry */
+
+       tdb_store_int32( the_tdb, VN_maxsize, 0x80000 );
+       tdb_store_int32( the_tdb, VN_retention, 0x93A80 );
+
+       tdb_store_int32( the_tdb, VN_version, EVENTLOG_DATABASE_VERSION_V1 );
+       return the_tdb;
+}
+
+/* make the tdb file name for an event log, given destination buffer and size */
+char *mk_tdbfilename( char *dest_buffer, char *eventlog_name, int size_dest )
+{
+       if ( !dest_buffer )
+               return NULL;
+       pstring ondisk_name;
+
+       pstrcpy( ondisk_name, "EV" );
+       pstrcat( ondisk_name, eventlog_name );
+       pstrcat( ondisk_name, ".tdb" );
+
+       memset( dest_buffer, 0, size_dest );
+
+       /* BAD things could happen if the dest_buffer is not large enough... */
+       if ( strlen( ondisk_name ) > size_dest ) {
+               DEBUG( 3, ( "Buffer not big enough for filename\n" ) );
+               return NULL;
+       }
+
+       strncpy( dest_buffer, ondisk_name, size_dest );
+
+       return dest_buffer;
+}
+
+
+/* count the number of bytes in the TDB */
+
+/* Arg! Static Globals! */
+
+static int eventlog_tdbcount;
+static int eventlog_tdbsize;
+
+/* this function is used to count up the number of bytes in a particular TDB */
+int eventlog_tdb_size_fn( TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data,
+                         void *state )
+{
+       eventlog_tdbsize += data.dsize;
+       eventlog_tdbcount++;
+       return 0;
+}
+
+/* returns the size of the eventlog, and if MaxSize is a non-null ptr, puts 
+   the MaxSize there. This is purely a way not to have yet another function that solely
+   reads the maxsize of the eventlog. Yeah, that's it.  */
+
+int eventlog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention )
+{
+       if ( !tdb )
+               return 0;
+       eventlog_tdbcount = 0;
+       eventlog_tdbsize = 0;
+
+       tdb_traverse( tdb, eventlog_tdb_size_fn, NULL );
+
+       if ( MaxSize != NULL ) {
+               *MaxSize = tdb_fetch_int32( tdb, VN_maxsize );
+       }
+
+       if ( Retention != NULL ) {
+               *Retention = tdb_fetch_int32( tdb, VN_retention );
+       }
+
+       DEBUG( 1,
+              ( "eventlog size: [%d] for [%d] records\n", eventlog_tdbsize,
+                eventlog_tdbcount ) );
+       return eventlog_tdbsize;
+}
+
+
+/* 
+   Discard early event logs until we have enough for 'needed' bytes...
+   NO checking done beforehand to see that we actually need to do this, and
+   it's going to pluck records one-by-one. So, it's best to determine that this 
+   needs to be done before doing it.  
+
+   Setting whack_by_date to True indicates that eventlogs falling outside of the 
+   retention range need to go...
+
+*/
+
+/* return True if we made enough room to accommodate needed bytes */
+
+BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
+                            BOOL whack_by_date )
+{
+       int start_record, i, new_start;
+       int end_record;
+       int nbytes, reclen, len, Retention, MaxSize;
+
+       int tresv1, trecnum, timegen, timewr;
+
+       TDB_DATA key, ret;
+       TALLOC_CTX *mem_ctx = NULL;
+
+       time_t current_time, exp_time;
+
+       /* discard some eventlogs */
+
+       /* read eventlogs from oldest_entry -- there can't be any discontinuity in recnos,
+          although records not necessarily guaranteed to have successive times */
+       /* */
+       mem_ctx = talloc_init( "make_way_for_eventlogs" );      /* Homage to BPG */
+
+       if ( mem_ctx == NULL )
+               return False;   /* can't allocate memory indicates bigger problems */
+       /* lock */
+       tdb_lock_bystring( the_tdb, VN_next_record, 1 );
+       /* read */
+       end_record = tdb_fetch_int32( the_tdb, VN_next_record );
+       start_record = tdb_fetch_int32( the_tdb, VN_oldest_entry );
+       Retention = tdb_fetch_int32( the_tdb, VN_retention );
+       MaxSize = tdb_fetch_int32( the_tdb, VN_maxsize );
+
+       time( &current_time );
+
+       /* calculate ... */
+       exp_time = current_time - Retention;    /* discard older than exp_time */
+
+       /* todo - check for sanity in next_record */
+       nbytes = 0;
+
+       DEBUG( 3,
+              ( "MaxSize [%d] Retention [%d] Current Time [%d]  exp_time [%d]\n",
+                MaxSize, Retention, (uint32)current_time, (uint32)exp_time ) );
+       DEBUG( 3,
+              ( "Start Record [%d] End Record [%d]\n", start_record,
+                end_record ) );
+
+       for ( i = start_record; i < end_record; i++ ) {
+               /* read a record, add the amt to nbytes */
+               key.dsize = sizeof( int32 );
+               key.dptr = ( char * ) ( int32 * ) & i;
+               ret = tdb_fetch( the_tdb, key );
+               if ( ret.dsize == 0 ) {
+                       DEBUG( 8,
+                              ( "Can't find a record for the key, record [%d]\n",
+                                i ) );
+                       tdb_unlock_bystring( the_tdb, VN_next_record );
+                       return False;
+               }
+               nbytes += ret.dsize;    /* note this includes overhead */
+
+               len = tdb_unpack( ret.dptr, ret.dsize, "ddddd", &reclen,
+                                 &tresv1, &trecnum, &timegen, &timewr );
+               DEBUG( 8,
+                      ( "read record %d, record size is [%d], total so far [%d]\n",
+                        i, reclen, nbytes ) );
+
+               SAFE_FREE( ret.dptr );
+
+               /* note that other servers may just stop writing records when the size limit
+                  is reached, and there are no records older than 'retention'. This doesn't 
+                  like a very useful thing to do, so instead we whack (as in sleeps with the 
+                  fishes) just enough records to fit the what we need.  This behavior could
+                  be changed to 'match', if the need arises. */
+
+               if ( !whack_by_date && ( nbytes >= needed ) )
+                       break;  /* done */
+               if ( whack_by_date && ( timegen >= exp_time ) )
+                       break;  /* done */
+       }
+
+       DEBUG( 3,
+              ( "nbytes [%d] needed [%d] start_record is [%d], should be set to [%d]\n",
+                nbytes, needed, start_record, i ) );
+       /* todo - remove eventlog entries here and set starting record to start_record... */
+       new_start = i;
+       if ( start_record != new_start ) {
+               for ( i = start_record; i < new_start; i++ ) {
+                       key.dsize = sizeof( int32 );
+                       key.dptr = ( char * ) ( int32 * ) & i;
+                       tdb_delete( the_tdb, key );
+               }
+
+               tdb_store_int32( the_tdb, VN_oldest_entry, new_start );
+       }
+       tdb_unlock_bystring( the_tdb, VN_next_record );
+       return True;
+}
+
+/*
+  some hygiene for an eventlog - see how big it is, and then 
+  calculate how many bytes we need to remove                   
+*/
+
+BOOL prune_eventlog( TDB_CONTEXT * tdb )
+{
+       int MaxSize, Retention, CalcdSize;
+
+       if ( !tdb ) {
+               DEBUG( 4, ( "No eventlog tdb handle\n" ) );
+               return False;
+       }
+
+       CalcdSize = eventlog_tdb_size( tdb, &MaxSize, &Retention );
+       DEBUG( 3,
+              ( "Calculated size [%d] MaxSize [%d]\n", CalcdSize,
+                MaxSize ) );
+
+       if ( CalcdSize > MaxSize ) {
+               return make_way_for_eventlogs( tdb, CalcdSize - MaxSize,
+                                              False );
+       }
+
+       return make_way_for_eventlogs( tdb, 0, True );
+}
+
+BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
+{
+       int calcd_size;
+       int MaxSize, Retention;
+
+       /* see if we can write to the eventlog -- do a policy enforcement */
+       if ( !tdb )
+               return False;   /* tdb is null, so we can't write to it */
+
+
+       if ( needed < 0 )
+               return False;
+       MaxSize = 0;
+       Retention = 0;
+
+       calcd_size = eventlog_tdb_size( tdb, &MaxSize, &Retention );
+
+       if ( calcd_size <= MaxSize )
+               return True;    /* you betcha */
+       if ( calcd_size + needed < MaxSize )
+               return True;
+
+       if ( Retention == 0xffffffff ) {
+               return False;   /* see msdn - we can't write no room, discard */
+       }
+       /*
+          note don't have to test, but always good to show intent, in case changes needed
+          later
+        */
+
+       if ( Retention == 0x00000000 ) {
+               /* discard record(s) */
+               /* todo  - decide when to remove a bunch vs. just what we need... */
+               return make_way_for_eventlogs( tdb, calcd_size - MaxSize,
+                                              True );
+       }
+
+       return make_way_for_eventlogs( tdb, calcd_size - MaxSize, False );
+}
+
+TDB_CONTEXT *open_eventlog_tdb( char *tdbfilename )
+{
+       TDB_CONTEXT *the_tdb;
+
+       the_tdb =
+               tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDWR | O_CREAT,
+                             0664 );
+       if ( the_tdb == NULL ) {
+               return init_eventlog_tdb( tdbfilename );
+       }
+       if ( EVENTLOG_DATABASE_VERSION_V1 !=
+            tdb_fetch_int32( the_tdb, VN_version ) ) {
+               tdb_close( the_tdb );
+               return init_eventlog_tdb( tdbfilename );
+       }
+       return the_tdb;
+}
+
+/* write an eventlog entry. Note that we have to lock, read next eventlog, increment, write, write the record, unlock */
+
+/* coming into this, ee has the eventlog record, and the auxilliary date (computer name, etc.) 
+   filled into the other structure. Before packing into a record, this routine will calc the 
+   appropriate padding, etc., and then blast out the record in a form that can be read back in */
+int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
+{
+       int32 next_record;
+       uint8 *packed_ee;
+       TALLOC_CTX *mem_ctx = NULL;
+       TDB_DATA kbuf, ebuf;
+       uint32 n_packed;
+
+       if ( !ee )
+               return 0;
+
+       mem_ctx = talloc_init( "write_eventlog_tdb" );
+
+       if ( mem_ctx == NULL )
+               return 0;
+
+       if ( !ee )
+               return 0;
+       /* discard any entries that have bogus time, which usually indicates a bogus entry as well. */
+       if ( ee->record.time_generated == 0 )
+               return 0;
+
+#define MARGIN 512
+
+       /* todo - check for sanity in next_record */
+
+       fixup_eventlog_entry( ee );
+
+       if ( !can_write_to_eventlog( the_tdb, ee->record.length ) ) {
+               DEBUG( 3, ( "Can't write to Eventlog, no room \n" ) );
+               talloc_destroy( mem_ctx );
+               return 0;
+       }
+
+       /* alloc mem for the packed version */
+       packed_ee = TALLOC( mem_ctx, ee->record.length + MARGIN );
+       if ( !packed_ee ) {
+               talloc_destroy( mem_ctx );
+               return 0;
+       }
+
+       /* need to read the record number and insert it into the entry here */
+
+       /* lock */
+       tdb_lock_bystring( the_tdb, VN_next_record, 1 );
+       /* read */
+       next_record = tdb_fetch_int32( the_tdb, VN_next_record );
+
+       n_packed =
+               tdb_pack( packed_ee, ee->record.length + MARGIN,
+                         "ddddddwwwwddddddBBdBBBd", ee->record.length,
+                         ee->record.reserved1, next_record,
+                         ee->record.time_generated, ee->record.time_written,
+                         ee->record.event_id, ee->record.event_type,
+                         ee->record.num_strings, ee->record.event_category,
+                         ee->record.reserved2,
+                         ee->record.closing_record_number,
+                         ee->record.string_offset,
+                         ee->record.user_sid_length,
+                         ee->record.user_sid_offset, ee->record.data_length,
+                         ee->record.data_offset,
+                         ee->data_record.source_name_len,
+                         ee->data_record.source_name,
+                         ee->data_record.computer_name_len,
+                         ee->data_record.computer_name,
+                         ee->data_record.sid_padding,
+                         ee->record.user_sid_length, ee->data_record.sid,
+                         ee->data_record.strings_len,
+                         ee->data_record.strings,
+                         ee->data_record.user_data_len,
+                         ee->data_record.user_data,
+                         ee->data_record.data_padding );
+
+       /*DEBUG(3,("write_eventlog_tdb: packed into  %d\n",n_packed)); */
+
+       /* increment the record count */
+
+       kbuf.dsize = sizeof( int32 );
+       kbuf.dptr = ( uint8 * ) & next_record;
+
+       ebuf.dsize = n_packed;
+       ebuf.dptr = packed_ee;
+
+       if ( tdb_store( the_tdb, kbuf, ebuf, 0 ) ) {
+               /* DEBUG(1,("write_eventlog_tdb: Can't write record %d to eventlog\n",next_record)); */
+               tdb_unlock_bystring( the_tdb, VN_next_record );
+               talloc_destroy( mem_ctx );
+               return 0;
+       }
+       next_record++;
+       tdb_store_int32( the_tdb, VN_next_record, next_record );
+       tdb_unlock_bystring( the_tdb, VN_next_record );
+       talloc_destroy( mem_ctx );
+       return ( next_record - 1 );
+}
+
+/* calculate the correct fields etc for an eventlog entry */
+
+void fixup_eventlog_entry( Eventlog_entry * ee )
+{
+       /* fix up the eventlog entry structure as necessary */
+
+       ee->data_record.sid_padding =
+               ( ( 4 -
+                   ( ( ee->data_record.source_name_len +
+                       ee->data_record.computer_name_len ) % 4 ) ) % 4 );
+       ee->data_record.data_padding =
+               ( 4 -
+                 ( ( ee->data_record.strings_len +
+                     ee->data_record.user_data_len ) % 4 ) ) % 4;
+       ee->record.length = sizeof( Eventlog_record );
+       ee->record.length += ee->data_record.source_name_len;
+       ee->record.length += ee->data_record.computer_name_len;
+       if ( ee->record.user_sid_length == 0 ) {
+               /* Should not pad to a DWORD boundary for writing out the sid if there is
+                  no SID, so just propagate the padding to pad the data */
+               ee->data_record.data_padding += ee->data_record.sid_padding;
+               ee->data_record.sid_padding = 0;
+       }
+       /* DEBUG(10, ("sid_padding is [%d].\n", ee->data_record.sid_padding)); */
+       /* DEBUG(10, ("data_padding is [%d].\n", ee->data_record.data_padding)); */
+
+       ee->record.length += ee->data_record.sid_padding;
+       ee->record.length += ee->record.user_sid_length;
+       ee->record.length += ee->data_record.strings_len;
+       ee->record.length += ee->data_record.user_data_len;
+       ee->record.length += ee->data_record.data_padding;
+       /* need another copy of length at the end of the data */
+       ee->record.length += sizeof( ee->record.length );
+}
+
+/********************************************************************
+Note that it's a pretty good idea to initialize the Eventlog_entry structure to zero's before
+calling parse_logentry on an batch of lines that may resolve to a record.
+ALSO, it's a good idea to remove any linefeeds (that's EOL to you and me) on the lines going in.
+
+********************************************************************/
+
+BOOL parse_logentry( char *line, Eventlog_entry * entry, BOOL * eor )
+{
+       char *start = NULL, *stop = NULL;
+       pstring temp;
+       int temp_len = 0;
+
+       start = line;
+
+       /* empty line signyfiying record delimeter, or we're at the end of the buffer */
+       if ( start == NULL || strlen( start ) == 0 ) {
+               DEBUG( 6,
+                      ( "parse_logentry: found end-of-record indicator.\n" ) );
+               *eor = True;
+               return True;
+       }
+       if ( !( stop = strchr( line, ':' ) ) ) {
+               return False;
+       }
+
+       DEBUG( 6, ( "parse_logentry: trying to parse [%s].\n", line ) );
+
+       if ( 0 == strncmp( start, "LEN", stop - start ) ) {
+               /* This will get recomputed later anyway -- probably not necessary */
+               entry->record.length = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "RS1", stop - start ) ) {
+               /* For now all these reserved entries seem to have the same value,
+                  which can be hardcoded to int(1699505740) for now */
+               entry->record.reserved1 = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "RCN", stop - start ) ) {
+               entry->record.record_number = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "TMG", stop - start ) ) {
+               entry->record.time_generated = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "TMW", stop - start ) ) {
+               entry->record.time_written = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "EID", stop - start ) ) {
+               entry->record.event_id = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "ETP", stop - start ) ) {
+               if ( strstr( start, "ERROR" ) ) {
+                       entry->record.event_type = EVENTLOG_ERROR_TYPE;
+               } else if ( strstr( start, "WARNING" ) ) {
+                       entry->record.event_type = EVENTLOG_WARNING_TYPE;
+               } else if ( strstr( start, "INFO" ) ) {
+                       entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
+               } else if ( strstr( start, "AUDIT_SUCCESS" ) ) {
+                       entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
+               } else if ( strstr( start, "AUDIT_FAILURE" ) ) {
+                       entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
+               } else if ( strstr( start, "SUCCESS" ) ) {
+                       entry->record.event_type = EVENTLOG_SUCCESS;
+               } else {
+                       /* some other eventlog type -- currently not defined in MSDN docs, so error out */
+                       return False;
+               }
+       }
+
+/*
+  else if(0 == strncmp(start, "NST", stop - start))
+  {
+  entry->record.num_strings = atoi(stop + 1);
+  }
+*/
+       else if ( 0 == strncmp( start, "ECT", stop - start ) ) {
+               entry->record.event_category = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "RS2", stop - start ) ) {
+               entry->record.reserved2 = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "CRN", stop - start ) ) {
+               entry->record.closing_record_number = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "USL", stop - start ) ) {
+               entry->record.user_sid_length = atoi( stop + 1 );
+       } else if ( 0 == strncmp( start, "SRC", stop - start ) ) {
+               memset( temp, 0, sizeof( temp ) );
+               stop++;
+               while ( isspace( stop[0] ) ) {
+                       stop++;
+               }
+               temp_len = strlen( stop );
+               strncpy( temp, stop, temp_len );
+               rpcstr_push( ( void * ) ( entry->data_record.source_name ),
+                            temp, sizeof( entry->data_record.source_name ),
+                            STR_TERMINATE );
+               entry->data_record.source_name_len =
+                       ( strlen_w( entry->data_record.source_name ) * 2 ) +
+                       2;
+       } else if ( 0 == strncmp( start, "SRN", stop - start ) ) {
+               memset( temp, 0, sizeof( temp ) );
+               stop++;
+               while ( isspace( stop[0] ) ) {
+                       stop++;
+               }
+               temp_len = strlen( stop );
+               strncpy( temp, stop, temp_len );
+               rpcstr_push( ( void * ) ( entry->data_record.computer_name ),
+                            temp, sizeof( entry->data_record.computer_name ),
+                            STR_TERMINATE );
+               entry->data_record.computer_name_len =
+                       ( strlen_w( entry->data_record.computer_name ) * 2 ) +
+                       2;
+       } else if ( 0 == strncmp( start, "SID", stop - start ) ) {
+               memset( temp, 0, sizeof( temp ) );
+               stop++;
+               while ( isspace( stop[0] ) ) {
+                       stop++;
+               }
+               temp_len = strlen( stop );
+               strncpy( temp, stop, temp_len );
+               rpcstr_push( ( void * ) ( entry->data_record.sid ), temp,
+                            sizeof( entry->data_record.sid ),
+                            STR_TERMINATE );
+               entry->record.user_sid_length =
+                       ( strlen_w( entry->data_record.sid ) * 2 ) + 2;
+       } else if ( 0 == strncmp( start, "STR", stop - start ) ) {
+               /* skip past initial ":" */
+               stop++;
+               /* now skip any other leading whitespace */
+               while ( isspace( stop[0] ) ) {
+                       stop++;
+               }
+               temp_len = strlen( stop );
+               memset( temp, 0, sizeof( temp ) );
+               strncpy( temp, stop, temp_len );
+               rpcstr_push( ( void * ) ( entry->data_record.strings +
+                                         entry->data_record.strings_len ),
+                            temp,
+                            sizeof( entry->data_record.strings ) -
+                            entry->data_record.strings_len, STR_TERMINATE );
+               entry->data_record.strings_len += temp_len + 1;
+               entry->record.num_strings++;
+       } else if ( 0 == strncmp( start, "DAT", stop - start ) ) {
+               /* Now that we're done processing the STR data, adjust the length to account for
+                  unicode, then proceed with the DAT data. */
+               entry->data_record.strings_len *= 2;
+               /* skip past initial ":" */
+               stop++;
+               /* now skip any other leading whitespace */
+               while ( isspace( stop[0] ) ) {
+                       stop++;
+               }
+               entry->data_record.user_data_len = strlen( stop );
+               memset( entry->data_record.user_data, 0,
+                       sizeof( entry->data_record.user_data ) );
+               if ( entry->data_record.user_data_len > 0 ) {
+                       /* copy no more than the first 1024 bytes */
+                       if ( entry->data_record.user_data_len >
+                            sizeof( entry->data_record.user_data ) )
+                               entry->data_record.user_data_len =
+                                       sizeof( entry->data_record.
+                                               user_data );
+                       memcpy( entry->data_record.user_data, stop,
+                               entry->data_record.user_data_len );
+               }
+       } else {
+               /* some other eventlog entry -- not implemented, so dropping on the floor */
+               DEBUG( 10, ( "Unknown entry [%s]. Ignoring.\n", line ) );
+               /* For now return true so that we can keep on parsing this mess. Eventually
+                  we will return False here. */
+               return True;
+       }
+       return True;
+}
index 414c99d28e2bcc0ec292845d6cbf3f245819d3af..6067c94fe89f278fc3eb5087e26213591ef69aa9 100644 (file)
@@ -2,6 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
  *  Copyright (C) Marcin Krzysztof Porwit    2005,
+ *  Copyright (C) Brian Moran                2005,
  *  Copyright (C) Gerald (Jerry) Carter      2005.
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+
 #include "includes.h"
 
-#undef DBGC_CLASS
+#undef  DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
+
+typedef struct {
+       pstring logname;        /* rather than alloc on the fly what we need... (memory is cheap now) */
+       pstring tdbfname;
+       TDB_CONTEXT *log_tdb;   /* the pointer to the TDB_CONTEXT */
+} EventlogTDBInfo;
+
+static int nlogs;
+static EventlogTDBInfo *ttdb = NULL;
+static TALLOC_CTX *mem_ctx = NULL;
+
 typedef struct {
        char *logname;
        char *servername;
@@ -32,54 +44,295 @@ typedef struct {
        uint32 flags;
 } EventlogInfo;
 
-  
+
+
+#if 0 /* UNUSED */
 /********************************************************************
- Inform the external eventlog machinery of default values (on startup 
- probably)
-********************************************************************/
+ ********************************************************************/
+void test_eventlog_tdb( TDB_CONTEXT * the_tdb )
+{
+       Eventlog_entry ee;
+
+       int i = 0;
+
+       memset( &ee, 0, sizeof( Eventlog_entry ) );
+
+       if ( !the_tdb )
+               return;
+
+       for ( i = 0; i < 100; i++ ) {
+               ee.record.length = sizeof( ee.record );
+               memset( &ee.data_record, 0, sizeof( ee.data_record ) );
+               ee.record.reserved1 = 0xBEEFDEAD;
+               ee.record.record_number = 1000 - i;     /* should get substituted */
+               ee.record.time_generated = 0;
+               ee.record.time_written = 0;
+               ee.record.event_id = 500;
+               ee.record.event_type = 300;
+               ee.record.num_strings = 0;
+               ee.record.event_category = 0;
+               ee.record.reserved2 = ( i << 8 ) | i;
+               ee.record.closing_record_number = -1;
+               ee.record.string_offset = 0;
+               ee.record.user_sid_length = 0;
+               ee.record.user_sid_offset = 0;
+               ee.record.data_length = 0;
+               ee.record.data_offset = 0;
+
+               rpcstr_push( ( void * ) ( ee.data_record.source_name ),
+                            "SystemLog",
+                            sizeof( ee.data_record.source_name ),
+                            STR_TERMINATE );
+               ee.data_record.source_name_len =
+                       ( strlen_w( ee.data_record.source_name ) * 2 ) + 2;
+
+               rpcstr_push( ( void * ) ( ee.data_record.computer_name ),
+                            "DMLINUX",
+                            sizeof( ee.data_record.computer_name ),
+                            STR_TERMINATE );
+
+               ee.data_record.computer_name_len =
+                       ( strlen_w( ee.data_record.computer_name ) * 2 ) + 2;
+
+               write_eventlog_tdb( the_tdb, &ee );
+       }
+}
+#endif /* UNUSED */
+
+/********************************************************************
+ ********************************************************************/
 
-void eventlog_refresh_external_parameters( NT_USER_TOKEN *token )
+static void refresh_eventlog_tdb_table( void )
 {
-       const char **elogs = lp_eventlog_list();
-       int i;
+       const char **elogs = lp_eventlog_list(  );
+       int i, j;
 
        if ( !elogs )
-               return ;
+               return;
 
-       if ( !*lp_eventlog_control_cmd() )
+       if ( !mem_ctx ) {
+               mem_ctx = talloc_init( "refresh_eventlog_tdb_table" );
+       }
+
+       if ( !mem_ctx ) {
+               DEBUG( 1, ( "Can't allocate memory\n" ) );
                return;
+       }
+
+       /* count them */
+       for ( i = 0; elogs[i]; i++ ) {
+       }
+       /* number of logs in i */
+       DEBUG( 10, ( "Number of eventlogs %d\n", i ) );
+       /* check to see if we need to adjust our tables */
+
+       if ( ( ttdb != NULL ) ) {
+               if ( i != nlogs ) {
+                       /* refresh the table, by closing and reconstructing */
+                       DEBUG( 10, ( "Closing existing table \n" ) );
+                       for ( j = 0; j < nlogs; j++ ) {
+                               tdb_close( ttdb[j].log_tdb );
+                       }
+                       TALLOC_FREE( ttdb );
+                       ttdb = NULL;
+               } else {        /* i == nlogs */
+
+                       for ( j = 0; j < nlogs; j++ ) {
+                               if ( StrCaseCmp( ttdb[j].logname, elogs[i] ) ) {
+                                       /* something changed, have to discard */
+                                       DEBUG( 10,
+                                              ( "Closing existing table \n" ) );
+                                       for ( j = 0; j < nlogs; j++ ) {
+                                               tdb_close( ttdb[j].log_tdb );
+                                       }
+                                       TALLOC_FREE( ttdb );
+                                       ttdb = NULL;
+                                       break;
+                               }
+                       }
+               }
+       }
 
-       for ( i=0; elogs[i]; i++ ) {
-       
-               DEBUG(10,("eventlog_refresh_external_parameters: Refreshing =>[%s]\n", 
-                       elogs[i]));     
-               
-               if ( !control_eventlog_hook( token, elogs[i] ) ) {
-                       DEBUG(0,("eventlog_refresh_external_parameters: failed to refresh [%s]\n",
-                               elogs[i]));
+       /* note that this might happen because of above */
+       if ( ( i > 0 ) && ( ttdb == NULL ) ) {
+               /* alloc the room */
+               DEBUG( 10, ( "Creating the table\n" ) );
+               ttdb = TALLOC( mem_ctx, sizeof( EventlogTDBInfo ) * i );
+               if ( !ttdb ) {
+                       DEBUG( 10,
+                              ( "Can't allocate table for tdb handles \n" ) );
+                       return;
                }
-       }  
-    
-       return;
+               for ( j = 0; j < i; j++ ) {
+                       pstrcpy( ttdb[j].tdbfname,
+                                lock_path( mk_tdbfilename
+                                           ( ttdb[j].tdbfname,
+                                             ( char * ) elogs[j],
+                                             sizeof( pstring ) ) ) );
+                       pstrcpy( ttdb[j].logname, elogs[j] );
+                       DEBUG( 10, ( "Opening tdb for %s\n", elogs[j] ) );
+                       ttdb[j].log_tdb =
+                               open_eventlog_tdb( ttdb[j].tdbfname );
+               }
+       }
+       nlogs = i;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-static void free_eventlog_info(void *ptr)
+TDB_CONTEXT *tdb_of( char *eventlog_name )
+{
+       int i;
+
+       if ( !eventlog_name )
+               return NULL;
+
+       if ( !ttdb ) {
+               DEBUG( 10, ( "Refreshing list of eventlogs\n" ) );
+               refresh_eventlog_tdb_table(  );
+
+               if ( !ttdb ) {
+                       DEBUG( 10,
+                              ( "eventlog tdb table is NULL after a refresh!\n" ) );
+                       return NULL;
+               }
+       }
+
+       DEBUG( 10, ( "Number of eventlogs %d\n", nlogs ) );
+
+       for ( i = 0; i < nlogs; i++ ) {
+               if ( strequal( eventlog_name, ttdb[i].logname ) ) 
+                       return ttdb[i].log_tdb;
+       }
+
+       return NULL;
+}
+
+
+/********************************************************************
+  For the given tdb, get the next eventlog record into the passed 
+  Eventlog_entry.  returns NULL if it can't get the record for some reason.
+ ********************************************************************/
+
+Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb,
+                                    int recno, Eventlog_entry * ee )
+{
+       TDB_DATA ret, key;
+
+       int srecno;
+       int reclen;
+       int len;
+       uint8 *rbuff;
+
+       pstring *wpsource, *wpcomputer, *wpsid, *wpstrs, *puserdata;
+
+       key.dsize = sizeof( int32 );
+       rbuff = NULL;
+
+       srecno = recno;
+       key.dptr = ( char * ) &srecno;
+
+       ret = tdb_fetch( tdb, key );
+
+       if ( ret.dsize == 0 ) {
+               DEBUG( 8,
+                      ( "Can't find a record for the key, record %d\n",
+                        recno ) );
+               return NULL;
+       }
+
+       len = tdb_unpack( ret.dptr, ret.dsize, "d", &reclen );
+
+       DEBUG( 10, ( "Unpacking record %d, size is %d\n", srecno, len ) );
+
+       if ( !len )
+               return NULL;
+
+       /* ee = PRS_ALLOC_MEM(ps, Eventlog_entry, 1); */
+
+       if ( !ee )
+               return NULL;
+
+       len = tdb_unpack( ret.dptr, ret.dsize, "ddddddwwwwddddddBBdBBBd",
+                         &ee->record.length, &ee->record.reserved1,
+                         &ee->record.record_number,
+                         &ee->record.time_generated,
+                         &ee->record.time_written, &ee->record.event_id,
+                         &ee->record.event_type, &ee->record.num_strings,
+                         &ee->record.event_category, &ee->record.reserved2,
+                         &ee->record.closing_record_number,
+                         &ee->record.string_offset,
+                         &ee->record.user_sid_length,
+                         &ee->record.user_sid_offset,
+                         &ee->record.data_length, &ee->record.data_offset,
+                         &ee->data_record.source_name_len, &wpsource,
+                         &ee->data_record.computer_name_len, &wpcomputer,
+                         &ee->data_record.sid_padding,
+                         &ee->record.user_sid_length, &wpsid,
+                         &ee->data_record.strings_len, &wpstrs,
+                         &ee->data_record.user_data_len, &puserdata,
+                         &ee->data_record.data_padding );
+       DEBUG( 10,
+              ( "Read record %d, len in tdb was %d\n",
+                ee->record.record_number, len ) );
+
+       /* have to do the following because the tdb_unpack allocs a buff, stuffs a pointer to the buff
+          into it's 2nd argment for 'B' */
+
+       if ( wpcomputer )
+               memcpy( ee->data_record.computer_name, wpcomputer,
+                       ee->data_record.computer_name_len );
+       if ( wpsource )
+               memcpy( ee->data_record.source_name, wpsource,
+                       ee->data_record.source_name_len );
+
+       if ( wpsid )
+               memcpy( ee->data_record.sid, wpsid,
+                       ee->record.user_sid_length );
+       if ( wpstrs )
+               memcpy( ee->data_record.strings, wpstrs,
+                       ee->data_record.strings_len );
+
+       /* note that userdata is a pstring */
+       if ( puserdata )
+               memcpy( ee->data_record.user_data, puserdata,
+                       ee->data_record.user_data_len );
+
+       SAFE_FREE( wpcomputer );
+       SAFE_FREE( wpsource );
+       SAFE_FREE( wpsid );
+       SAFE_FREE( wpstrs );
+       SAFE_FREE( puserdata );
+
+       DEBUG( 10, ( "get_eventlog_record: read back %d\n", len ) );
+       DEBUG( 10,
+              ( "get_eventlog_record: computer_name %d is ",
+                ee->data_record.computer_name_len ) );
+       SAFE_FREE( ret.dptr );
+       return ee;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+static void free_eventlog_info( void *ptr )
 {
        TALLOC_FREE( ptr );
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-static EventlogInfo *find_eventlog_info_by_hnd(pipes_struct *p, POLICY_HND *handle)
+static EventlogInfo *find_eventlog_info_by_hnd( pipes_struct * p,
+                                               POLICY_HND * handle )
 {
        EventlogInfo *info;
-    
-       if ( !find_policy_by_hnd(p,handle,(void **)&info) ) {
-               DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
+
+       if ( !find_policy_by_hnd( p, handle, ( void ** ) &info ) ) {
+               DEBUG( 2,
+                      ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
                return NULL;
        }
 
@@ -87,144 +340,85 @@ static EventlogInfo *find_eventlog_info_by_hnd(pipes_struct *p, POLICY_HND *hand
 }
 
 /********************************************************************
- Callout to control the specified event log - passing out only 
- the MaxSize and Retention values, along with eventlog name
- uses smbrun...
-      INPUT: <control_cmd> <log name> <retention> <maxsize>
-      OUTPUT: nothing
-********************************************************************/
+ note that this can only be called AFTER the table is constructed, 
+ since it uses the table to find the tdb handle
+ ********************************************************************/
 
-BOOL control_eventlog_hook(NT_USER_TOKEN *token, const char *elogname )
+static BOOL sync_eventlog_params( const char *elogname )
 {
-       char *cmd = lp_eventlog_control_cmd();
-       pstring command;
-       int ret;
-       int fd = -1;
-       uint32 uiMaxSize, uiRetention;
        pstring path;
+       uint32 uiMaxSize;
+       uint32 uiRetention;
        REGISTRY_KEY *keyinfo;
        REGISTRY_VALUE *val;
        REGVAL_CTR *values;
        WERROR wresult;
+       TDB_CONTEXT *the_tdb;
+
+       the_tdb = tdb_of( ( char * ) elogname );
+
+       DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
 
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("control_eventlog_hook: No \"eventlog control command\" defined in smb.conf!\n"));
+       if ( !the_tdb ) {
+               DEBUG( 4, ( "Can't open tdb for %s\n", elogname ) );
                return False;
        }
-
        /* set resonable defaults.  512Kb on size and 1 week on time */
-       
+
        uiMaxSize = 0x80000;
        uiRetention = 604800;
-       
+
        /* the general idea is to internally open the registry 
           key and retreive the values.  That way we can continue 
           to use the same fetch/store api that we use in 
           srv_reg_nt.c */
 
        pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname );
-       wresult = regkey_open_internal( &keyinfo, path, token, REG_KEY_READ );
-       
+
+       wresult =
+               regkey_open_internal( &keyinfo, path, get_root_nt_token(  ),
+                                     REG_KEY_READ );
+
        if ( !W_ERROR_IS_OK( wresult ) ) {
-               DEBUG(4,("control_eventlog_hook: Failed to open key [%s] (%s)\n",
-                       path, dos_errstr(wresult) ));
+               DEBUG( 4,
+                      ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
+                        path, dos_errstr( wresult ) ) );
                return False;
        }
-       
-       if ( !(values = TALLOC_ZERO_P( keyinfo, REGVAL_CTR )) ) {
+
+       if ( !( values = TALLOC_ZERO_P( keyinfo, REGVAL_CTR ) ) ) {
                TALLOC_FREE( keyinfo );
-               DEBUG(0,("control_eventlog_hook: talloc() failed!\n"));
-               
+               DEBUG( 0, ( "control_eventlog_hook: talloc() failed!\n" ) );
+
                return False;
        }
        fetch_reg_values( keyinfo, values );
-       
-       if ( (val = regval_ctr_getvalue( values, "Retention" )) != NULL )
-               uiRetention = IVAL( regval_data_p(val), 0 );
 
-       if ( (val = regval_ctr_getvalue( values, "MaxSize" )) != NULL )
-               uiMaxSize = IVAL( regval_data_p(val), 0 );
-               
-       TALLOC_FREE( keyinfo );
-       
-       /* now run the command */
+       if ( ( val = regval_ctr_getvalue( values, "Retention" ) ) != NULL )
+               uiRetention = IVAL( regval_data_p( val ), 0 );
 
-       pstr_sprintf(command, "%s \"%s\" %u %u", cmd, elogname, uiRetention, uiMaxSize );
+       if ( ( val = regval_ctr_getvalue( values, "MaxSize" ) ) != NULL )
+               uiMaxSize = IVAL( regval_data_p( val ), 0 );
 
-       DEBUG(10, ("control_eventlog_hook: Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
+       TALLOC_FREE( keyinfo );
 
-       if ( ret != 0 ) {
-               DEBUG(10,("control_eventlog_hook: Command returned  [%d]\n", ret));
-               if (fd != -1 )
-                       close(fd);
-               return False;
-       }
+       tdb_store_int32( the_tdb, VN_maxsize, uiMaxSize );
+       tdb_store_int32( the_tdb, VN_retention, uiRetention );
 
-       close(fd);
        return True;
 }
 
-
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-/**
- * Callout to open the specified event log
- * 
- *   smbrun calling convention --
- *     INPUT: <open_cmd> <log name> <policy handle>
- *     OUTPUT: the string "SUCCESS" if the command succeeded
- *             no such string if there was a failure.
- */
-static BOOL open_eventlog_hook( EventlogInfo *info )
+static BOOL open_eventlog_hook( EventlogInfo * info )
 {
-       char *cmd = lp_eventlog_open_cmd();
-       char **qlines;
-       pstring command;
-       int numlines = 0;
-       int ret;
-       int fd = -1;
-
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("Must define an \"eventlog open command\" entry in the config.\n"));
-               return False;
-       }
-
-       pstr_sprintf(command, "%s \"%s\"", cmd, info->logname );
-
-       DEBUG(10, ("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
-
-       if(ret != 0) {
-               if(fd != -1) {
-                       close(fd);
-               }
-               return False;
-       }
-
-       qlines = fd_lines_load(fd, &numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
-       close(fd);
-
-       if(numlines) {
-               DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
-               if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS"))) {
-                       DEBUGADD(10, ("Able to open [%s].\n", info->logname));
-                       file_lines_free(qlines);
-                       return True;
-               }
-       }
-
-       file_lines_free(qlines);
-
-       return False;
+       return True;
 }
 
 /********************************************************************
 ********************************************************************/
+
 /**
  * Callout to get the number of records in the specified event log
  * 
@@ -234,50 +428,49 @@ static BOOL open_eventlog_hook( EventlogInfo *info )
  *             entries in the log. If there are no entries in the log, return 0.
  */
 
-static BOOL get_num_records_hook(EventlogInfo *info)
+
+static BOOL get_num_records_hook( EventlogInfo * info )
 {
-       char *cmd = lp_eventlog_num_records_cmd();
-       char **qlines;
-       pstring command;
-       int numlines = 0;
-       int ret;
-       int fd = -1;
-
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("Must define an \"eventlog num records command\" entry in the config.\n"));
-               return False;
-       }
 
-       pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
+       TDB_CONTEXT *the_tdb = NULL;
+       int next_record;
+       int oldest_record;
 
-       DEBUG(10, ("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
 
-       if(ret != 0) {
-               if(fd != -1) {
-                       close(fd);
-               }
+       the_tdb = tdb_of( info->logname );
+
+       if ( !the_tdb ) {
+               DEBUG( 10, ( "Can't find tdb for %s\n", info->logname ) );
+               info->num_records = 0;
                return False;
        }
 
-       qlines = fd_lines_load(fd, &numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
-       close(fd);
+       /* lock */
+       tdb_lock_bystring( the_tdb, VN_next_record, 1 );
+
+
+       /* read */
+       next_record = tdb_fetch_int32( the_tdb, VN_next_record );
+       oldest_record = tdb_fetch_int32( the_tdb, VN_oldest_entry );
+
+
+
+       DEBUG( 8,
+              ( "Oldest Record %d Next Record %d\n", oldest_record,
+                next_record ) );
+
+       info->num_records = ( next_record - oldest_record );
+       info->oldest_entry = oldest_record;
+       tdb_unlock_bystring( the_tdb, VN_next_record );
+
+
+       return True;
 
-       if(numlines) {
-               DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
-               sscanf(qlines[0], "%d", &(info->num_records));
-               file_lines_free(qlines);
-               return True;
-       }
 
-       file_lines_free(qlines);
-       return False;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
 /**
  * Callout to find the oldest record in the log
@@ -289,50 +482,17 @@ static BOOL get_num_records_hook(EventlogInfo *info)
  *             If there are no entries in the log, returns a 0
  */
 
-static BOOL get_oldest_entry_hook(EventlogInfo *info)
+static BOOL get_oldest_entry_hook( EventlogInfo * info )
 {
-       char *cmd = lp_eventlog_oldest_record_cmd();
-       char **qlines;
-       pstring command;
-       int numlines = 0;
-       int ret;
-       int fd = -1;
-
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("Must define an \"eventlog oldest record command\" entry in the config.\n"));
-               return False;
-       }
-
-       pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
-
-       DEBUG(10, ("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
 
-       if(ret != 0) {
-               if(fd != -1) {
-                       close(fd);
-               }
-               return False;
-       }
-
-       qlines = fd_lines_load(fd, &numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
-       close(fd);
-
-       if(numlines) {
-               DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
-               sscanf(qlines[0], "%d", &(info->oldest_entry));
-               file_lines_free(qlines);
-               return True;
-       }
-
-       file_lines_free(qlines);
-       return False;
+       /* it's the same thing */
+       return get_num_records_hook( info );
 }
 
+
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
+
 /**
  * Callout to close the specified event log
  * 
@@ -342,323 +502,51 @@ static BOOL get_oldest_entry_hook(EventlogInfo *info)
  *             no such string if there was a failure.
  */
 
-static BOOL close_eventlog_hook(EventlogInfo *info)
-{
-       char *cmd = lp_eventlog_close_cmd();
-       char **qlines;
-       pstring command;
-       int numlines = 0;
-       int ret;
-       int fd = -1;
-
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("Must define an \"eventlog close command\" entry in the config.\n"));
-               return False;
-       }
-
-       pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
-
-       DEBUG(10, ("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
-
-       if(ret != 0) {
-               if(fd != -1) {
-                       close(fd);
-               }
-               return False;
-       }
-
-       qlines = fd_lines_load(fd, &numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
-       close(fd);
-
-       if(numlines) {
-               DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
-               if(0 == strncmp(qlines[0], "SUCCESS", 7)) {
-                       DEBUGADD(10, ("Able to close [%s].\n", info->logname));
-                       file_lines_free(qlines);
-                       return True;
-               }
-       }
-
-       file_lines_free(qlines);
-       return False;
-}
-
-/********************************************************************
-********************************************************************/
-
-static BOOL parse_logentry(char *line, Eventlog_entry *entry, BOOL *eor)
+static BOOL close_eventlog_hook( EventlogInfo * info )
 {
-       char *start = NULL, *stop = NULL;
-       pstring temp;
-       int temp_len = 0, i;
-       start = line;
 
-       /* empty line signyfiying record delimeter, or we're at the end of the buffer */
-       if(start == NULL || strlen(start) == 0) {
-               DEBUG(6, ("parse_logentry: found end-of-record indicator.\n"));
-               *eor = True;
-               return True;
-       }
-       if(!(stop = strchr(line, ':'))) {
-               return False;
-       }
-    
-       DEBUG(6, ("parse_logentry: trying to parse [%s].\n", line));
-
-       if(0 == strncmp(start, "LEN", stop - start)) {
-               /* This will get recomputed later anyway -- probably not necessary */
-               entry->record.length = atoi(stop + 1);
-       } else if(0 == strncmp(start, "RS1", stop - start)) {
-               /* For now all these reserved entries seem to have the same value,
-                  which can be hardcoded to int(1699505740) for now */
-               entry->record.reserved1 = atoi(stop + 1);
-       } else if(0 == strncmp(start, "RCN", stop - start)) {
-               entry->record.record_number = atoi(stop + 1);
-       } else if(0 == strncmp(start, "TMG", stop - start)) {
-               entry->record.time_generated = atoi(stop + 1);
-       } else if(0 == strncmp(start, "TMW", stop - start)) {
-               entry->record.time_written = atoi(stop + 1);
-       } else if(0 == strncmp(start, "EID", stop - start)) {
-               entry->record.event_id = atoi(stop + 1);
-       } else if(0 == strncmp(start, "ETP", stop - start)) {
-               if(strstr(start, "ERROR")) {
-                       entry->record.event_type = EVENTLOG_ERROR_TYPE;
-               } else if(strstr(start, "WARNING")) {
-                       entry->record.event_type = EVENTLOG_WARNING_TYPE;
-               } else if(strstr(start, "INFO")) {
-                       entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
-               } else if(strstr(start, "AUDIT_SUCCESS")) {
-                       entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
-               } else if(strstr(start, "AUDIT_FAILURE")) {
-                       entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
-               } else if(strstr(start, "SUCCESS")) {
-                       entry->record.event_type = EVENTLOG_SUCCESS;
-               } else {
-                       /* some other eventlog type -- currently not defined in MSDN docs, so error out */
-                       return False;
-               }
-       }
-/*
-  else if(0 == strncmp(start, "NST", stop - start))
-  {
-  entry->record.num_strings = atoi(stop + 1);
-  }
-*/
-       else if(0 == strncmp(start, "ECT", stop - start)) {
-               entry->record.event_category = atoi(stop + 1);
-       } else if(0 == strncmp(start, "RS2", stop - start)) {
-               entry->record.reserved2 = atoi(stop + 1);
-       } else if(0 == strncmp(start, "CRN", stop - start)) {
-               entry->record.closing_record_number = atoi(stop + 1);
-       } else if(0 == strncmp(start, "USL", stop - start)) {
-               entry->record.user_sid_length = atoi(stop + 1);
-       } else if(0 == strncmp(start, "SRC", stop - start)) {
-               memset(temp, 0, sizeof(temp));
-               stop++;
-               while(isspace(stop[0])) {
-                       stop++;
-               }
-               temp_len = strlen(stop);
-               strncpy(temp, stop, temp_len);
-               rpcstr_push((void *)(entry->data_record.source_name), temp, 
-                           sizeof(entry->data_record.source_name), STR_TERMINATE);
-               entry->data_record.source_name_len = (strlen_w(entry->data_record.source_name)* 2) + 2;
-       } else if(0 == strncmp(start, "SRN", stop - start)) {
-               memset(temp, 0, sizeof(temp));
-               stop++;
-               while(isspace(stop[0])) {
-                       stop++; 
-               }
-               temp_len = strlen(stop);
-               strncpy(temp, stop, temp_len);
-               rpcstr_push((void *)(entry->data_record.computer_name), temp,
-                           sizeof(entry->data_record.computer_name), STR_TERMINATE);
-               entry->data_record.computer_name_len = (strlen_w(entry->data_record.computer_name)* 2) + 2;
-       } else if(0 == strncmp(start, "SID", stop - start)) {
-               memset(temp, 0, sizeof(temp));
-               stop++;
-               while(isspace(stop[0])) {
-                       stop++;
-               }
-               temp_len = strlen(stop);
-               strncpy(temp, stop, temp_len);
-               rpcstr_push((void *)(entry->data_record.sid), temp,
-                           sizeof(entry->data_record.sid), STR_TERMINATE);
-               entry->record.user_sid_length = (strlen_w(entry->data_record.sid) * 2) + 2;
-       } else if(0 == strncmp(start, "STR", stop - start)) {
-               /* skip past initial ":" */
-               stop++;
-               /* now skip any other leading whitespace */
-               while(isspace(stop[0])) {
-                       stop++;
-               }
-               temp_len = strlen(stop);
-               memset(temp, 0, sizeof(temp));
-               strncpy(temp, stop, temp_len);
-               rpcstr_push((void *)(entry->data_record.strings + entry->data_record.strings_len),
-                           temp,
-                           sizeof(entry->data_record.strings) - entry->data_record.strings_len, 
-                           STR_TERMINATE);
-               entry->data_record.strings_len += temp_len + 1;
-               fprintf(stderr, "Dumping strings:\n");
-               for(i = 0; i < entry->data_record.strings_len; i++) {
-                       fputc((char)entry->data_record.strings[i], stderr);
-               }
-               fprintf(stderr, "\nDone\n");
-               entry->record.num_strings++;
-       } else if(0 == strncmp(start, "DAT", stop - start)) {
-               /* Now that we're done processing the STR data, adjust the length to account for
-                  unicode, then proceed with the DAT data. */
-               entry->data_record.strings_len *= 2;
-               /* skip past initial ":" */
-               stop++;
-               /* now skip any other leading whitespace */
-               while(isspace(stop[0])) {
-                       stop++;
-               }
-               entry->data_record.user_data_len = strlen(stop);
-               memset(entry->data_record.user_data, 0, sizeof(entry->data_record.user_data));
-               if(entry->data_record.user_data_len > 0) {
-                       /* copy no more than the first 1024 bytes */
-                       if(entry->data_record.user_data_len > sizeof(entry->data_record.user_data))
-                               entry->data_record.user_data_len = sizeof(entry->data_record.user_data);
-                       memcpy(entry->data_record.user_data, stop, entry->data_record.user_data_len);
-               }
-       } else {
-               /* some other eventlog entry -- not implemented, so dropping on the floor */
-               DEBUG(10, ("Unknown entry [%s]. Ignoring.\n", line));
-               /* For now return true so that we can keep on parsing this mess. Eventually
-                  we will return False here. */
-               return True;
-       }
        return True;
 }
 
 /********************************************************************
-********************************************************************/
-
-/**
- * Callout to read entries from the specified event log
- *
- *   smbrun calling convention --
- *     INPUT: <read_cmd> <log name> <direction> <starting record> <buffer size> <policy handle>
- *            where direction is either "forward" or "backward", the starting record is somewhere
- *            between the oldest_record and oldest_record+num_records, and the buffer size is the
- *            maximum size of the buffer that the client can accomodate.
- *     OUTPUT: A buffer containing a set of entries, one to a line, of the format:
- *             Multiple log entries can be contained in the buffer, delimited by an empty line
- *               line type:line data
- *             These are the allowed line types:
- *               RS1:(uint32) - reserved. All M$ entries seem to have int(1699505740) for now
- *               RCN:(uint32) - record number of the record, however it may be calculated by the script
- *               TMG:(uint32) - time generated, seconds since January 1, 1970, 0000 UTC
- *               TMW:(uint32) - time written, seconds since January 1, 1970, 0000 UTC
- *               EID:(uint32) - eventlog source defined event identifier. If there's a stringfile for the event, it is an index into that
- *               ETP:(uint16) - eventlog type - one of ERROR, WARNING, INFO, AUDIT_SUCCESS, AUDIT_FAILURE
- *               ECT:(uint16) - event category - depends on the eventlog generator... 
- *               RS2:(uint16) - reserved, make it 0000
- *               CRN:(uint32) - reserved, make it 00000000 for now
- *               USL:(uint32) - user SID length. No sid? Make this 0. Must match SID below
- *               SRC:[(uint8)] - Name of the source, for example ccPwdSvc, in hex bytes. Can not be multiline.
- *               SRN:[(uint8)] - Name of the computer on which this is generated, the short hostname usually.
- *               SID:[(uint8)] - User sid if one exists. Must be present even if there is no SID.
- *               STR:[(uint8)] - String data. One string per line. Multiple strings can be specified using consecutive "STR" lines,
- *                               up to a total aggregate string length of 1024 characters.
- *               DAT:[(uint8)] - The user-defined data portion of the event log. Can not be multiple lines.
- *               <empty line>  - end-of-record indicator 
- */
-
-static BOOL read_eventlog_hook(EventlogInfo *info, Eventlog_entry *entry, 
-                                        const char *direction, int starting_record, 
-                                        int buffer_size, BOOL *eof,
-                                        char ***buffer, int *numlines)
-{
-       char *cmd = lp_eventlog_read_cmd();
-       pstring command;
-       int ret;
-       int fd = -1;
-
-       if ( !info )
-               return False;
-
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("Must define an \"eventlog read command\" entry in the config.\n"));
-               return False;
-       }
-
-       pstr_sprintf( command, "%s \"%s\" %s %d %d",
-                cmd, info->logname, direction, starting_record, buffer_size );
-
-       *numlines = 0;
-
-       DEBUG(10, ("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
-
-       if(ret != 0) {
-               if(fd != -1) {
-                       close(fd);
-               }
-               return False;
-       }
-
-       *buffer = fd_lines_load(fd, numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", *numlines));
-       close(fd);
-    
-       if(*numlines) {
-               /*
-                 for(i = 0; i < numlines; i++)
-                 {
-                 DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
-                 parse_logentry(qlines[i], entry);
-                 }
-                 file_lines_free(qlines);
-               */
-               *eof = False;
-               return True;
-       }
-       *eof = True;
-
-/*    file_lines_free(qlines);*/
-       return False;
-}
-
-/********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-static Eventlog_entry *read_package_entry(prs_struct *ps,
-                                                   EVENTLOG_Q_READ_EVENTLOG *q_u,
-                                                   EVENTLOG_R_READ_EVENTLOG *r_u,
-                                                   Eventlog_entry *entry)
+static Eventlog_entry *read_package_entry( prs_struct * ps,
+                                          EVENTLOG_Q_READ_EVENTLOG * q_u,
+                                          EVENTLOG_R_READ_EVENTLOG * r_u,
+                                          Eventlog_entry * entry )
 {
        uint8 *offset;
        Eventlog_entry *ee_new = NULL;
 
-       ee_new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1);
-       if(ee_new == NULL) {
+       ee_new = PRS_ALLOC_MEM( ps, Eventlog_entry, 1 );
+       if ( ee_new == NULL ) {
                return NULL;
        }
 
-       entry->data_record.sid_padding = ((4 - ((entry->data_record.source_name_len 
-                                                + entry->data_record.computer_name_len) % 4)) %4);
-       entry->data_record.data_padding = (4 - ((entry->data_record.strings_len 
-                                                + entry->data_record.user_data_len) % 4)) % 4;
-       entry->record.length = sizeof(Eventlog_record);
+       entry->data_record.sid_padding =
+               ( ( 4 -
+                   ( ( entry->data_record.source_name_len +
+                       entry->data_record.computer_name_len ) % 4 ) ) % 4 );
+       entry->data_record.data_padding =
+               ( 4 -
+                 ( ( entry->data_record.strings_len +
+                     entry->data_record.user_data_len ) % 4 ) ) % 4;
+       entry->record.length = sizeof( Eventlog_record );
        entry->record.length += entry->data_record.source_name_len;
        entry->record.length += entry->data_record.computer_name_len;
-       if(entry->record.user_sid_length == 0) {
+       if ( entry->record.user_sid_length == 0 ) {
                /* Should not pad to a DWORD boundary for writing out the sid if there is
                   no SID, so just propagate the padding to pad the data */
-               entry->data_record.data_padding += entry->data_record.sid_padding;
+               entry->data_record.data_padding +=
+                       entry->data_record.sid_padding;
                entry->data_record.sid_padding = 0;
        }
-       DEBUG(10, ("sid_padding is [%d].\n", entry->data_record.sid_padding));
-       DEBUG(10, ("data_padding is [%d].\n", entry->data_record.data_padding));
+       DEBUG( 10,
+              ( "sid_padding is [%d].\n", entry->data_record.sid_padding ) );
+       DEBUG( 10,
+              ( "data_padding is [%d].\n",
+                entry->data_record.data_padding ) );
 
        entry->record.length += entry->data_record.sid_padding;
        entry->record.length += entry->record.user_sid_length;
@@ -666,66 +554,82 @@ static Eventlog_entry *read_package_entry(prs_struct *ps,
        entry->record.length += entry->data_record.user_data_len;
        entry->record.length += entry->data_record.data_padding;
        /* need another copy of length at the end of the data */
-       entry->record.length += sizeof(entry->record.length);
-       DEBUG(10, ("entry->record.length is [%d].\n", entry->record.length));
-       entry->data = PRS_ALLOC_MEM(ps, uint8, entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length));
-       if(entry->data == NULL) {
+       entry->record.length += sizeof( entry->record.length );
+       DEBUG( 10,
+              ( "entry->record.length is [%d].\n", entry->record.length ) );
+       entry->data =
+               PRS_ALLOC_MEM( ps, uint8,
+                              entry->record.length -
+                              sizeof( Eventlog_record ) -
+                              sizeof( entry->record.length ) );
+       if ( entry->data == NULL ) {
                return NULL;
        }
        offset = entry->data;
-       memcpy(offset, &(entry->data_record.source_name), entry->data_record.source_name_len);
+       memcpy( offset, &( entry->data_record.source_name ),
+               entry->data_record.source_name_len );
        offset += entry->data_record.source_name_len;
-       memcpy(offset, &(entry->data_record.computer_name), entry->data_record.computer_name_len);
+       memcpy( offset, &( entry->data_record.computer_name ),
+               entry->data_record.computer_name_len );
        offset += entry->data_record.computer_name_len;
        /* SID needs to be DWORD-aligned */
        offset += entry->data_record.sid_padding;
-       entry->record.user_sid_offset = sizeof(Eventlog_record) + (offset - entry->data);
-       memcpy(offset, &(entry->data_record.sid), entry->record.user_sid_length);
+       entry->record.user_sid_offset =
+               sizeof( Eventlog_record ) + ( offset - entry->data );
+       memcpy( offset, &( entry->data_record.sid ),
+               entry->record.user_sid_length );
        offset += entry->record.user_sid_length;
        /* Now do the strings */
-       entry->record.string_offset = sizeof(Eventlog_record) + (offset - entry->data);
-       memcpy(offset, &(entry->data_record.strings), entry->data_record.strings_len);
+       entry->record.string_offset =
+               sizeof( Eventlog_record ) + ( offset - entry->data );
+       memcpy( offset, &( entry->data_record.strings ),
+               entry->data_record.strings_len );
        offset += entry->data_record.strings_len;
        /* Now do the data */
        entry->record.data_length = entry->data_record.user_data_len;
-       entry->record.data_offset = sizeof(Eventlog_record) + (offset - entry->data);
-       memcpy(offset, &(entry->data_record.user_data), entry->data_record.user_data_len);
+       entry->record.data_offset =
+               sizeof( Eventlog_record ) + ( offset - entry->data );
+       memcpy( offset, &( entry->data_record.user_data ),
+               entry->data_record.user_data_len );
        offset += entry->data_record.user_data_len;
 
-       memcpy(&(ee_new->record), &entry->record, sizeof(Eventlog_record));
-       memcpy(&(ee_new->data_record), &entry->data_record, sizeof(Eventlog_data_record));
+       memcpy( &( ee_new->record ), &entry->record,
+               sizeof( Eventlog_record ) );
+       memcpy( &( ee_new->data_record ), &entry->data_record,
+               sizeof( Eventlog_data_record ) );
        ee_new->data = entry->data;
 
        return ee_new;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-static BOOL add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *ee_new)
+static BOOL add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u,
+                               Eventlog_entry * ee_new )
 {
        Eventlog_entry *insert_point;
 
-       insert_point=r_u->entry;
+       insert_point = r_u->entry;
 
-       if (NULL == insert_point) {
+       if ( NULL == insert_point ) {
                r_u->entry = ee_new;
                ee_new->next = NULL;
        } else {
-               while ((NULL != insert_point->next)) {
-                       insert_point=insert_point->next;
+               while ( ( NULL != insert_point->next ) ) {
+                       insert_point = insert_point->next;
                }
                ee_new->next = NULL;
                insert_point->next = ee_new;
        }
-       r_u->num_records++; 
+       r_u->num_records++;
        r_u->num_bytes_in_resp += ee_new->record.length;
 
        return True;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
 /**
  * Callout to clear (and optionally backup) a specified event log
@@ -741,128 +645,153 @@ static BOOL add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *ee
  *             The given log is copied to that location on the server. See comments for
  *               eventlog_io_q_clear_eventlog for info about odd file name behavior
  */
-
-static BOOL clear_eventlog_hook(EventlogInfo *info, pstring backup_file_name)
+static BOOL clear_eventlog_hook( EventlogInfo * info,
+                                pstring backup_file_name )
 {
-       char *cmd = lp_eventlog_clear_cmd();
-       char **qlines;
-       pstring command;
-       int numlines = 0;
-       int ret;
-       int fd = -1;
-
-       if ( !cmd || !*cmd ) {
-               DEBUG(0, ("Must define an \"eventlog clear command\" entry in the config.\n"));
-               return False;
-       }
 
-       if ( strlen(backup_file_name) ) 
-               pstr_sprintf( command, "%s \"%s\" \"%s\"", cmd, info->logname, backup_file_name );
-       else 
-               pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
+       int i;
 
-       DEBUG(10, ("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
-       DEBUGADD(10, ("returned [%d]\n", ret));
 
-       if(ret != 0) {
-               if(fd != -1) {
-                       close(fd);
-               }
+       if ( !info )
                return False;
-       }
-
-       qlines = fd_lines_load(fd, &numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
-       close(fd);
-
-       if(numlines) {
-               DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
-               if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS"))) {
-                       DEBUGADD(10, ("Able to clear [%s].\n", info->logname));
-                       file_lines_free(qlines);
+       DEBUG( 3, ( "There are %d event logs\n", nlogs ) );
+       for ( i = 0; i < nlogs; i++ ) {
+               DEBUG( 3,
+                      ( "Comparing Eventlog %s,  %s\n", info->logname,
+                        ttdb[i].logname ) );
+               if ( !StrCaseCmp( info->logname, ttdb[i].logname ) ) {
+                       /* close the current one, reinit */
+                       tdb_close( ttdb[i].log_tdb );
+                       DEBUG( 3,
+                              ( "Closing Eventlog %s, file-on-disk %s\n",
+                                info->logname, ttdb[i].tdbfname ) );
+                       ttdb[i].log_tdb =
+                               init_eventlog_tdb( ttdb[i].tdbfname );
                        return True;
                }
        }
 
-       file_lines_free(qlines);
-       return False;
+       return False;           /* not found */
+       /* TODO- do something with the backup file name */
+
 }
 
 /*******************************************************************
-*******************************************************************/
+ *******************************************************************/
+
+static int eventlog_size( char *eventlog_name )
+{
+       TDB_CONTEXT *tdb;
+
+       if ( !eventlog_name )
+               return 0;
+       tdb = tdb_of( eventlog_name );
+       if ( !tdb )
+               return 0;
+       return eventlog_tdb_size( tdb, NULL, NULL );
+}
+
+/********************************************************************
+ ********************************************************************/
 
-WERROR _eventlog_open_eventlog(pipes_struct *p, EVENTLOG_Q_OPEN_EVENTLOG *q_u, EVENTLOG_R_OPEN_EVENTLOG *r_u)
+WERROR _eventlog_open_eventlog( pipes_struct * p,
+                               EVENTLOG_Q_OPEN_EVENTLOG * q_u,
+                               EVENTLOG_R_OPEN_EVENTLOG * r_u )
 {
        EventlogInfo *info = NULL;
        fstring str;
-    
-       if ( !(info = TALLOC_ZERO_P(NULL, EventlogInfo)) ) 
+
+       if ( !( info = TALLOC_ZERO_P( NULL, EventlogInfo ) ) )
                return WERR_NOMEM;
 
-       fstrcpy( str, global_myname() );
+       fstrcpy( str, global_myname(  ) );
        if ( q_u->servername.string ) {
-               rpcstr_pull( str, q_u->servername.string->buffer, 
-                       sizeof(str), q_u->servername.string->uni_str_len*2, 0 );
-       } 
+               rpcstr_pull( str, q_u->servername.string->buffer,
+                            sizeof( str ),
+                            q_u->servername.string->uni_str_len * 2, 0 );
+       }
+
        info->servername = talloc_strdup( info, str );
 
        fstrcpy( str, "Application" );
        if ( q_u->logname.string ) {
-               rpcstr_pull( str, q_u->logname.string->buffer, 
-                       sizeof(str), q_u->logname.string->uni_str_len*2, 0 );
-       } 
+               rpcstr_pull( str, q_u->logname.string->buffer,
+                            sizeof( str ),
+                            q_u->logname.string->uni_str_len * 2, 0 );
+       }
+
        info->logname = talloc_strdup( info, str );
 
-       DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the server name.\n", info->servername));
-       DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info->logname));
+       DEBUG( 1,
+              ( "Size of %s is %d\n", info->logname,
+                eventlog_size( info->logname ) ) );
 
-       if ( !create_policy_hnd(p, &r_u->handle, free_eventlog_info, (void *)info) ) {
-               free_eventlog_info(info);
+
+
+       DEBUG( 10,
+              ( "_eventlog_open_eventlog: Using [%s] as the server name.\n",
+                info->servername ) );
+       DEBUG( 10,
+              ( "_eventlog_open_eventlog: Using [%s] as the source log file.\n",
+                info->logname ) );
+
+
+       if ( !create_policy_hnd
+            ( p, &r_u->handle, free_eventlog_info, ( void * ) info ) ) {
+               free_eventlog_info( info );
                return WERR_NOMEM;
        }
-       
-       if ( !(open_eventlog_hook(info)) ) {
-               close_policy_hnd(p, &r_u->handle);
+
+       if ( !open_eventlog_hook( info ) ) {
+               close_policy_hnd( p, &r_u->handle );
                return WERR_BADFILE;
        }
-       
+
+       sync_eventlog_params( info->logname );
+       prune_eventlog( tdb_of( info->logname ) );
+
        return WERR_OK;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-WERROR _eventlog_clear_eventlog(pipes_struct *p, EVENTLOG_Q_CLEAR_EVENTLOG *q_u, EVENTLOG_R_CLEAR_EVENTLOG *r_u)
+WERROR _eventlog_clear_eventlog( pipes_struct * p,
+                                EVENTLOG_Q_CLEAR_EVENTLOG * q_u,
+                                EVENTLOG_R_CLEAR_EVENTLOG * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
        pstring backup_file_name;
 
        pstrcpy( backup_file_name, "" );
 
-       if ( q_u->backupfile.string ) 
-               unistr2_to_ascii(backup_file_name, q_u->backupfile.string, sizeof(backup_file_name));
+       if ( q_u->backupfile.string )
+               unistr2_to_ascii( backup_file_name, q_u->backupfile.string,
+                                 sizeof( backup_file_name ) );
 
-       DEBUG(10, ("_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
-                  backup_file_name, info->logname));
+       DEBUG( 10,
+              ( "_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
+                backup_file_name, info->logname ) );
 
-       if ( !(clear_eventlog_hook(info, backup_file_name)) )
+       if ( !( clear_eventlog_hook( info, backup_file_name ) ) )
                return WERR_BADFILE;
 
        return WERR_OK;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-WERROR _eventlog_close_eventlog(pipes_struct *p, EVENTLOG_Q_CLOSE_EVENTLOG *q_u, EVENTLOG_R_CLOSE_EVENTLOG *r_u)
+WERROR _eventlog_close_eventlog( pipes_struct * p,
+                                EVENTLOG_Q_CLOSE_EVENTLOG * q_u,
+                                EVENTLOG_R_CLOSE_EVENTLOG * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd(p,&q_u->handle);
+       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
 
-       if ( !(close_eventlog_hook(info)) )
+       if ( !( close_eventlog_hook( info ) ) )
                return WERR_BADFILE;
 
-       if ( !(close_policy_hnd(p, &q_u->handle)) ) {
+       if ( !( close_policy_hnd( p, &q_u->handle ) ) ) {
                return WERR_BADFID;
        }
 
@@ -870,76 +799,93 @@ WERROR _eventlog_close_eventlog(pipes_struct *p, EVENTLOG_Q_CLOSE_EVENTLOG *q_u,
 }
 
 /********************************************************************
-********************************************************************/
-   
-WERROR _eventlog_read_eventlog(pipes_struct *p, EVENTLOG_Q_READ_EVENTLOG *q_u, EVENTLOG_R_READ_EVENTLOG *r_u)
+ ********************************************************************/
+
+WERROR _eventlog_read_eventlog( pipes_struct * p,
+                               EVENTLOG_Q_READ_EVENTLOG * q_u,
+                               EVENTLOG_R_READ_EVENTLOG * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
        Eventlog_entry entry, *ee_new;
-       BOOL eof = False, eor = False;
-       const char *direction = "";
+
        uint32 num_records_read = 0;
        prs_struct *ps;
-       int numlines, i;
-       char **buffer;
+       int bytes_left, record_number;
+       TDB_CONTEXT *the_tdb;
+
 
        info->flags = q_u->flags;
        ps = &p->out_data.rdata;
 
-       if ( info->flags & EVENTLOG_FORWARDS_READ ) 
-               direction = "forward";
-       else if ( info->flags & EVENTLOG_BACKWARDS_READ )
-               direction = "backward";
 
-       if ( !(read_eventlog_hook(info, &entry, direction, q_u->offset, q_u->max_read_size, &eof, &buffer, &numlines)) ) {
-               if(eof == False) {
-                       return WERR_NOMEM;
-               }
+       bytes_left = q_u->max_read_size;
+       the_tdb = tdb_of( info->logname );
+       if ( !the_tdb ) {
+               /* todo handle the error */
+
        }
+       /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */
+
+
+       record_number = q_u->offset;
+
+       while ( bytes_left > 0 ) {
+               if ( get_eventlog_record
+                    ( ps, the_tdb, record_number, &entry ) ) {
+                       DEBUG( 8,
+                              ( "Retrieved record %d\n", record_number ) );
+                       /* Now see if there is enough room to add */
+                       if ( ( ee_new =
+                              read_package_entry( ps, q_u, r_u,
+                                                  &entry ) ) == NULL ) {
+                               return WERR_NOMEM;
 
-       if(numlines > 0) {
-               ZERO_STRUCT(entry);
-               for(i = 0; i < numlines; i++) {
-                       num_records_read = r_u->num_records;
-                       DEBUGADD(10, ("Line[%d] = [%s]\n", i, buffer[i]));
-                       parse_logentry(buffer[i], &entry, &eor);
-                       if(eor == True) {
-                               /* package ee_new entry */
-                               if((ee_new = read_package_entry(ps, q_u, r_u, &entry)) == NULL) {
-                                       SAFE_FREE(buffer);
-                                       return WERR_NOMEM;
-                               }
-                               /* Now see if there is enough room to add */
-                               if(r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size) {
-                                       r_u->bytes_in_next_record = ee_new->record.length;
-                                       /* response would be too big to fit in client-size buffer */
-                                       break;
-                               }
-                               add_record_to_resp(r_u, ee_new);
-                               ZERO_STRUCT(entry);
-                               eor=False;
-                               num_records_read = r_u->num_records - num_records_read;
-                               DEBUG(10, ("_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
-                                          num_records_read,
-                                          r_u->num_records,
-                                          r_u->num_bytes_in_resp,
-                                          q_u->max_read_size));
                        }
+
+                       if ( r_u->num_bytes_in_resp + ee_new->record.length >
+                            q_u->max_read_size ) {
+                               r_u->bytes_in_next_record =
+                                       ee_new->record.length;
+                               /* response would be too big to fit in client-size buffer */
+                               bytes_left = 0;
+                               break;
+                       }
+                       add_record_to_resp( r_u, ee_new );
+                       bytes_left -= ee_new->record.length;
+                       ZERO_STRUCT( entry );
+                       num_records_read =
+                               r_u->num_records - num_records_read;
+                       DEBUG( 10,
+                              ( "_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
+                                num_records_read, r_u->num_records,
+                                r_u->num_bytes_in_resp,
+                                q_u->max_read_size ) );
+               } else {
+                       DEBUG( 8, ( "get_eventlog_record returned NULL\n" ) );
+                       return WERR_NOMEM;      /* wrong error - but return one anyway */
                }
-               SAFE_FREE(buffer);
-       }
 
+
+               if ( info->flags & EVENTLOG_FORWARDS_READ ) {
+                       record_number++;
+               } else {
+                       record_number--;
+               }
+
+       }
        return WERR_OK;
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-WERROR _eventlog_get_oldest_entry(pipes_struct *p, EVENTLOG_Q_GET_OLDEST_ENTRY *q_u, EVENTLOG_R_GET_OLDEST_ENTRY *r_u)
+WERROR _eventlog_get_oldest_entry( pipes_struct * p,
+                                  EVENTLOG_Q_GET_OLDEST_ENTRY * q_u,
+                                  EVENTLOG_R_GET_OLDEST_ENTRY * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
 
-       if ( !(get_oldest_entry_hook(info)) ) 
+       if ( !( get_oldest_entry_hook( info ) ) )
                return WERR_BADFILE;
 
        r_u->oldest_entry = info->oldest_entry;
@@ -948,17 +894,18 @@ WERROR _eventlog_get_oldest_entry(pipes_struct *p, EVENTLOG_Q_GET_OLDEST_ENTRY *
 }
 
 /********************************************************************
-********************************************************************/
+ ********************************************************************/
 
-WERROR _eventlog_get_num_records(pipes_struct *p, EVENTLOG_Q_GET_NUM_RECORDS *q_u, EVENTLOG_R_GET_NUM_RECORDS *r_u)
+WERROR _eventlog_get_num_records( pipes_struct * p,
+                                 EVENTLOG_Q_GET_NUM_RECORDS * q_u,
+                                 EVENTLOG_R_GET_NUM_RECORDS * r_u )
 {
-       EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+       EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle );
 
-       if ( !(get_num_records_hook(info)) )
+       if ( !( get_num_records_hook( info ) ) )
                return WERR_BADFILE;
 
        r_u->num_records = info->num_records;
 
        return WERR_OK;
 }
-
index 0bb9154aaf05952d32962a3213eeffb000c4d961..79259174fd2d376965fed0029e676dd7c617ac8f 100644 (file)
@@ -80,11 +80,9 @@ WERROR _ntsvcs_get_device_list( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST *q_u,
        rpcstr_pull(device, q_u->devicename->buffer, sizeof(device), q_u->devicename->uni_str_len*2, 0);
        devicepath = get_device_path( device );
 
-       /* From the packet traces I've see, I think this really should be an array
-          of UNISTR2's.  But I've never seen more than one string in spite of the 
-          fact that the string in double NULL terminated.  -- jerry */
+       /* This has to be DOUBLE NULL terminated */
 
-       init_unistr2( &r_u->devicepath, devicepath, UNI_STR_TERMINATE );
+       init_unistr2( &r_u->devicepath, devicepath, UNI_STR_DBLTERMINATE );
        r_u->needed = r_u->devicepath.uni_str_len;
 
        return WERR_OK;
index 4db5ed0ed6227df9fb0d64bb3f6b005f9acade0f..0ba3e04b99f09460642a8fdada6c925e6ab7b530 100644 (file)
@@ -293,9 +293,11 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
                          SEC_RIGHTS_CREATE_SUBKEY|
                         SEC_RIGHTS_QUERY_VALUE|
                         SEC_RIGHTS_SET_VALUE);
-                        
-       if ( !(parent->access_granted & check_rights) )
+
+       if ( !(parent->access_granted & check_rights) ) {
+               DEBUG(8,("Rights check failed, parent had %04x, check_rights %04x\n",parent->access_granted, check_rights));
                return WERR_ACCESS_DENIED;
+       }
        
        /* 
         * very crazy, but regedit.exe on Win2k will attempt to call 
index e8df2acb22fec61ea99995e048343afcd4c875c5..19648f5e78bc87220d21e91b5d2b47a486bbbcaa 100644 (file)
@@ -32,10 +32,21 @@ struct service_control_op {
        SERVICE_CONTROL_OPS *ops;
 };
 
-extern SERVICE_CONTROL_OPS spoolss_svc_ops;
+#define SVCCTL_NUM_INTERNAL_SERVICES   4
+
+/* handle external services */
 extern SERVICE_CONTROL_OPS rcinit_svc_ops;
+
+/* builtin services (see service_db.c and services/svc_*.c */
+extern SERVICE_CONTROL_OPS spoolss_svc_ops;
 extern SERVICE_CONTROL_OPS netlogon_svc_ops;
 extern SERVICE_CONTROL_OPS winreg_svc_ops;
+extern SERVICE_CONTROL_OPS wins_svc_ops;
+
+/* make sure this number patches the number of builtin
+   SERVICE_CONTROL_OPS structure listed above */
+
+#define SVCCTL_NUM_INTERNAL_SERVICES   4
 
 struct service_control_op *svcctl_ops;
 
@@ -51,7 +62,7 @@ static struct generic_mapping svc_generic_map =
 BOOL init_service_op_table( void )
 {
        const char **service_list = lp_svcctl_list();
-       int num_services = 3 + str_list_count( service_list );
+       int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_count( service_list );
        int i;
        
        if ( !(svcctl_ops = TALLOC_ARRAY( NULL, struct service_control_op, num_services+1)) ) {
@@ -80,6 +91,10 @@ BOOL init_service_op_table( void )
        svcctl_ops[i].ops  = &winreg_svc_ops;
        i++;
        
+       svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" );
+       svcctl_ops[i].ops  = &wins_svc_ops;
+       i++;
+       
        /* NULL terminate the array */
        
        svcctl_ops[i].name = NULL;
index b59cd5330e5acae3e40761e47a397f700486cfd0..7c75d41352890288a851f69872b0924da80739ce 100644 (file)
 
 #include "includes.h"
 
+struct rcinit_file_information {
+       char *description;
+};
+
+struct service_display_info {
+       const char *servicename;
+       const char *daemon;
+       const char *dispname;
+       const char *description;
+};
+
+struct service_display_info builtin_svcs[] = {  
+  { "Spooler",       "smbd", "Print Spooler",
+       "Internal service for spooling files to print devices" },
+  { "NETLOGON",              "smbd", "Net Logon",
+       "File service providing access to policy and profile data" },
+  { "RemoteRegistry", "smbd", "Remote Registry Service",
+       "Internal service providing remote access to the Samba registry" },
+  { "WINS",           "nmbd", "Windows Internet Name Service (WINS)",
+       "Internal service providing a NetBIOS point-to-point name server" },
+  { NULL, NULL, NULL, NULL }
+};
+
+struct service_display_info common_unix_svcs[] = {  
+  { "cups",          NULL, "Common Unix Printing System", NULL },
+  { "postfix",       NULL, "Internet Mail Service", NULL },
+  { "sendmail",      NULL, "Internet Mail Service", NULL },
+  { "portmap",       NULL, "TCP Port to RPC PortMapper", NULL },
+  { "xinetd",        NULL, "Internet Meta-Daemon", NULL },
+  { "inet",          NULL, "Internet Meta-Daemon", NULL },
+  { "xntpd",         NULL, "Network Time Service", NULL },
+  { "ntpd",          NULL, "Network Time Service", NULL },
+  { "lpd",           NULL, "BSD Print Spooler", NULL },
+  { "nfsserver",     NULL, "Network File Service", NULL },
+  { "cron",          NULL, "Scheduling Service", NULL },
+  { "at",            NULL, "Scheduling Service", NULL },
+  { "nscd",          NULL, "Name Service Cache Daemon", NULL },
+  { "slapd",         NULL, "LDAP Directory Service", NULL },
+  { "ldap",          NULL, "LDAP DIrectory Service", NULL },
+  { "ypbind",        NULL, "NIS Directory Service", NULL },
+  { "courier-imap",  NULL, "IMAP4 Mail Service", NULL },
+  { "courier-pop3",  NULL, "POP3 Mail Service", NULL },
+  { "named",         NULL, "Domain Name Service", NULL },
+  { "bind",          NULL, "Domain Name Service", NULL },
+  { "httpd",         NULL, "HTTP Server", NULL },
+  { "apache",        NULL, "HTTP Server", NULL },
+  { "autofs",        NULL, "Automounter", NULL },
+  { "squid",         NULL, "Web Cache Proxy ", NULL },
+  { NULL, NULL, NULL, NULL }
+};
+
+
 /********************************************************************
 ********************************************************************/
 
@@ -63,11 +115,122 @@ static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
  Display name, Description, etc...
 ********************************************************************/
 
+static char *get_common_service_dispname( const char *servicename )
+{
+       static fstring dispname;
+       int i;
+       
+       for ( i=0; common_unix_svcs[i].servicename; i++ ) {
+               if ( strequal( servicename, common_unix_svcs[i].servicename ) ) {
+                       fstr_sprintf( dispname, "%s (%s)", 
+                               common_unix_svcs[i].dispname,
+                               common_unix_svcs[i].servicename );
+                               
+                       return dispname;
+               }
+       } 
+       
+       fstrcpy( dispname, servicename );
+       
+       return dispname;
+}
+
+/********************************************************************
+********************************************************************/
+
+static char* cleanup_string( const char *string )
+{
+       static pstring clean;
+       char *begin, *end;
+
+       pstrcpy( clean, string );
+       begin = clean;
+       
+       /* trim any beginning whilespace */
+       
+       while ( isspace(*begin) )
+               begin++;
+
+       if ( !begin )
+               return NULL;
+                       
+       /* trim any trailing whitespace or carriage returns.
+          Start at the end and move backwards */
+                       
+       end = begin + strlen(begin) - 1;
+                       
+       while ( isspace(*end) || *end=='\n' || *end=='\r' ) {
+               *end = '\0';
+               end--;
+       }
+
+       return begin;
+}
+
+/********************************************************************
+********************************************************************/
+
+static BOOL read_init_file( const char *servicename, struct rcinit_file_information **service_info )
+{
+       struct rcinit_file_information *info;
+       pstring filepath, str;
+       XFILE *f;
+       char *p, *s;
+               
+       if ( !(info = TALLOC_ZERO_P( NULL, struct rcinit_file_information ) ) )
+               return False;
+       
+       /* attempt the file open */
+               
+       pstr_sprintf( filepath, "%s/%s/%s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, servicename );
+       if ( !(f = x_fopen( filepath, O_RDONLY, 0 )) ) {
+               DEBUG(0,("read_init_file: failed to open [%s]\n", filepath));
+               TALLOC_FREE(info);
+               return False;
+       }
+       
+       while ( (s = x_fgets( str, sizeof(str)-1, f )) != NULL ) {
+               /* ignore everything that is not a full line 
+                  comment starting with a '#' */
+                  
+               if ( str[0] != '#' )
+                       continue;
+               
+               /* Look for a line like '^#.*Description:' */
+               
+               if ( (p = strstr( str, "Description:" )) != NULL ) {
+                       char *desc;
+
+                       p += strlen( "Description:" ) + 1;
+                       if ( !p ) 
+                               break;
+                               
+                       if ( (desc = cleanup_string(p)) != NULL )
+                               info->description = talloc_strdup( info, desc );
+               }
+       }
+       
+       x_fclose( f );
+       
+       if ( !info->description )
+               info->description = talloc_strdup( info, "External Unix Service" );
+       
+       *service_info = info;
+       
+       return True;
+}
+
+/********************************************************************
+ This is where we do the dirty work of filling in things like the
+ Display name, Description, etc...
+********************************************************************/
+
 static void fill_service_values( const char *name, REGVAL_CTR *values )
 {
        UNISTR2 data, dname, ipath, description;
        uint32 dword;
        pstring pstr;
+       int i;
        
        /* These values are hardcoded in all QueryServiceConfig() replies.
           I'm just storing them here for cosmetic purposes */
@@ -88,30 +251,39 @@ static void fill_service_values( const char *name, REGVAL_CTR *values )
        
        /* special considerations for internal services and the DisplayName value */
        
-       if ( strequal(name, "Spooler") ) {
-               pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR );
-               init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
-               init_unistr2( &description, "Internal service for spooling files to print devices", UNI_STR_TERMINATE );
-               init_unistr2( &dname, "Print Spooler", UNI_STR_TERMINATE );
-       } 
-       else if ( strequal(name, "NETLOGON") ) {
-               pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR );
-               init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
-               init_unistr2( &description, "File service providing access to policy and profile data", UNI_STR_TERMINATE );
-               init_unistr2( &dname, "Net Logon", UNI_STR_TERMINATE );
+       for ( i=0; builtin_svcs[i].servicename; i++ ) {
+               if ( strequal( name, builtin_svcs[i].servicename ) ) {
+                       pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, builtin_svcs[i].daemon );
+                       init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+                       init_unistr2( &description, builtin_svcs[i].description, UNI_STR_TERMINATE );
+                       init_unistr2( &dname, builtin_svcs[i].dispname, UNI_STR_TERMINATE );
+                       break;
+               }
        } 
-       else if ( strequal(name, "RemoteRegistry") ) {
-               pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR );
-               init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
-               init_unistr2( &description, "Internal service providing remote access to the Samba registry", UNI_STR_TERMINATE );
-               init_unistr2( &dname, "Remote Registry Service", UNI_STR_TERMINATE );
-       } 
-       else {
+       
+       /* default to an external service if we haven't found a match */
+       
+       if ( builtin_svcs[i].servicename == NULL ) {
+               struct rcinit_file_information *init_info = NULL;
+
                pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, name );
                init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
-               init_unistr2( &description, "External Unix Service", UNI_STR_TERMINATE );
-               init_unistr2( &dname, name, UNI_STR_TERMINATE );
+               
+               /* lookup common unix display names */
+               init_unistr2( &dname, get_common_service_dispname( name ), UNI_STR_TERMINATE );
+
+               /* get info from init file itself */            
+               if ( read_init_file( name, &init_info ) ) {
+                       init_unistr2( &description, init_info->description, UNI_STR_TERMINATE );
+                       TALLOC_FREE( init_info );
+               }
+               else {
+                       init_unistr2( &description, "External Unix Service", UNI_STR_TERMINATE );
+               }
        }
+       
+       /* add the new values */
+       
        regval_ctr_addvalue( values, "DisplayName", REG_SZ, (char*)dname.buffer, dname.uni_str_len*2);
        regval_ctr_addvalue( values, "ImagePath", REG_SZ, (char*)ipath.buffer, ipath.uni_str_len*2);
        regval_ctr_addvalue( values, "Description", REG_SZ, (char*)description.buffer, description.uni_str_len*2);
@@ -248,9 +420,8 @@ void svcctl_init_keys( void )
        
        /* the builting services exist */
        
-       add_new_svc_name( key, subkeys, "Spooler" );
-       add_new_svc_name( key, subkeys, "NETLOGON" );
-       add_new_svc_name( key, subkeys, "RemoteRegistry" );
+       for ( i=0; builtin_svcs[i].servicename; i++ )
+               add_new_svc_name( key, subkeys, builtin_svcs[i].servicename );
                
        for ( i=0; service_list[i]; i++ ) {
        
@@ -352,29 +523,34 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+       wresult = regkey_open_internal( &key, path, token, REG_KEY_READ );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
-               return NULL;
+               goto fail;
        }
 
        if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
                DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
                TALLOC_FREE( key );
-               return NULL;
+               goto fail;
        }
 
        fetch_reg_values( key, values );
        
        if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) )
-               fstrcpy( display_name, name );
-       else
-               rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 );
+               goto fail;
+
+       rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 );
 
        TALLOC_FREE( key );
        
        return display_name;
+
+fail:
+       /* default to returning the service name */
+       fstrcpy( display_name, name );
+       return display_name;
 }
 
 /********************************************************************
@@ -392,7 +568,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+       wresult = regkey_open_internal( &key, path, token, REG_KEY_READ );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
@@ -431,7 +607,7 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token )
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+       wresult = regkey_open_internal( &key, path, token, REG_KEY_READ );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
index 5801d076c496ebc22d6b6affedeee68d7b3b53ce..f60019601fe60b1eef20902694e55697b199b8dc 100644 (file)
@@ -1,4 +1,3 @@
-
 /* 
  *  Unix SMB/CIFS implementation.
  *  Service Control API Implementation
 
 #include "includes.h"
 
-/* Implementation for LSB compliant init scripts */
-
-/*******************************************************************************
- Get the services information  by reading and parsing the shell scripts. These 
- are symbolically linked into the  SVCCTL_SCRIPT_DIR  directory.
-
- Get the names of the services/scripts to read from the smb.conf file.
-*******************************************************************************/
-
-BOOL get_LSB_data(char *fname,Service_info *si )
-{
-       pstring initdfile;
-       char mybuffer[256];
-       const char *tokenptr;
-       char **qlines;
-       int fd = -1;
-       int nlines, *numlines,i,in_section,in_description;
-       
-       pstrcpy(si->servicename,"");
-       pstrcpy(si->servicetype,"EXTERNAL");
-       pstrcpy(si->filename,fname);
-       pstrcpy(si->provides,"");
-       pstrcpy(si->dependencies,"");
-       pstrcpy(si->shouldstart,"");
-       pstrcpy(si->shouldstop,"");
-       pstrcpy(si->requiredstart,"");
-       pstrcpy(si->requiredstop,"");
-       pstrcpy(si->description,"");
-       pstrcpy(si->shortdescription,"");
-
-       numlines = &nlines;
-       in_section = 0;
-       in_description = 0;
-
-   
-       if( !fname || !*fname ) {
-               DEBUG(0, ("Must define an \"LSB-style init file\" to read.\n"));
-               return False;
-       }
-       pstrcpy(initdfile,dyn_LIBDIR);
-       pstrcat(initdfile,SVCCTL_SCRIPT_DIR);
-       pstrcat(initdfile,fname);
-
-       /* TODO  - should check to see if the file that we're trying to open is 
-          actually a script. If it's NOT, we should do something like warn, 
-          and not continue to try to find info we're looking for */
-
-       DEBUG(10, ("Opening [%s]\n", initdfile));
-       fd = -1;
-       fd = open(initdfile,O_RDONLY);
-       *numlines = 0;
-
-       if (fd == -1) {
-               DEBUG(10, ("Couldn't open [%s]\n", initdfile));
-               return False;
-       }
-
-       qlines = fd_lines_load(fd, numlines);
-       DEBUGADD(10, ("Lines returned = [%d]\n", *numlines));
-       close(fd);
-    
-
-       if (*numlines) {
-       
-               for(i = 0; i < *numlines; i++) {
-
-                       DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
-                       if (!in_section && (0==strwicmp("### BEGIN INIT INFO", qlines[i]))) {
-                               /* we now can look for params */
-                               DEBUGADD(10, ("Configuration information starts on line = [%d]\n", i));
-                               in_section = 1;
-
-                       } else if (in_section && (0==strwicmp("### END INIT INFO", qlines[i]))) {
-                               DEBUGADD(10, ("Configuration information ends on line = [%d]\n", i));
-                               DEBUGADD(10, ("Description is [%s]\n", si->description));
-                               in_description = 0;
-                               in_section = 0;
-                               break;
-                       } else if (in_section) {
-                               tokenptr = qlines[i];
-                               if (in_description) {
-                                       DEBUGADD(10, ("Processing DESCRIPTION [%d]\n", *tokenptr));
-                                       if (tokenptr && (*tokenptr=='#') && (*(tokenptr+1)=='\t')) {
-                                               DEBUGADD(10, ("Adding to DESCRIPTION [%d]\n", *tokenptr));
-                                               pstrcat(si->description," ");
-                                               pstrcat(si->description,tokenptr+2);
-                                               continue;
-                                       }
-                                       in_description = 0;
-                                       DEBUGADD(10, ("Not a description!\n"));
-                               }
-                               if (!next_token(&tokenptr,mybuffer," \t",sizeof(mybuffer))) {
-                                       DEBUGADD(10, ("Invalid line [%d]\n", i));
-                                       break; /* bad line? */
-                               }
-                               if (0 != strncmp(mybuffer,"#",1)) {
-                                       DEBUGADD(10, ("Invalid line [%d], is %s\n", i,mybuffer));
-                                       break;
-                               }
-                               if (!next_token(&tokenptr,mybuffer," \t",sizeof(mybuffer))) {
-                                       DEBUGADD(10, ("Invalid token on line [%d]\n", i));
-                                       break; /* bad line? */
-                               }             
-                               DEBUGADD(10, ("Keyword is  [%s]\n", mybuffer));
-                               if (0==strwicmp(mybuffer,"Description:")) {
-                                       while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) { 
-                                               tokenptr++; 
-                                       }
-                                       pstrcpy(si->description,tokenptr);
-                                       DEBUGADD(10, ("FOUND DESCRIPTION! Data is [%s]\n", tokenptr));
-                                       in_description = 1;
-                               } else {
-                                       while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) { 
-                                               tokenptr++; 
-                                       }
-                                       DEBUGADD(10, ("Data is [%s]\n", tokenptr));
-                                       in_description = 0;
-
-                                       /* save certain keywords, don't save others */
-                                       if (0==strwicmp(mybuffer, "Provides:")) {
-                                               pstrcpy(si->provides,tokenptr);
-                                               pstrcpy(si->servicename,tokenptr);
-                                       }
-
-                                       if (0==strwicmp(mybuffer, "Short-Description:")) {
-                                               pstrcpy(si->shortdescription,tokenptr);
-                                       }
-
-                                       if (0==strwicmp(mybuffer, "Required-start:")) {
-                                               pstrcpy(si->requiredstart,tokenptr);
-                                               pstrcpy(si->dependencies,tokenptr);
-                                       }
-
-                                       if (0==strwicmp(mybuffer, "Should-start:")) {
-                                               pstrcpy(si->shouldstart,tokenptr);
-                                       }
-                               }
-                       }
-               }
-
-               file_lines_free(qlines);
-                       return True;
-       }
-
-       return False;
-}
-
 /*********************************************************************
 *********************************************************************/
 
diff --git a/source3/services/svc_wins.c b/source3/services/svc_wins.c
new file mode 100644 (file)
index 0000000..3a46506
--- /dev/null
@@ -0,0 +1,66 @@
+/* 
+ *  Unix SMB/CIFS implementation.
+ *  Service Control API Implementation
+ *  Copyright (C) Gerald Carter                   2005.
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/* Implementation for internal wins service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR wins_stop( const char *service, SERVICE_STATUS *service_status )
+{
+       return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR wins_start( const char *service )
+{
+       return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR wins_status( const char *service, SERVICE_STATUS *service_status )
+{
+       ZERO_STRUCTP( service_status );
+
+       service_status->type              = 0x10;
+       if ( lp_wins_support() ) 
+               service_status->state     = SVCCTL_RUNNING;
+       else
+               service_status->state     = SVCCTL_STOPPED;
+       
+       return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate wins service */
+
+SERVICE_CONTROL_OPS wins_svc_ops = {
+       wins_stop,
+       wins_start,
+       wins_status
+};