LCOV - code coverage report
Current view: top level - source3/rpc_server/eventlog - srv_eventlog_nt.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 215 430 50.0 %
Date: 2024-02-28 12:06:22 Functions: 19 38 50.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Marcin Krzysztof Porwit    2005,
       5             :  *  Copyright (C) Brian Moran                2005,
       6             :  *  Copyright (C) Gerald (Jerry) Carter      2005.
       7             :  *  Copyright (C) Guenther Deschner          2009.
       8             :  *
       9             :  *  This program is free software; you can redistribute it and/or modify
      10             :  *  it under the terms of the GNU General Public License as published by
      11             :  *  the Free Software Foundation; either version 3 of the License, or
      12             :  *  (at your option) any later version.
      13             :  *
      14             :  *  This program is distributed in the hope that it will be useful,
      15             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :  *  GNU General Public License for more details.
      18             :  *
      19             :  *  You should have received a copy of the GNU General Public License
      20             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      21             :  */
      22             : 
      23             : #include "includes.h"
      24             : #include "system/passwd.h" /* uid_wrapper */
      25             : #include "ntdomain.h"
      26             : #include "lib/eventlog/eventlog.h"
      27             : #include "../libcli/security/security.h"
      28             : #include "../librpc/gen_ndr/ndr_winreg_c.h"
      29             : #include "rpc_client/cli_winreg_int.h"
      30             : #include "rpc_client/cli_winreg.h"
      31             : #include "smbd/smbd.h"
      32             : #include "auth.h"
      33             : #include "util_tdb.h"
      34             : 
      35             : #include "rpc_server/rpc_server.h"
      36             : #include "librpc/rpc/dcesrv_core.h"
      37             : #include "librpc/gen_ndr/ndr_eventlog_scompat.h"
      38             : #include "rpc_server/eventlog/srv_eventlog_reg.h"
      39             : #include "lib/global_contexts.h"
      40             : 
      41             : #undef  DBGC_CLASS
      42             : #define DBGC_CLASS DBGC_RPC_SRV
      43             : 
      44             : #define TOP_LEVEL_EVENTLOG_KEY "SYSTEM\\CurrentControlSet\\Services\\Eventlog"
      45             : 
      46             : typedef struct {
      47             :         char *logname;
      48             :         ELOG_TDB *etdb;
      49             :         uint32_t current_record;
      50             :         uint32_t num_records;
      51             :         uint32_t oldest_entry;
      52             :         uint32_t flags;
      53             :         uint32_t access_granted;
      54             : } EVENTLOG_INFO;
      55             : 
      56             : /********************************************************************
      57             :  ********************************************************************/
      58             : 
      59          12 : static int eventlog_info_destructor(EVENTLOG_INFO *elog)
      60             : {
      61          12 :         if (elog->etdb) {
      62          12 :                 elog_close_tdb(elog->etdb, false);
      63             :         }
      64          12 :         return 0;
      65             : }
      66             : 
      67             : /********************************************************************
      68             :  ********************************************************************/
      69             : 
      70          28 : static EVENTLOG_INFO *find_eventlog_info_by_hnd( struct pipes_struct * p,
      71             :                                                 struct policy_handle * handle )
      72             : {
      73           0 :         EVENTLOG_INFO *info;
      74           0 :         NTSTATUS status;
      75             : 
      76          28 :         info = find_policy_by_hnd(p,
      77             :                                   handle,
      78             :                                   DCESRV_HANDLE_ANY,
      79             :                                   EVENTLOG_INFO,
      80           0 :                                   &status);
      81          28 :         if (!NT_STATUS_IS_OK(status)) {
      82           0 :                 DEBUG( 2,
      83             :                        ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
      84           0 :                 return NULL;
      85             :         }
      86             : 
      87          28 :         return info;
      88             : }
      89             : 
      90             : /********************************************************************
      91             :  Pull the NT ACL from a file on disk or the OpenEventlog() access
      92             :  check.  Caller is responsible for freeing the returned security
      93             :  descriptor via TALLOC_FREE().  This is designed for dealing with
      94             :  user space access checks in smbd outside of the VFS.  For example,
      95             :  checking access rights in OpenEventlog() or from python.
      96             : 
      97             : ********************************************************************/
      98             : 
      99          12 : static NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx,
     100             :                             struct auth_session_info *session_info,
     101             :                             const char *fname,
     102             :                                 uint32_t security_info_wanted,
     103             :                                 struct security_descriptor **sd)
     104             : {
     105          12 :         TALLOC_CTX *frame = talloc_stackframe();
     106          12 :         struct conn_struct_tos *c = NULL;
     107          12 :         NTSTATUS status = NT_STATUS_OK;
     108          12 :         struct smb_filename *pathref_fname = NULL;
     109             : 
     110          12 :         if (!posix_locking_init(false)) {
     111           0 :                 TALLOC_FREE(frame);
     112           0 :                 return NT_STATUS_NO_MEMORY;
     113             :         }
     114             : 
     115          12 :         status = create_conn_struct_tos(global_messaging_context(),
     116             :                                         -1,
     117             :                                         "/",
     118             :                                         session_info,
     119             :                                         &c);
     120          12 :         if (!NT_STATUS_IS_OK(status)) {
     121           0 :                 DBG_ERR("create_conn_struct_tos() returned %s.\n",
     122             :                         nt_errstr(status));
     123           0 :                 TALLOC_FREE(frame);
     124           0 :                 return status;
     125             :         }
     126             : 
     127          12 :         status = synthetic_pathref(talloc_tos(),
     128          12 :                                 c->conn->cwd_fsp,
     129             :                                 fname,
     130             :                                 NULL,
     131             :                                 NULL,
     132             :                                 0,
     133             :                                 0,
     134             :                                 &pathref_fname);
     135          12 :         if (!NT_STATUS_IS_OK(status)) {
     136           0 :                 DBG_ERR("synthetic_pathref for file %s returned %s.\n",
     137             :                           fname, nt_errstr(status));
     138           0 :                 TALLOC_FREE(frame);
     139           0 :                 return status;
     140             :         }
     141          12 :         status = SMB_VFS_FGET_NT_ACL(pathref_fname->fsp,
     142             :                                 security_info_wanted,
     143             :                                 ctx,
     144             :                                 sd);
     145          12 :         if (!NT_STATUS_IS_OK(status)) {
     146           0 :                 DBG_ERR("SMB_VFS_FGET_NT_ACL for file %s returned %s.\n",
     147             :                           fname, nt_errstr(status));
     148             :         }
     149             : 
     150          12 :         TALLOC_FREE(frame);
     151             : 
     152          12 :         return status;
     153             : }
     154             : 
     155             : /********************************************************************
     156             : ********************************************************************/
     157             : 
     158          12 : static bool elog_check_access(EVENTLOG_INFO *info,
     159             :                               struct auth_session_info *session_info)
     160             : {
     161          12 :         const struct security_token *token = session_info->security_token;
     162          12 :         char *tdbname = elog_tdbname(talloc_tos(), info->logname );
     163           0 :         struct security_descriptor *sec_desc;
     164           0 :         struct security_ace *ace;
     165           0 :         NTSTATUS status;
     166             : 
     167          12 :         if ( !tdbname )
     168           0 :                 return False;
     169             : 
     170             :         /* get the security descriptor for the file */
     171             : 
     172          12 :         status = get_nt_acl_no_snum( info,
     173             :                         session_info,
     174             :                         tdbname,
     175             :                         SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL,
     176             :                         &sec_desc);
     177          12 :         if (!NT_STATUS_IS_OK(status)) {
     178           0 :                 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s: %s\n",
     179             :                         tdbname, nt_errstr(status)));
     180           0 :                 TALLOC_FREE(tdbname);
     181           0 :                 return False;
     182             :         }
     183          12 :         TALLOC_FREE(tdbname);
     184             : 
     185          12 :         ace = talloc_zero(sec_desc, struct security_ace);
     186          12 :         if (ace == NULL) {
     187           0 :                 TALLOC_FREE(sec_desc);
     188           0 :                 return false;
     189             :         }
     190             : 
     191          12 :         ace->type            = SEC_ACE_TYPE_ACCESS_ALLOWED;
     192          12 :         ace->flags           = 0;
     193          12 :         ace->access_mask     = REG_KEY_ALL;
     194          12 :         ace->trustee         = global_sid_System;
     195             : 
     196          12 :         status = security_descriptor_dacl_add(sec_desc, ace);
     197          12 :         if (!NT_STATUS_IS_OK(status)) {
     198           0 :                 TALLOC_FREE(sec_desc);
     199           0 :                 return false;
     200             :         }
     201             : 
     202             :         /* root free pass */
     203             : 
     204          12 :         if ( geteuid() == sec_initial_uid() ) {
     205          12 :                 DEBUG(5,("elog_check_access: running as root, using system token\n"));
     206          12 :                 token = get_system_token();
     207             :         }
     208             : 
     209             :         /* run the check, try for the max allowed */
     210             : 
     211          12 :         status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
     212             :                 &info->access_granted);
     213             : 
     214          12 :         TALLOC_FREE(sec_desc);
     215             : 
     216          12 :         if (!NT_STATUS_IS_OK(status)) {
     217           0 :                 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
     218             :                         nt_errstr(status)));
     219           0 :                 return False;
     220             :         }
     221             : 
     222             :         /* we have to have READ permission for a successful open */
     223             : 
     224          12 :         return ( info->access_granted & SEC_FILE_READ_DATA );
     225             : }
     226             : 
     227             : /********************************************************************
     228             :  ********************************************************************/
     229             : 
     230          24 : static bool elog_validate_logname( const char *name )
     231             : {
     232           0 :         int i;
     233          24 :         const char **elogs = lp_eventlog_list();
     234             : 
     235          24 :         if (!elogs) {
     236          12 :                 return False;
     237             :         }
     238             : 
     239          24 :         for ( i=0; elogs[i]; i++ ) {
     240          24 :                 if ( strequal( name, elogs[i] ) )
     241          12 :                         return True;
     242             :         }
     243             : 
     244           0 :         return False;
     245             : }
     246             : 
     247             : /********************************************************************
     248             : ********************************************************************/
     249             : 
     250          14 : static bool get_num_records_hook( EVENTLOG_INFO * info )
     251             : {
     252           0 :         int next_record;
     253           0 :         int oldest_record;
     254             : 
     255          14 :         if ( !info->etdb ) {
     256           0 :                 DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
     257           0 :                 return False;
     258             :         }
     259             : 
     260             :         /* lock the tdb since we have to get 2 records */
     261             : 
     262          14 :         tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
     263          14 :         next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
     264          14 :         oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
     265          14 :         tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
     266             : 
     267          14 :         DEBUG( 8,
     268             :                ( "Oldest Record %d; Next Record %d\n", oldest_record,
     269             :                  next_record ) );
     270             : 
     271          14 :         info->num_records = ( next_record - oldest_record );
     272          14 :         info->oldest_entry = oldest_record;
     273             : 
     274          14 :         return True;
     275             : }
     276             : 
     277             : /********************************************************************
     278             :  ********************************************************************/
     279             : 
     280          12 : static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
     281             : {
     282             :         /* it's the same thing */
     283          12 :         return get_num_records_hook( info );
     284             : }
     285             : 
     286             : /********************************************************************
     287             :  ********************************************************************/
     288             : 
     289          24 : static NTSTATUS elog_open( struct pipes_struct * p, const char *logname, struct policy_handle *hnd )
     290             : {
     291          24 :         struct dcesrv_call_state *dce_call = p->dce_call;
     292           0 :         struct auth_session_info *session_info =
     293          24 :                 dcesrv_call_session_info(dce_call);
     294           0 :         EVENTLOG_INFO *elog;
     295             : 
     296             :         /* first thing is to validate the eventlog name */
     297             : 
     298          24 :         if ( !elog_validate_logname( logname ) )
     299          12 :                 return NT_STATUS_OBJECT_PATH_INVALID;
     300             : 
     301          12 :         if ( !(elog = talloc_zero( NULL, EVENTLOG_INFO )) )
     302           0 :                 return NT_STATUS_NO_MEMORY;
     303          12 :         talloc_set_destructor(elog, eventlog_info_destructor);
     304             : 
     305          12 :         elog->logname = talloc_strdup( elog, logname );
     306             : 
     307             :         /* Open the tdb first (so that we can create any new tdbs if necessary).
     308             :            We have to do this as root and then use an internal access check
     309             :            on the file permissions since you can only have a tdb open once
     310             :            in a single process */
     311             : 
     312          12 :         become_root();
     313          12 :         elog->etdb = elog_open_tdb( elog->logname, False, False );
     314          12 :         unbecome_root();
     315             : 
     316          12 :         if ( !elog->etdb ) {
     317             :                 /* according to MSDN, if the logfile cannot be found, we should
     318             :                   default to the "Application" log */
     319             : 
     320           0 :                 if ( !strequal( logname, ELOG_APPL ) ) {
     321             : 
     322           0 :                         TALLOC_FREE( elog->logname );
     323             : 
     324           0 :                         elog->logname = talloc_strdup( elog, ELOG_APPL );
     325             : 
     326             :                         /* do the access check */
     327           0 :                         if ( !elog_check_access( elog, session_info) ) {
     328           0 :                                 TALLOC_FREE( elog );
     329           0 :                                 return NT_STATUS_ACCESS_DENIED;
     330             :                         }
     331             : 
     332           0 :                         become_root();
     333           0 :                         elog->etdb = elog_open_tdb( elog->logname, False, False );
     334           0 :                         unbecome_root();
     335             :                 }
     336             : 
     337           0 :                 if ( !elog->etdb ) {
     338           0 :                         TALLOC_FREE( elog );
     339           0 :                         return NT_STATUS_ACCESS_DENIED; /* ??? */
     340             :                 }
     341             :         }
     342             : 
     343             :         /* now do the access check.  Close the tdb if we fail here */
     344             : 
     345          12 :         if ( !elog_check_access( elog, session_info) ) {
     346           0 :                 TALLOC_FREE( elog );
     347           0 :                 return NT_STATUS_ACCESS_DENIED;
     348             :         }
     349             : 
     350             :         /* create the policy handle */
     351             : 
     352          12 :         if ( !create_policy_hnd( p, hnd, 0, elog ) ) {
     353           0 :                 TALLOC_FREE(elog);
     354           0 :                 return NT_STATUS_NO_MEMORY;
     355             :         }
     356             : 
     357             :         /* set the initial current_record pointer */
     358             : 
     359          12 :         if ( !get_oldest_entry_hook( elog ) ) {
     360           0 :                 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
     361             :                         "get any information on internal records!\n"));
     362             :         }
     363             : 
     364          12 :         elog->current_record = elog->oldest_entry;
     365             : 
     366          12 :         return NT_STATUS_OK;
     367             : }
     368             : 
     369             : /********************************************************************
     370             :  ********************************************************************/
     371             : 
     372          12 : static NTSTATUS elog_close( struct pipes_struct *p, struct policy_handle *hnd )
     373             : {
     374          12 :         if ( !( close_policy_hnd( p, hnd ) ) ) {
     375           0 :                 return NT_STATUS_INVALID_HANDLE;
     376             :         }
     377             : 
     378          12 :         return NT_STATUS_OK;
     379             : }
     380             : 
     381             : /*******************************************************************
     382             :  *******************************************************************/
     383             : 
     384           0 : static int elog_size( EVENTLOG_INFO *info )
     385             : {
     386           0 :         if ( !info || !info->etdb ) {
     387           0 :                 DEBUG(0,("elog_size: Invalid info* structure!\n"));
     388           0 :                 return 0;
     389             :         }
     390             : 
     391           0 :         return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
     392             : }
     393             : 
     394             : /********************************************************************
     395             :  note that this can only be called AFTER the table is constructed,
     396             :  since it uses the table to find the tdb handle
     397             :  ********************************************************************/
     398             : 
     399          12 : static bool sync_eventlog_params(TALLOC_CTX *mem_ctx,
     400             :                                  struct messaging_context *msg_ctx,
     401             :                                  EVENTLOG_INFO *info)
     402             : {
     403          12 :         struct dcerpc_binding_handle *h = NULL;
     404          12 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     405           0 :         struct policy_handle hive_hnd, key_hnd;
     406          12 :         uint32_t uiMaxSize = 0;
     407          12 :         uint32_t uiRetention = 0;
     408          12 :         char *path = NULL;
     409           0 :         NTSTATUS status;
     410          12 :         WERROR wresult = WERR_OK;
     411          12 :         char *elogname = info->logname;
     412           0 :         TALLOC_CTX *ctx;
     413          12 :         bool ret = false;
     414             : 
     415          12 :         ctx = talloc_stackframe();
     416          12 :         if (ctx == NULL) {
     417           0 :                 return false;
     418             :         }
     419             : 
     420          12 :         DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
     421             : 
     422          12 :         if ( !info->etdb ) {
     423           0 :                 DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
     424           0 :                 goto done;
     425             :         }
     426             :         /* set reasonable defaults.  512Kb on size and 1 week on time */
     427             : 
     428          12 :         uiMaxSize = 0x80000;
     429          12 :         uiRetention = 604800;
     430             : 
     431             :         /* the general idea is to internally open the registry
     432             :            key and retrieve the values.  That way we can continue
     433             :            to use the same fetch/store api that we use in
     434             :            srv_reg_nt.c */
     435          12 :         path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname);
     436          12 :         if (!path) {
     437           0 :                 goto done;
     438             :         }
     439             : 
     440          12 :         status = dcerpc_winreg_int_hklm_openkey(ctx,
     441             :                                                 get_session_info_system(),
     442             :                                                 msg_ctx,
     443             :                                                 &h,
     444             :                                                 path,
     445             :                                                 false,
     446             :                                                 access_mask,
     447             :                                                 &hive_hnd,
     448             :                                                 &key_hnd,
     449             :                                                 &wresult);
     450          12 :         if (!NT_STATUS_IS_OK(status)) {
     451           0 :                 DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n",
     452             :                          path, nt_errstr(status)));
     453           0 :                 goto done;
     454             :         }
     455          12 :         if ( !W_ERROR_IS_OK( wresult ) ) {
     456           0 :                 DEBUG( 4,
     457             :                        ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
     458             :                          path, win_errstr( wresult ) ) );
     459           0 :                 goto done;
     460             :         }
     461             : 
     462          12 :         status = dcerpc_winreg_query_dword(ctx,
     463             :                                            h,
     464             :                                            &key_hnd,
     465             :                                            "Retention",
     466             :                                            &uiRetention,
     467             :                                            &wresult);
     468          12 :         if (!NT_STATUS_IS_OK(status)) {
     469           0 :                 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
     470             :                           nt_errstr(status)));
     471           0 :                 goto done;
     472             :         }
     473          12 :         if (!W_ERROR_IS_OK(wresult)) {
     474           0 :                 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
     475             :                           win_errstr(wresult)));
     476           0 :                 goto done;
     477             :         }
     478             : 
     479          12 :         status = dcerpc_winreg_query_dword(ctx,
     480             :                                            h,
     481             :                                            &key_hnd,
     482             :                                            "MaxSize",
     483             :                                            &uiMaxSize,
     484             :                                            &wresult);
     485          12 :         if (!NT_STATUS_IS_OK(status)) {
     486           0 :                 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
     487             :                           nt_errstr(status)));
     488           0 :                 goto done;
     489             :         }
     490          12 :         if (!W_ERROR_IS_OK(wresult)) {
     491           0 :                 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
     492             :                           win_errstr(wresult)));
     493           0 :                 goto done;
     494             :         }
     495             : 
     496          12 :         tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
     497          12 :         tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
     498             : 
     499          12 :         ret = true;
     500             : 
     501          12 : done:
     502          12 :         if (h != NULL) {
     503           0 :                 WERROR ignore;
     504             : 
     505          12 :                 if (is_valid_policy_hnd(&key_hnd)) {
     506          12 :                         dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore);
     507             :                 }
     508          12 :                 if (is_valid_policy_hnd(&hive_hnd)) {
     509          12 :                         dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore);
     510             :                 }
     511             :         }
     512             : 
     513          12 :         TALLOC_FREE(ctx);
     514          12 :         return ret;
     515             : }
     516             : 
     517             : /********************************************************************
     518             :  _eventlog_OpenEventLogW
     519             :  ********************************************************************/
     520             : 
     521          24 : NTSTATUS _eventlog_OpenEventLogW(struct pipes_struct *p,
     522             :                                  struct eventlog_OpenEventLogW *r)
     523             : {
     524           0 :         EVENTLOG_INFO *info;
     525           0 :         NTSTATUS result;
     526             : 
     527          24 :         DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
     528             :                 r->in.servername->string, r->in.logname->string ));
     529             : 
     530             :         /* according to MSDN, if the logfile cannot be found, we should
     531             :           default to the "Application" log */
     532             : 
     533          24 :         if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) )
     534          12 :                 return result;
     535             : 
     536          12 :         if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) {
     537           0 :                 DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
     538             :                         r->in.logname->string ));
     539           0 :                 elog_close( p, r->out.handle );
     540           0 :                 return NT_STATUS_INVALID_HANDLE;
     541             :         }
     542             : 
     543          12 :         DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
     544             : 
     545          12 :         if (!sync_eventlog_params(p->mem_ctx,
     546             :                                   p->msg_ctx,
     547             :                                   info)) {
     548           0 :                 elog_close(p, r->out.handle);
     549           0 :                 return NT_STATUS_EVENTLOG_FILE_CORRUPT;
     550             :         }
     551          12 :         prune_eventlog( ELOG_TDB_CTX(info->etdb) );
     552             : 
     553          12 :         return NT_STATUS_OK;
     554             : }
     555             : 
     556             : /********************************************************************
     557             :  _eventlog_ClearEventLogW
     558             :  This call still needs some work
     559             :  ********************************************************************/
     560             : /** The windows client seems to be doing something funny with the file name
     561             :    A call like
     562             :       ClearEventLog(handle, "backup_file")
     563             :    on the client side will result in the backup file name looking like this on the
     564             :    server side:
     565             :       \??\${CWD of client}\backup_file
     566             :    If an absolute path gets specified, such as
     567             :       ClearEventLog(handle, "C:\\temp\\backup_file")
     568             :    then it is still mangled by the client into this:
     569             :       \??\C:\temp\backup_file
     570             :    when it is on the wire.
     571             :    I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
     572             :    would be added in given that the backup file gets written on the server side. */
     573             : 
     574           0 : NTSTATUS _eventlog_ClearEventLogW(struct pipes_struct *p,
     575             :                                   struct eventlog_ClearEventLogW *r)
     576             : {
     577           0 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
     578             : 
     579           0 :         if ( !info )
     580           0 :                 return NT_STATUS_INVALID_HANDLE;
     581             : 
     582           0 :         if (r->in.backupfile && r->in.backupfile->string) {
     583             : 
     584           0 :                 DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
     585             :                         "file name for log [%s].\n",
     586             :                          r->in.backupfile->string, info->logname ) );
     587             :         }
     588             : 
     589             :         /* check for WRITE access to the file */
     590             : 
     591           0 :         if ( !(info->access_granted & SEC_FILE_WRITE_DATA) )
     592           0 :                 return NT_STATUS_ACCESS_DENIED;
     593             : 
     594             :         /* Force a close and reopen */
     595             : 
     596           0 :         elog_close_tdb( info->etdb, True );
     597           0 :         become_root();
     598           0 :         info->etdb = elog_open_tdb( info->logname, True, False );
     599           0 :         unbecome_root();
     600             : 
     601           0 :         if ( !info->etdb )
     602           0 :                 return NT_STATUS_ACCESS_DENIED;
     603             : 
     604           0 :         return NT_STATUS_OK;
     605             : }
     606             : 
     607             : /********************************************************************
     608             :  _eventlog_CloseEventLog
     609             :  ********************************************************************/
     610             : 
     611          12 : NTSTATUS _eventlog_CloseEventLog(struct pipes_struct * p,
     612             :                                  struct eventlog_CloseEventLog *r)
     613             : {
     614           0 :         NTSTATUS status;
     615             : 
     616          12 :         status = elog_close( p, r->in.handle );
     617          12 :         if (!NT_STATUS_IS_OK(status)) {
     618           0 :                 return status;
     619             :         }
     620             : 
     621          12 :         ZERO_STRUCTP(r->out.handle);
     622             : 
     623          12 :         return NT_STATUS_OK;
     624             : }
     625             : 
     626             : /********************************************************************
     627             :  _eventlog_ReadEventLogW
     628             :  ********************************************************************/
     629             : 
     630           4 : NTSTATUS _eventlog_ReadEventLogW(struct pipes_struct *p,
     631             :                                  struct eventlog_ReadEventLogW *r)
     632             : {
     633           4 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
     634           0 :         int bytes_left, record_number;
     635           0 :         uint32_t elog_read_type, elog_read_dir;
     636             : 
     637           4 :         if (!info) {
     638           0 :                 return NT_STATUS_INVALID_HANDLE;
     639             :         }
     640             : 
     641           4 :         info->flags  = r->in.flags;
     642           4 :         bytes_left      = r->in.number_of_bytes;
     643             : 
     644           4 :         if (!info->etdb) {
     645           0 :                 return NT_STATUS_ACCESS_DENIED;
     646             :         }
     647             : 
     648             :         /* check for valid flags.  Can't use the sequential and seek flags together */
     649             : 
     650           4 :         elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
     651           4 :         elog_read_dir  = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
     652             : 
     653           4 :         if (r->in.flags == 0 ||
     654           2 :             elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
     655           0 :             elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
     656             :         {
     657           2 :                 DEBUG(3,("_eventlog_ReadEventLogW: "
     658             :                         "Invalid flags [0x%08x] for ReadEventLog\n",
     659             :                         r->in.flags));
     660           2 :                 return NT_STATUS_INVALID_PARAMETER;
     661             :         }
     662             : 
     663             :         /* a sequential read should ignore the offset */
     664             : 
     665           2 :         if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
     666           2 :                 record_number = info->current_record;
     667             :         } else {
     668           0 :                 record_number = r->in.offset;
     669             :         }
     670             : 
     671           2 :         if (r->in.number_of_bytes == 0) {
     672           0 :                 struct EVENTLOGRECORD *e;
     673           2 :                 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
     674             :                                       record_number);
     675           2 :                 if (!e) {
     676           2 :                         return NT_STATUS_END_OF_FILE;
     677             :                 }
     678           0 :                 *r->out.real_size = e->Length;
     679           0 :                 return NT_STATUS_BUFFER_TOO_SMALL;
     680             :         }
     681             : 
     682           0 :         while (bytes_left > 0) {
     683             : 
     684           0 :                 DATA_BLOB blob;
     685           0 :                 enum ndr_err_code ndr_err;
     686           0 :                 struct EVENTLOGRECORD *e;
     687             : 
     688           0 :                 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
     689             :                                       record_number);
     690           0 :                 if (!e) {
     691           0 :                         break;
     692             :                 }
     693             : 
     694           0 :                 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, e,
     695             :                               (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
     696           0 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     697           0 :                         return ndr_map_error2ntstatus(ndr_err);
     698             :                 }
     699             : 
     700           0 :                 if (DEBUGLEVEL >= 10) {
     701           0 :                         NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
     702             :                 }
     703             : 
     704           0 :                 if (blob.length > r->in.number_of_bytes) {
     705           0 :                         *r->out.real_size = blob.length;
     706           0 :                         return NT_STATUS_BUFFER_TOO_SMALL;
     707             :                 }
     708             : 
     709           0 :                 if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
     710           0 :                         break;
     711             :                 }
     712             : 
     713           0 :                 bytes_left -= blob.length;
     714             : 
     715           0 :                 if (info->flags & EVENTLOG_FORWARDS_READ) {
     716           0 :                         record_number++;
     717             :                 } else {
     718           0 :                         record_number--;
     719             :                 }
     720             : 
     721             :                 /* update the eventlog record pointer */
     722             : 
     723           0 :                 info->current_record = record_number;
     724             : 
     725           0 :                 memcpy(&r->out.data[*(r->out.sent_size)],
     726           0 :                        blob.data, blob.length);
     727           0 :                 *(r->out.sent_size) += blob.length;
     728             :         }
     729             : 
     730           0 :         if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
     731           0 :                 return NT_STATUS_END_OF_FILE;
     732             :         }
     733             : 
     734           0 :         return NT_STATUS_OK;
     735             : }
     736             : 
     737             : /********************************************************************
     738             :  _eventlog_GetOldestRecord
     739             :  ********************************************************************/
     740             : 
     741           0 : NTSTATUS _eventlog_GetOldestRecord(struct pipes_struct *p,
     742             :                                    struct eventlog_GetOldestRecord *r)
     743             : {
     744           0 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
     745             : 
     746           0 :         if (info == NULL) {
     747           0 :                 return NT_STATUS_INVALID_HANDLE;
     748             :         }
     749             : 
     750           0 :         if ( !( get_oldest_entry_hook( info ) ) )
     751           0 :                 return NT_STATUS_ACCESS_DENIED;
     752             : 
     753           0 :         *r->out.oldest_entry = info->oldest_entry;
     754             : 
     755           0 :         return NT_STATUS_OK;
     756             : }
     757             : 
     758             : /********************************************************************
     759             : _eventlog_GetNumRecords
     760             :  ********************************************************************/
     761             : 
     762           2 : NTSTATUS _eventlog_GetNumRecords(struct pipes_struct *p,
     763             :                                  struct eventlog_GetNumRecords *r)
     764             : {
     765           2 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
     766             : 
     767           2 :         if (info == NULL) {
     768           0 :                 return NT_STATUS_INVALID_HANDLE;
     769             :         }
     770             : 
     771           2 :         if ( !( get_num_records_hook( info ) ) )
     772           0 :                 return NT_STATUS_ACCESS_DENIED;
     773             : 
     774           2 :         *r->out.number = info->num_records;
     775             : 
     776           2 :         return NT_STATUS_OK;
     777             : }
     778             : 
     779           0 : NTSTATUS _eventlog_BackupEventLogW(struct pipes_struct *p, struct eventlog_BackupEventLogW *r)
     780             : {
     781           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     782           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     783             : }
     784             : 
     785             : /********************************************************************
     786             : _eventlog_GetLogInformation
     787             :  ********************************************************************/
     788             : 
     789           6 : NTSTATUS _eventlog_GetLogInformation(struct pipes_struct *p,
     790             :                                      struct eventlog_GetLogInformation *r)
     791             : {
     792           6 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
     793           0 :         struct EVENTLOG_FULL_INFORMATION f;
     794           0 :         enum ndr_err_code ndr_err;
     795           0 :         DATA_BLOB blob;
     796             : 
     797           6 :         if (!info) {
     798           0 :                 return NT_STATUS_INVALID_HANDLE;
     799             :         }
     800             : 
     801           6 :         if (r->in.level != 0) {
     802           2 :                 return NT_STATUS_INVALID_LEVEL;
     803             :         }
     804             : 
     805           4 :         *r->out.bytes_needed = 4;
     806             : 
     807           4 :         if (r->in.buf_size < 4) {
     808           2 :                 return NT_STATUS_BUFFER_TOO_SMALL;
     809             :         }
     810             : 
     811             :         /* FIXME: this should be retrieved from the handle */
     812           2 :         f.full = false;
     813             : 
     814           2 :         ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &f,
     815             :                       (ndr_push_flags_fn_t)ndr_push_EVENTLOG_FULL_INFORMATION);
     816           2 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     817           0 :                 return ndr_map_error2ntstatus(ndr_err);
     818             :         }
     819             : 
     820           2 :         if (DEBUGLEVEL >= 10) {
     821           0 :                 NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION, &f);
     822             :         }
     823             : 
     824           2 :         memcpy(r->out.buffer, blob.data, 4);
     825             : 
     826           2 :         return NT_STATUS_OK;
     827             : }
     828             : 
     829             : /********************************************************************
     830             : _eventlog_FlushEventLog
     831             :  ********************************************************************/
     832             : 
     833           2 : NTSTATUS _eventlog_FlushEventLog(struct pipes_struct *p,
     834             :                                  struct eventlog_FlushEventLog *r)
     835             : {
     836           2 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
     837           2 :         if (!info) {
     838           0 :                 return NT_STATUS_INVALID_HANDLE;
     839             :         }
     840             : 
     841           2 :         return NT_STATUS_ACCESS_DENIED;
     842             : }
     843             : 
     844             : /********************************************************************
     845             :  ********************************************************************/
     846             : 
     847           2 : static NTSTATUS evlog_report_to_record(TALLOC_CTX *mem_ctx,
     848             :                                        const struct eventlog_ReportEventW *r,
     849             :                                        const char *logname,
     850             :                                        struct EVENTLOGRECORD *e)
     851             : {
     852           0 :         uint32_t i;
     853           2 :         ZERO_STRUCTP(e);
     854             : 
     855           2 :         e->TimeGenerated     = r->in.timestamp;
     856           2 :         e->TimeWritten               = time(NULL);
     857           2 :         e->EventID           = r->in.event_id;
     858           2 :         e->EventType         = r->in.event_type;
     859           2 :         e->NumStrings                = r->in.num_of_strings;
     860           2 :         e->EventCategory     = r->in.event_category;
     861           2 :         e->ReservedFlags     = r->in.flags;
     862           2 :         e->DataLength                = r->in.data_size;
     863           2 :         e->SourceName                = talloc_strdup(mem_ctx, logname);
     864           2 :         NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
     865           2 :         if (r->in.servername->string) {
     866           0 :                 e->Computername      = r->in.servername->string;
     867             :         } else {
     868           2 :                 e->Computername      = talloc_strdup(mem_ctx, "");
     869           2 :                 NT_STATUS_HAVE_NO_MEMORY(e->Computername);
     870             :         }
     871           2 :         if (r->in.user_sid) {
     872           0 :                 e->UserSid   = *r->in.user_sid;
     873             :         }
     874           2 :         e->Strings           = talloc_array(mem_ctx, const char *, e->NumStrings);
     875           2 :         NT_STATUS_HAVE_NO_MEMORY(e->Strings);
     876             : 
     877           4 :         for (i=0; i < e->NumStrings; i++) {
     878           4 :                 e->Strings[i] = talloc_strdup(e->Strings,
     879           2 :                                               r->in.strings[i]->string);
     880           2 :                 NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
     881             :         }
     882           2 :         e->Data                      = r->in.data;
     883             : 
     884           2 :         return NT_STATUS_OK;
     885             : }
     886             : 
     887             : /********************************************************************
     888             : _eventlog_ReportEventW
     889             :  ********************************************************************/
     890             : 
     891           2 : NTSTATUS _eventlog_ReportEventW(struct pipes_struct *p,
     892             :                                 struct eventlog_ReportEventW *r)
     893             : {
     894           0 :         NTSTATUS status;
     895           0 :         struct EVENTLOGRECORD record;
     896             : 
     897           2 :         EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
     898           2 :         if (!info) {
     899           0 :                 return NT_STATUS_INVALID_HANDLE;
     900             :         }
     901             : 
     902           2 :         status = evlog_report_to_record(p->mem_ctx, r, info->logname, &record);
     903           2 :         if (!NT_STATUS_IS_OK(status)) {
     904           0 :                 return status;
     905             :         }
     906             : 
     907           2 :         status = evlog_push_record(p->mem_ctx,
     908           2 :                                    ELOG_TDB_CTX(info->etdb),
     909             :                                    &record,
     910             :                                    r->out.record_number);
     911           2 :         if (!NT_STATUS_IS_OK(status)) {
     912           0 :                 return status;
     913             :         }
     914             : 
     915           2 :         return NT_STATUS_OK;
     916             : }
     917             : 
     918             : /********************************************************************
     919             :  ********************************************************************/
     920             : 
     921           0 : NTSTATUS _eventlog_DeregisterEventSource(struct pipes_struct *p,
     922             :                                          struct eventlog_DeregisterEventSource *r)
     923             : {
     924           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     925           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     926             : }
     927             : 
     928           0 : NTSTATUS _eventlog_ChangeNotify(struct pipes_struct *p,
     929             :                                 struct eventlog_ChangeNotify *r)
     930             : {
     931           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     932           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     933             : }
     934             : 
     935           0 : NTSTATUS _eventlog_RegisterEventSourceW(struct pipes_struct *p,
     936             :                                         struct eventlog_RegisterEventSourceW *r)
     937             : {
     938           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     939           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     940             : }
     941             : 
     942           0 : NTSTATUS _eventlog_OpenBackupEventLogW(struct pipes_struct *p,
     943             :                                        struct eventlog_OpenBackupEventLogW *r)
     944             : {
     945           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     946           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     947             : }
     948             : 
     949           0 : NTSTATUS _eventlog_ClearEventLogA(struct pipes_struct *p,
     950             :                                   struct eventlog_ClearEventLogA *r)
     951             : {
     952           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     953           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     954             : }
     955             : 
     956           0 : NTSTATUS _eventlog_BackupEventLogA(struct pipes_struct *p,
     957             :                                    struct eventlog_BackupEventLogA *r)
     958             : {
     959           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     960           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     961             : }
     962             : 
     963           0 : NTSTATUS _eventlog_OpenEventLogA(struct pipes_struct *p,
     964             :                                  struct eventlog_OpenEventLogA *r)
     965             : {
     966           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     967           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     968             : }
     969             : 
     970           0 : NTSTATUS _eventlog_RegisterEventSourceA(struct pipes_struct *p,
     971             :                                         struct eventlog_RegisterEventSourceA *r)
     972             : {
     973           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     974           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     975             : }
     976             : 
     977           0 : NTSTATUS _eventlog_OpenBackupEventLogA(struct pipes_struct *p,
     978             :                                        struct eventlog_OpenBackupEventLogA *r)
     979             : {
     980           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     981           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     982             : }
     983             : 
     984           0 : NTSTATUS _eventlog_ReadEventLogA(struct pipes_struct *p,
     985             :                                  struct eventlog_ReadEventLogA *r)
     986             : {
     987           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     988           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     989             : }
     990             : 
     991           0 : NTSTATUS _eventlog_ReportEventA(struct pipes_struct *p,
     992             :                                 struct eventlog_ReportEventA *r)
     993             : {
     994           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     995           0 :         return NT_STATUS_NOT_IMPLEMENTED;
     996             : }
     997             : 
     998           0 : NTSTATUS _eventlog_RegisterClusterSvc(struct pipes_struct *p,
     999             :                                       struct eventlog_RegisterClusterSvc *r)
    1000             : {
    1001           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1002           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    1003             : }
    1004             : 
    1005           0 : NTSTATUS _eventlog_DeregisterClusterSvc(struct pipes_struct *p,
    1006             :                                         struct eventlog_DeregisterClusterSvc *r)
    1007             : {
    1008           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1009           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    1010             : }
    1011             : 
    1012           0 : NTSTATUS _eventlog_WriteClusterEvents(struct pipes_struct *p,
    1013             :                                       struct eventlog_WriteClusterEvents *r)
    1014             : {
    1015           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1016           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    1017             : }
    1018             : 
    1019           0 : NTSTATUS _eventlog_ReportEventAndSourceW(struct pipes_struct *p,
    1020             :                                          struct eventlog_ReportEventAndSourceW *r)
    1021             : {
    1022           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1023           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    1024             : }
    1025             : 
    1026             : static NTSTATUS eventlog__op_init_server(struct dcesrv_context *dce_ctx,
    1027             :                 const struct dcesrv_endpoint_server *ep_server);
    1028             : 
    1029             : #define DCESRV_INTERFACE_EVENTLOG_INIT_SERVER \
    1030             :         eventlog_init_server
    1031             : 
    1032         128 : static NTSTATUS eventlog_init_server(struct dcesrv_context *dce_ctx,
    1033             :                 const struct dcesrv_endpoint_server *ep_server)
    1034             : {
    1035         128 :         struct messaging_context *msg_ctx = global_messaging_context();
    1036           0 :         bool ok;
    1037             : 
    1038         128 :         ok = eventlog_init_winreg(msg_ctx);
    1039         128 :         if (!ok) {
    1040           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1041             :         }
    1042             : 
    1043         128 :         return eventlog__op_init_server(dce_ctx, ep_server);
    1044             : }
    1045             : 
    1046             : /* include the generated boilerplate */
    1047             : #include "librpc/gen_ndr/ndr_eventlog_scompat.c"

Generated by: LCOV version 1.14