s3:ntlm_auth: make logs more consistent with length check
[Samba.git] / source3 / rpc_server / eventlog / srv_eventlog_nt.c
bloba946c5731437bb5a70f5bb02ae1b10cbe07a1086
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.
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.
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.
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/>.
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"
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"
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_RPC_SRV
44 #define TOP_LEVEL_EVENTLOG_KEY "SYSTEM\\CurrentControlSet\\Services\\Eventlog"
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;
56 /********************************************************************
57 ********************************************************************/
59 static int eventlog_info_destructor(EVENTLOG_INFO *elog)
61 if (elog->etdb) {
62 elog_close_tdb(elog->etdb, false);
64 return 0;
67 /********************************************************************
68 ********************************************************************/
70 static EVENTLOG_INFO *find_eventlog_info_by_hnd( struct pipes_struct * p,
71 struct policy_handle * handle )
73 EVENTLOG_INFO *info;
74 NTSTATUS status;
76 info = find_policy_by_hnd(p,
77 handle,
78 DCESRV_HANDLE_ANY,
79 EVENTLOG_INFO,
80 &status);
81 if (!NT_STATUS_IS_OK(status)) {
82 DEBUG( 2,
83 ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
84 return NULL;
87 return info;
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.
97 ********************************************************************/
99 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)
105 TALLOC_CTX *frame = talloc_stackframe();
106 struct conn_struct_tos *c = NULL;
107 NTSTATUS status = NT_STATUS_OK;
108 struct smb_filename *pathref_fname = NULL;
110 if (!posix_locking_init(false)) {
111 TALLOC_FREE(frame);
112 return NT_STATUS_NO_MEMORY;
115 status = create_conn_struct_tos(global_messaging_context(),
117 "/",
118 session_info,
119 &c);
120 if (!NT_STATUS_IS_OK(status)) {
121 DBG_ERR("create_conn_struct_tos() returned %s.\n",
122 nt_errstr(status));
123 TALLOC_FREE(frame);
124 return status;
127 status = synthetic_pathref(talloc_tos(),
128 c->conn->cwd_fsp,
129 fname,
130 NULL,
131 NULL,
134 &pathref_fname);
135 if (!NT_STATUS_IS_OK(status)) {
136 DBG_ERR("synthetic_pathref for file %s returned %s.\n",
137 fname, nt_errstr(status));
138 TALLOC_FREE(frame);
139 return status;
141 status = SMB_VFS_FGET_NT_ACL(pathref_fname->fsp,
142 security_info_wanted,
143 ctx,
144 sd);
145 if (!NT_STATUS_IS_OK(status)) {
146 DBG_ERR("SMB_VFS_FGET_NT_ACL for file %s returned %s.\n",
147 fname, nt_errstr(status));
150 TALLOC_FREE(frame);
152 return status;
155 /********************************************************************
156 ********************************************************************/
158 static bool elog_check_access(EVENTLOG_INFO *info,
159 struct auth_session_info *session_info)
161 const struct security_token *token = session_info->security_token;
162 char *tdbname = elog_tdbname(talloc_tos(), info->logname );
163 struct security_descriptor *sec_desc;
164 struct security_ace *ace;
165 NTSTATUS status;
167 if ( !tdbname )
168 return False;
170 /* get the security descriptor for the file */
172 status = get_nt_acl_no_snum( info,
173 session_info,
174 tdbname,
175 SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL,
176 &sec_desc);
177 if (!NT_STATUS_IS_OK(status)) {
178 DEBUG(5,("elog_check_access: Unable to get NT ACL for %s: %s\n",
179 tdbname, nt_errstr(status)));
180 TALLOC_FREE(tdbname);
181 return False;
183 TALLOC_FREE(tdbname);
185 ace = talloc_zero(sec_desc, struct security_ace);
186 if (ace == NULL) {
187 TALLOC_FREE(sec_desc);
188 return false;
191 ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
192 ace->flags = 0;
193 ace->access_mask = REG_KEY_ALL;
194 ace->trustee = global_sid_System;
196 status = security_descriptor_dacl_add(sec_desc, ace);
197 if (!NT_STATUS_IS_OK(status)) {
198 TALLOC_FREE(sec_desc);
199 return false;
202 /* root free pass */
204 if ( geteuid() == sec_initial_uid() ) {
205 DEBUG(5,("elog_check_access: running as root, using system token\n"));
206 token = get_system_token();
209 /* run the check, try for the max allowed */
211 status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
212 &info->access_granted);
214 TALLOC_FREE(sec_desc);
216 if (!NT_STATUS_IS_OK(status)) {
217 DEBUG(8,("elog_check_access: se_access_check() return %s\n",
218 nt_errstr(status)));
219 return False;
222 /* we have to have READ permission for a successful open */
224 return ( info->access_granted & SEC_FILE_READ_DATA );
227 /********************************************************************
228 ********************************************************************/
230 static bool elog_validate_logname( const char *name )
232 int i;
233 const char **elogs = lp_eventlog_list();
235 if (!elogs) {
236 return False;
239 for ( i=0; elogs[i]; i++ ) {
240 if ( strequal( name, elogs[i] ) )
241 return True;
244 return False;
247 /********************************************************************
248 ********************************************************************/
250 static bool get_num_records_hook( EVENTLOG_INFO * info )
252 int next_record;
253 int oldest_record;
255 if ( !info->etdb ) {
256 DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
257 return False;
260 /* lock the tdb since we have to get 2 records */
262 tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
263 next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
264 oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
265 tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
267 DEBUG( 8,
268 ( "Oldest Record %d; Next Record %d\n", oldest_record,
269 next_record ) );
271 info->num_records = ( next_record - oldest_record );
272 info->oldest_entry = oldest_record;
274 return True;
277 /********************************************************************
278 ********************************************************************/
280 static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
282 /* it's the same thing */
283 return get_num_records_hook( info );
286 /********************************************************************
287 ********************************************************************/
289 static NTSTATUS elog_open( struct pipes_struct * p, const char *logname, struct policy_handle *hnd )
291 struct dcesrv_call_state *dce_call = p->dce_call;
292 struct auth_session_info *session_info =
293 dcesrv_call_session_info(dce_call);
294 EVENTLOG_INFO *elog;
296 /* first thing is to validate the eventlog name */
298 if ( !elog_validate_logname( logname ) )
299 return NT_STATUS_OBJECT_PATH_INVALID;
301 if ( !(elog = talloc_zero( NULL, EVENTLOG_INFO )) )
302 return NT_STATUS_NO_MEMORY;
303 talloc_set_destructor(elog, eventlog_info_destructor);
305 elog->logname = talloc_strdup( elog, logname );
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 */
312 become_root();
313 elog->etdb = elog_open_tdb( elog->logname, False, False );
314 unbecome_root();
316 if ( !elog->etdb ) {
317 /* according to MSDN, if the logfile cannot be found, we should
318 default to the "Application" log */
320 if ( !strequal( logname, ELOG_APPL ) ) {
322 TALLOC_FREE( elog->logname );
324 elog->logname = talloc_strdup( elog, ELOG_APPL );
326 /* do the access check */
327 if ( !elog_check_access( elog, session_info) ) {
328 TALLOC_FREE( elog );
329 return NT_STATUS_ACCESS_DENIED;
332 become_root();
333 elog->etdb = elog_open_tdb( elog->logname, False, False );
334 unbecome_root();
337 if ( !elog->etdb ) {
338 TALLOC_FREE( elog );
339 return NT_STATUS_ACCESS_DENIED; /* ??? */
343 /* now do the access check. Close the tdb if we fail here */
345 if ( !elog_check_access( elog, session_info) ) {
346 TALLOC_FREE( elog );
347 return NT_STATUS_ACCESS_DENIED;
350 /* create the policy handle */
352 if ( !create_policy_hnd( p, hnd, 0, elog ) ) {
353 TALLOC_FREE(elog);
354 return NT_STATUS_NO_MEMORY;
357 /* set the initial current_record pointer */
359 if ( !get_oldest_entry_hook( elog ) ) {
360 DEBUG(3,("elog_open: Successfully opened eventlog but can't "
361 "get any information on internal records!\n"));
364 elog->current_record = elog->oldest_entry;
366 return NT_STATUS_OK;
369 /********************************************************************
370 ********************************************************************/
372 static NTSTATUS elog_close( struct pipes_struct *p, struct policy_handle *hnd )
374 if ( !( close_policy_hnd( p, hnd ) ) ) {
375 return NT_STATUS_INVALID_HANDLE;
378 return NT_STATUS_OK;
381 /*******************************************************************
382 *******************************************************************/
384 static int elog_size( EVENTLOG_INFO *info )
386 if ( !info || !info->etdb ) {
387 DEBUG(0,("elog_size: Invalid info* structure!\n"));
388 return 0;
391 return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
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 ********************************************************************/
399 static bool sync_eventlog_params(TALLOC_CTX *mem_ctx,
400 struct messaging_context *msg_ctx,
401 EVENTLOG_INFO *info)
403 struct dcerpc_binding_handle *h = NULL;
404 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
405 struct policy_handle hive_hnd, key_hnd;
406 uint32_t uiMaxSize = 0;
407 uint32_t uiRetention = 0;
408 char *path = NULL;
409 NTSTATUS status;
410 WERROR wresult = WERR_OK;
411 char *elogname = info->logname;
412 TALLOC_CTX *ctx;
413 bool ret = false;
415 ctx = talloc_stackframe();
416 if (ctx == NULL) {
417 return false;
420 DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
422 if ( !info->etdb ) {
423 DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
424 goto done;
426 /* set reasonable defaults. 512Kb on size and 1 week on time */
428 uiMaxSize = 0x80000;
429 uiRetention = 604800;
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 path = talloc_asprintf(ctx, "%s\\%s", TOP_LEVEL_EVENTLOG_KEY, elogname);
436 if (!path) {
437 goto done;
440 status = dcerpc_winreg_int_hklm_openkey(ctx,
441 get_session_info_system(),
442 msg_ctx,
444 path,
445 false,
446 access_mask,
447 &hive_hnd,
448 &key_hnd,
449 &wresult);
450 if (!NT_STATUS_IS_OK(status)) {
451 DEBUG(4,("sync_eventlog_params: Failed to open key [%s] (%s)\n",
452 path, nt_errstr(status)));
453 goto done;
455 if ( !W_ERROR_IS_OK( wresult ) ) {
456 DEBUG( 4,
457 ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
458 path, win_errstr( wresult ) ) );
459 goto done;
462 status = dcerpc_winreg_query_dword(ctx,
464 &key_hnd,
465 "Retention",
466 &uiRetention,
467 &wresult);
468 if (!NT_STATUS_IS_OK(status)) {
469 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
470 nt_errstr(status)));
471 goto done;
473 if (!W_ERROR_IS_OK(wresult)) {
474 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
475 win_errstr(wresult)));
476 goto done;
479 status = dcerpc_winreg_query_dword(ctx,
481 &key_hnd,
482 "MaxSize",
483 &uiMaxSize,
484 &wresult);
485 if (!NT_STATUS_IS_OK(status)) {
486 DEBUG(4, ("Failed to query value \"Retention\": %s\n",
487 nt_errstr(status)));
488 goto done;
490 if (!W_ERROR_IS_OK(wresult)) {
491 DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
492 win_errstr(wresult)));
493 goto done;
496 tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
497 tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
499 ret = true;
501 done:
502 if (h != NULL) {
503 WERROR ignore;
505 if (is_valid_policy_hnd(&key_hnd)) {
506 dcerpc_winreg_CloseKey(h, ctx, &key_hnd, &ignore);
508 if (is_valid_policy_hnd(&hive_hnd)) {
509 dcerpc_winreg_CloseKey(h, ctx, &hive_hnd, &ignore);
513 TALLOC_FREE(ctx);
514 return ret;
517 /********************************************************************
518 _eventlog_OpenEventLogW
519 ********************************************************************/
521 NTSTATUS _eventlog_OpenEventLogW(struct pipes_struct *p,
522 struct eventlog_OpenEventLogW *r)
524 EVENTLOG_INFO *info;
525 NTSTATUS result;
527 DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
528 r->in.servername->string, r->in.logname->string ));
530 /* according to MSDN, if the logfile cannot be found, we should
531 default to the "Application" log */
533 if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) )
534 return result;
536 if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) {
537 DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
538 r->in.logname->string ));
539 elog_close( p, r->out.handle );
540 return NT_STATUS_INVALID_HANDLE;
543 DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
545 if (!sync_eventlog_params(p->mem_ctx,
546 p->msg_ctx,
547 info)) {
548 elog_close(p, r->out.handle);
549 return NT_STATUS_EVENTLOG_FILE_CORRUPT;
551 prune_eventlog( ELOG_TDB_CTX(info->etdb) );
553 return NT_STATUS_OK;
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. */
574 NTSTATUS _eventlog_ClearEventLogW(struct pipes_struct *p,
575 struct eventlog_ClearEventLogW *r)
577 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
579 if ( !info )
580 return NT_STATUS_INVALID_HANDLE;
582 if (r->in.backupfile && r->in.backupfile->string) {
584 DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
585 "file name for log [%s].\n",
586 r->in.backupfile->string, info->logname ) );
589 /* check for WRITE access to the file */
591 if ( !(info->access_granted & SEC_FILE_WRITE_DATA) )
592 return NT_STATUS_ACCESS_DENIED;
594 /* Force a close and reopen */
596 elog_close_tdb( info->etdb, True );
597 become_root();
598 info->etdb = elog_open_tdb( info->logname, True, False );
599 unbecome_root();
601 if ( !info->etdb )
602 return NT_STATUS_ACCESS_DENIED;
604 return NT_STATUS_OK;
607 /********************************************************************
608 _eventlog_CloseEventLog
609 ********************************************************************/
611 NTSTATUS _eventlog_CloseEventLog(struct pipes_struct * p,
612 struct eventlog_CloseEventLog *r)
614 NTSTATUS status;
616 status = elog_close( p, r->in.handle );
617 if (!NT_STATUS_IS_OK(status)) {
618 return status;
621 ZERO_STRUCTP(r->out.handle);
623 return NT_STATUS_OK;
626 /********************************************************************
627 _eventlog_ReadEventLogW
628 ********************************************************************/
630 NTSTATUS _eventlog_ReadEventLogW(struct pipes_struct *p,
631 struct eventlog_ReadEventLogW *r)
633 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
634 int bytes_left, record_number;
635 uint32_t elog_read_type, elog_read_dir;
637 if (!info) {
638 return NT_STATUS_INVALID_HANDLE;
641 info->flags = r->in.flags;
642 bytes_left = r->in.number_of_bytes;
644 if (!info->etdb) {
645 return NT_STATUS_ACCESS_DENIED;
648 /* check for valid flags. Can't use the sequential and seek flags together */
650 elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
651 elog_read_dir = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
653 if (r->in.flags == 0 ||
654 elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
655 elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
657 DEBUG(3,("_eventlog_ReadEventLogW: "
658 "Invalid flags [0x%08x] for ReadEventLog\n",
659 r->in.flags));
660 return NT_STATUS_INVALID_PARAMETER;
663 /* a sequential read should ignore the offset */
665 if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
666 record_number = info->current_record;
667 } else {
668 record_number = r->in.offset;
671 if (r->in.number_of_bytes == 0) {
672 struct EVENTLOGRECORD *e;
673 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
674 record_number);
675 if (!e) {
676 return NT_STATUS_END_OF_FILE;
678 *r->out.real_size = e->Length;
679 return NT_STATUS_BUFFER_TOO_SMALL;
682 while (bytes_left > 0) {
684 DATA_BLOB blob;
685 enum ndr_err_code ndr_err;
686 struct EVENTLOGRECORD *e;
688 e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
689 record_number);
690 if (!e) {
691 break;
694 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, e,
695 (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
696 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
697 return ndr_map_error2ntstatus(ndr_err);
700 if (DEBUGLEVEL >= 10) {
701 NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
704 if (blob.length > r->in.number_of_bytes) {
705 *r->out.real_size = blob.length;
706 return NT_STATUS_BUFFER_TOO_SMALL;
709 if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
710 break;
713 bytes_left -= blob.length;
715 if (info->flags & EVENTLOG_FORWARDS_READ) {
716 record_number++;
717 } else {
718 record_number--;
721 /* update the eventlog record pointer */
723 info->current_record = record_number;
725 memcpy(&r->out.data[*(r->out.sent_size)],
726 blob.data, blob.length);
727 *(r->out.sent_size) += blob.length;
730 if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
731 return NT_STATUS_END_OF_FILE;
734 return NT_STATUS_OK;
737 /********************************************************************
738 _eventlog_GetOldestRecord
739 ********************************************************************/
741 NTSTATUS _eventlog_GetOldestRecord(struct pipes_struct *p,
742 struct eventlog_GetOldestRecord *r)
744 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
746 if (info == NULL) {
747 return NT_STATUS_INVALID_HANDLE;
750 if ( !( get_oldest_entry_hook( info ) ) )
751 return NT_STATUS_ACCESS_DENIED;
753 *r->out.oldest_entry = info->oldest_entry;
755 return NT_STATUS_OK;
758 /********************************************************************
759 _eventlog_GetNumRecords
760 ********************************************************************/
762 NTSTATUS _eventlog_GetNumRecords(struct pipes_struct *p,
763 struct eventlog_GetNumRecords *r)
765 EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
767 if (info == NULL) {
768 return NT_STATUS_INVALID_HANDLE;
771 if ( !( get_num_records_hook( info ) ) )
772 return NT_STATUS_ACCESS_DENIED;
774 *r->out.number = info->num_records;
776 return NT_STATUS_OK;
779 NTSTATUS _eventlog_BackupEventLogW(struct pipes_struct *p, struct eventlog_BackupEventLogW *r)
781 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
782 return NT_STATUS_NOT_IMPLEMENTED;
785 /********************************************************************
786 _eventlog_GetLogInformation
787 ********************************************************************/
789 NTSTATUS _eventlog_GetLogInformation(struct pipes_struct *p,
790 struct eventlog_GetLogInformation *r)
792 EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
793 struct EVENTLOG_FULL_INFORMATION f;
794 enum ndr_err_code ndr_err;
795 DATA_BLOB blob;
797 if (!info) {
798 return NT_STATUS_INVALID_HANDLE;
801 if (r->in.level != 0) {
802 return NT_STATUS_INVALID_LEVEL;
805 *r->out.bytes_needed = 4;
807 if (r->in.buf_size < 4) {
808 return NT_STATUS_BUFFER_TOO_SMALL;
811 /* FIXME: this should be retrieved from the handle */
812 f.full = false;
814 ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, &f,
815 (ndr_push_flags_fn_t)ndr_push_EVENTLOG_FULL_INFORMATION);
816 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
817 return ndr_map_error2ntstatus(ndr_err);
820 if (DEBUGLEVEL >= 10) {
821 NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION, &f);
824 memcpy(r->out.buffer, blob.data, 4);
826 return NT_STATUS_OK;
829 /********************************************************************
830 _eventlog_FlushEventLog
831 ********************************************************************/
833 NTSTATUS _eventlog_FlushEventLog(struct pipes_struct *p,
834 struct eventlog_FlushEventLog *r)
836 EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
837 if (!info) {
838 return NT_STATUS_INVALID_HANDLE;
841 return NT_STATUS_ACCESS_DENIED;
844 /********************************************************************
845 ********************************************************************/
847 static NTSTATUS evlog_report_to_record(TALLOC_CTX *mem_ctx,
848 const struct eventlog_ReportEventW *r,
849 const char *logname,
850 struct EVENTLOGRECORD *e)
852 uint32_t i;
853 ZERO_STRUCTP(e);
855 e->TimeGenerated = r->in.timestamp;
856 e->TimeWritten = time(NULL);
857 e->EventID = r->in.event_id;
858 e->EventType = r->in.event_type;
859 e->NumStrings = r->in.num_of_strings;
860 e->EventCategory = r->in.event_category;
861 e->ReservedFlags = r->in.flags;
862 e->DataLength = r->in.data_size;
863 e->SourceName = talloc_strdup(mem_ctx, logname);
864 NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
865 if (r->in.servername->string) {
866 e->Computername = r->in.servername->string;
867 } else {
868 e->Computername = talloc_strdup(mem_ctx, "");
869 NT_STATUS_HAVE_NO_MEMORY(e->Computername);
871 if (r->in.user_sid) {
872 e->UserSid = *r->in.user_sid;
874 e->Strings = talloc_array(mem_ctx, const char *, e->NumStrings);
875 NT_STATUS_HAVE_NO_MEMORY(e->Strings);
877 for (i=0; i < e->NumStrings; i++) {
878 e->Strings[i] = talloc_strdup(e->Strings,
879 r->in.strings[i]->string);
880 NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
882 e->Data = r->in.data;
884 return NT_STATUS_OK;
887 /********************************************************************
888 _eventlog_ReportEventW
889 ********************************************************************/
891 NTSTATUS _eventlog_ReportEventW(struct pipes_struct *p,
892 struct eventlog_ReportEventW *r)
894 NTSTATUS status;
895 struct EVENTLOGRECORD record;
897 EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
898 if (!info) {
899 return NT_STATUS_INVALID_HANDLE;
902 status = evlog_report_to_record(p->mem_ctx, r, info->logname, &record);
903 if (!NT_STATUS_IS_OK(status)) {
904 return status;
907 status = evlog_push_record(p->mem_ctx,
908 ELOG_TDB_CTX(info->etdb),
909 &record,
910 r->out.record_number);
911 if (!NT_STATUS_IS_OK(status)) {
912 return status;
915 return NT_STATUS_OK;
918 /********************************************************************
919 ********************************************************************/
921 NTSTATUS _eventlog_DeregisterEventSource(struct pipes_struct *p,
922 struct eventlog_DeregisterEventSource *r)
924 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
925 return NT_STATUS_NOT_IMPLEMENTED;
928 NTSTATUS _eventlog_ChangeNotify(struct pipes_struct *p,
929 struct eventlog_ChangeNotify *r)
931 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
932 return NT_STATUS_NOT_IMPLEMENTED;
935 NTSTATUS _eventlog_RegisterEventSourceW(struct pipes_struct *p,
936 struct eventlog_RegisterEventSourceW *r)
938 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
939 return NT_STATUS_NOT_IMPLEMENTED;
942 NTSTATUS _eventlog_OpenBackupEventLogW(struct pipes_struct *p,
943 struct eventlog_OpenBackupEventLogW *r)
945 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
946 return NT_STATUS_NOT_IMPLEMENTED;
949 NTSTATUS _eventlog_ClearEventLogA(struct pipes_struct *p,
950 struct eventlog_ClearEventLogA *r)
952 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
953 return NT_STATUS_NOT_IMPLEMENTED;
956 NTSTATUS _eventlog_BackupEventLogA(struct pipes_struct *p,
957 struct eventlog_BackupEventLogA *r)
959 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
960 return NT_STATUS_NOT_IMPLEMENTED;
963 NTSTATUS _eventlog_OpenEventLogA(struct pipes_struct *p,
964 struct eventlog_OpenEventLogA *r)
966 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
967 return NT_STATUS_NOT_IMPLEMENTED;
970 NTSTATUS _eventlog_RegisterEventSourceA(struct pipes_struct *p,
971 struct eventlog_RegisterEventSourceA *r)
973 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
974 return NT_STATUS_NOT_IMPLEMENTED;
977 NTSTATUS _eventlog_OpenBackupEventLogA(struct pipes_struct *p,
978 struct eventlog_OpenBackupEventLogA *r)
980 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
981 return NT_STATUS_NOT_IMPLEMENTED;
984 NTSTATUS _eventlog_ReadEventLogA(struct pipes_struct *p,
985 struct eventlog_ReadEventLogA *r)
987 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
988 return NT_STATUS_NOT_IMPLEMENTED;
991 NTSTATUS _eventlog_ReportEventA(struct pipes_struct *p,
992 struct eventlog_ReportEventA *r)
994 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
995 return NT_STATUS_NOT_IMPLEMENTED;
998 NTSTATUS _eventlog_RegisterClusterSvc(struct pipes_struct *p,
999 struct eventlog_RegisterClusterSvc *r)
1001 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1002 return NT_STATUS_NOT_IMPLEMENTED;
1005 NTSTATUS _eventlog_DeregisterClusterSvc(struct pipes_struct *p,
1006 struct eventlog_DeregisterClusterSvc *r)
1008 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1009 return NT_STATUS_NOT_IMPLEMENTED;
1012 NTSTATUS _eventlog_WriteClusterEvents(struct pipes_struct *p,
1013 struct eventlog_WriteClusterEvents *r)
1015 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1016 return NT_STATUS_NOT_IMPLEMENTED;
1019 NTSTATUS _eventlog_ReportEventAndSourceW(struct pipes_struct *p,
1020 struct eventlog_ReportEventAndSourceW *r)
1022 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1023 return NT_STATUS_NOT_IMPLEMENTED;
1026 static NTSTATUS eventlog__op_init_server(struct dcesrv_context *dce_ctx,
1027 const struct dcesrv_endpoint_server *ep_server);
1029 #define DCESRV_INTERFACE_EVENTLOG_INIT_SERVER \
1030 eventlog_init_server
1032 static NTSTATUS eventlog_init_server(struct dcesrv_context *dce_ctx,
1033 const struct dcesrv_endpoint_server *ep_server)
1035 struct messaging_context *msg_ctx = global_messaging_context();
1036 bool ok;
1038 ok = eventlog_init_winreg(msg_ctx);
1039 if (!ok) {
1040 return NT_STATUS_UNSUCCESSFUL;
1043 return eventlog__op_init_server(dce_ctx, ep_server);
1046 /* include the generated boilerplate */
1047 #include "librpc/gen_ndr/ndr_eventlog_scompat.c"