~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/rpc_server/srv_eventlog_nt.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "../librpc/gen_ndr/srv_eventlog.h"
25
 
 
26
 
#undef  DBGC_CLASS
27
 
#define DBGC_CLASS DBGC_RPC_SRV
28
 
 
29
 
typedef struct {
30
 
        char *logname;
31
 
        ELOG_TDB *etdb;
32
 
        uint32 current_record;
33
 
        uint32 num_records;
34
 
        uint32 oldest_entry;
35
 
        uint32 flags;
36
 
        uint32 access_granted;
37
 
} EVENTLOG_INFO;
38
 
 
39
 
/********************************************************************
40
 
 ********************************************************************/
41
 
 
42
 
static int eventlog_info_destructor(EVENTLOG_INFO *elog)
43
 
{
44
 
        if (elog->etdb) {
45
 
                elog_close_tdb(elog->etdb, false);
46
 
        }
47
 
        return 0;
48
 
}
49
 
 
50
 
/********************************************************************
51
 
 ********************************************************************/
52
 
 
53
 
static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p,
54
 
                                                struct policy_handle * handle )
55
 
{
56
 
        EVENTLOG_INFO *info;
57
 
 
58
 
        if ( !find_policy_by_hnd( p, handle, (void **)(void *)&info ) ) {
59
 
                DEBUG( 2,
60
 
                       ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) );
61
 
                return NULL;
62
 
        }
63
 
 
64
 
        return info;
65
 
}
66
 
 
67
 
/********************************************************************
68
 
********************************************************************/
69
 
 
70
 
static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
71
 
{
72
 
        char *tdbname = elog_tdbname(talloc_tos(), info->logname );
73
 
        SEC_DESC *sec_desc;
74
 
        NTSTATUS status;
75
 
 
76
 
        if ( !tdbname )
77
 
                return False;
78
 
 
79
 
        /* get the security descriptor for the file */
80
 
 
81
 
        sec_desc = get_nt_acl_no_snum( info, tdbname );
82
 
        TALLOC_FREE( tdbname );
83
 
 
84
 
        if ( !sec_desc ) {
85
 
                DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
86
 
                        tdbname));
87
 
                return False;
88
 
        }
89
 
 
90
 
        /* root free pass */
91
 
 
92
 
        if ( geteuid() == sec_initial_uid() ) {
93
 
                DEBUG(5,("elog_check_access: using root's token\n"));
94
 
                token = get_root_nt_token();
95
 
        }
96
 
 
97
 
        /* run the check, try for the max allowed */
98
 
 
99
 
        status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
100
 
                &info->access_granted);
101
 
 
102
 
        if ( sec_desc )
103
 
                TALLOC_FREE( sec_desc );
104
 
 
105
 
        if (!NT_STATUS_IS_OK(status)) {
106
 
                DEBUG(8,("elog_check_access: se_access_check() return %s\n",
107
 
                        nt_errstr(status)));
108
 
                return False;
109
 
        }
110
 
 
111
 
        /* we have to have READ permission for a successful open */
112
 
 
113
 
        return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
114
 
}
115
 
 
116
 
/********************************************************************
117
 
 ********************************************************************/
118
 
 
119
 
static bool elog_validate_logname( const char *name )
120
 
{
121
 
        int i;
122
 
        const char **elogs = lp_eventlog_list();
123
 
 
124
 
        if (!elogs) {
125
 
                return False;
126
 
        }
127
 
 
128
 
        for ( i=0; elogs[i]; i++ ) {
129
 
                if ( strequal( name, elogs[i] ) )
130
 
                        return True;
131
 
        }
132
 
 
133
 
        return False;
134
 
}
135
 
 
136
 
/********************************************************************
137
 
********************************************************************/
138
 
 
139
 
static bool get_num_records_hook( EVENTLOG_INFO * info )
140
 
{
141
 
        int next_record;
142
 
        int oldest_record;
143
 
 
144
 
        if ( !info->etdb ) {
145
 
                DEBUG( 10, ( "No open tdb for %s\n", info->logname ) );
146
 
                return False;
147
 
        }
148
 
 
149
 
        /* lock the tdb since we have to get 2 records */
150
 
 
151
 
        tdb_lock_bystring_with_timeout( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 );
152
 
        next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
153
 
        oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY);
154
 
        tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD);
155
 
 
156
 
        DEBUG( 8,
157
 
               ( "Oldest Record %d; Next Record %d\n", oldest_record,
158
 
                 next_record ) );
159
 
 
160
 
        info->num_records = ( next_record - oldest_record );
161
 
        info->oldest_entry = oldest_record;
162
 
 
163
 
        return True;
164
 
}
165
 
 
166
 
/********************************************************************
167
 
 ********************************************************************/
168
 
 
169
 
static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
170
 
{
171
 
        /* it's the same thing */
172
 
        return get_num_records_hook( info );
173
 
}
174
 
 
175
 
/********************************************************************
176
 
 ********************************************************************/
177
 
 
178
 
static NTSTATUS elog_open( pipes_struct * p, const char *logname, struct policy_handle *hnd )
179
 
{
180
 
        EVENTLOG_INFO *elog;
181
 
 
182
 
        /* first thing is to validate the eventlog name */
183
 
 
184
 
        if ( !elog_validate_logname( logname ) )
185
 
                return NT_STATUS_OBJECT_PATH_INVALID;
186
 
 
187
 
        if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) )
188
 
                return NT_STATUS_NO_MEMORY;
189
 
        talloc_set_destructor(elog, eventlog_info_destructor);
190
 
 
191
 
        elog->logname = talloc_strdup( elog, logname );
192
 
 
193
 
        /* Open the tdb first (so that we can create any new tdbs if necessary).
194
 
           We have to do this as root and then use an internal access check
195
 
           on the file permissions since you can only have a tdb open once
196
 
           in a single process */
197
 
 
198
 
        become_root();
199
 
        elog->etdb = elog_open_tdb( elog->logname, False, False );
200
 
        unbecome_root();
201
 
 
202
 
        if ( !elog->etdb ) {
203
 
                /* according to MSDN, if the logfile cannot be found, we should
204
 
                  default to the "Application" log */
205
 
 
206
 
                if ( !strequal( logname, ELOG_APPL ) ) {
207
 
 
208
 
                        TALLOC_FREE( elog->logname );
209
 
 
210
 
                        elog->logname = talloc_strdup( elog, ELOG_APPL );
211
 
 
212
 
                        /* do the access check */
213
 
                        if ( !elog_check_access( elog, p->server_info->ptok ) ) {
214
 
                                TALLOC_FREE( elog );
215
 
                                return NT_STATUS_ACCESS_DENIED;
216
 
                        }
217
 
 
218
 
                        become_root();
219
 
                        elog->etdb = elog_open_tdb( elog->logname, False, False );
220
 
                        unbecome_root();
221
 
                }
222
 
 
223
 
                if ( !elog->etdb ) {
224
 
                        TALLOC_FREE( elog );
225
 
                        return NT_STATUS_ACCESS_DENIED; /* ??? */
226
 
                }
227
 
        }
228
 
 
229
 
        /* now do the access check.  Close the tdb if we fail here */
230
 
 
231
 
        if ( !elog_check_access( elog, p->server_info->ptok ) ) {
232
 
                TALLOC_FREE( elog );
233
 
                return NT_STATUS_ACCESS_DENIED;
234
 
        }
235
 
 
236
 
        /* create the policy handle */
237
 
 
238
 
        if ( !create_policy_hnd( p, hnd, elog ) ) {
239
 
                TALLOC_FREE(elog);
240
 
                return NT_STATUS_NO_MEMORY;
241
 
        }
242
 
 
243
 
        /* set the initial current_record pointer */
244
 
 
245
 
        if ( !get_oldest_entry_hook( elog ) ) {
246
 
                DEBUG(3,("elog_open: Successfully opened eventlog but can't "
247
 
                        "get any information on internal records!\n"));
248
 
        }
249
 
 
250
 
        elog->current_record = elog->oldest_entry;
251
 
 
252
 
        return NT_STATUS_OK;
253
 
}
254
 
 
255
 
/********************************************************************
256
 
 ********************************************************************/
257
 
 
258
 
static NTSTATUS elog_close( pipes_struct *p, struct policy_handle *hnd )
259
 
{
260
 
        if ( !( close_policy_hnd( p, hnd ) ) ) {
261
 
                return NT_STATUS_INVALID_HANDLE;
262
 
        }
263
 
 
264
 
        return NT_STATUS_OK;
265
 
}
266
 
 
267
 
/*******************************************************************
268
 
 *******************************************************************/
269
 
 
270
 
static int elog_size( EVENTLOG_INFO *info )
271
 
{
272
 
        if ( !info || !info->etdb ) {
273
 
                DEBUG(0,("elog_size: Invalid info* structure!\n"));
274
 
                return 0;
275
 
        }
276
 
 
277
 
        return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL );
278
 
}
279
 
 
280
 
/********************************************************************
281
 
 note that this can only be called AFTER the table is constructed,
282
 
 since it uses the table to find the tdb handle
283
 
 ********************************************************************/
284
 
 
285
 
static bool sync_eventlog_params( EVENTLOG_INFO *info )
286
 
{
287
 
        char *path = NULL;
288
 
        uint32 uiMaxSize;
289
 
        uint32 uiRetention;
290
 
        struct registry_key *key;
291
 
        struct registry_value *value;
292
 
        WERROR wresult;
293
 
        char *elogname = info->logname;
294
 
        TALLOC_CTX *ctx = talloc_stackframe();
295
 
        bool ret = false;
296
 
 
297
 
        DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
298
 
 
299
 
        if ( !info->etdb ) {
300
 
                DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
301
 
                goto done;
302
 
        }
303
 
        /* set resonable defaults.  512Kb on size and 1 week on time */
304
 
 
305
 
        uiMaxSize = 0x80000;
306
 
        uiRetention = 604800;
307
 
 
308
 
        /* the general idea is to internally open the registry
309
 
           key and retrieve the values.  That way we can continue
310
 
           to use the same fetch/store api that we use in
311
 
           srv_reg_nt.c */
312
 
 
313
 
        path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname );
314
 
        if (!path) {
315
 
                goto done;
316
 
        }
317
 
 
318
 
        wresult = reg_open_path(ctx, path, REG_KEY_READ, get_root_nt_token(),
319
 
                                &key);
320
 
 
321
 
        if ( !W_ERROR_IS_OK( wresult ) ) {
322
 
                DEBUG( 4,
323
 
                       ( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
324
 
                         path, win_errstr( wresult ) ) );
325
 
                goto done;
326
 
        }
327
 
 
328
 
        wresult = reg_queryvalue(key, key, "Retention", &value);
329
 
        if (!W_ERROR_IS_OK(wresult)) {
330
 
                DEBUG(4, ("Failed to query value \"Retention\": %s\n",
331
 
                          win_errstr(wresult)));
332
 
                goto done;
333
 
        }
334
 
        uiRetention = value->v.dword;
335
 
 
336
 
        wresult = reg_queryvalue(key, key, "MaxSize", &value);
337
 
        if (!W_ERROR_IS_OK(wresult)) {
338
 
                DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
339
 
                          win_errstr(wresult)));
340
 
                goto done;
341
 
        }
342
 
        uiMaxSize = value->v.dword;
343
 
 
344
 
        tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize );
345
 
        tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention );
346
 
 
347
 
        ret = true;
348
 
 
349
 
done:
350
 
        TALLOC_FREE(ctx);
351
 
        return ret;
352
 
}
353
 
 
354
 
/********************************************************************
355
 
 _eventlog_OpenEventLogW
356
 
 ********************************************************************/
357
 
 
358
 
NTSTATUS _eventlog_OpenEventLogW(pipes_struct *p,
359
 
                                 struct eventlog_OpenEventLogW *r)
360
 
{
361
 
        EVENTLOG_INFO *info;
362
 
        NTSTATUS result;
363
 
 
364
 
        DEBUG( 10,("_eventlog_OpenEventLogW: Server [%s], Log [%s]\n",
365
 
                r->in.servername->string, r->in.logname->string ));
366
 
 
367
 
        /* according to MSDN, if the logfile cannot be found, we should
368
 
          default to the "Application" log */
369
 
 
370
 
        if ( !NT_STATUS_IS_OK( result = elog_open( p, r->in.logname->string, r->out.handle )) )
371
 
                return result;
372
 
 
373
 
        if ( !(info = find_eventlog_info_by_hnd( p, r->out.handle )) ) {
374
 
                DEBUG(0,("_eventlog_OpenEventLogW: eventlog (%s) opened but unable to find handle!\n",
375
 
                        r->in.logname->string ));
376
 
                elog_close( p, r->out.handle );
377
 
                return NT_STATUS_INVALID_HANDLE;
378
 
        }
379
 
 
380
 
        DEBUG(10,("_eventlog_OpenEventLogW: Size [%d]\n", elog_size( info )));
381
 
 
382
 
        sync_eventlog_params( info );
383
 
        prune_eventlog( ELOG_TDB_CTX(info->etdb) );
384
 
 
385
 
        return NT_STATUS_OK;
386
 
}
387
 
 
388
 
/********************************************************************
389
 
 _eventlog_ClearEventLogW
390
 
 This call still needs some work
391
 
 ********************************************************************/
392
 
/** The windows client seems to be doing something funny with the file name
393
 
   A call like
394
 
      ClearEventLog(handle, "backup_file")
395
 
   on the client side will result in the backup file name looking like this on the
396
 
   server side:
397
 
      \??\${CWD of client}\backup_file
398
 
   If an absolute path gets specified, such as
399
 
      ClearEventLog(handle, "C:\\temp\\backup_file")
400
 
   then it is still mangled by the client into this:
401
 
      \??\C:\temp\backup_file
402
 
   when it is on the wire.
403
 
   I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
404
 
   would be added in given that the backup file gets written on the server side. */
405
 
 
406
 
NTSTATUS _eventlog_ClearEventLogW(pipes_struct *p,
407
 
                                  struct eventlog_ClearEventLogW *r)
408
 
{
409
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
410
 
 
411
 
        if ( !info )
412
 
                return NT_STATUS_INVALID_HANDLE;
413
 
 
414
 
        if (r->in.backupfile && r->in.backupfile->string) {
415
 
 
416
 
                DEBUG(8,( "_eventlog_ClearEventLogW: Using [%s] as the backup "
417
 
                        "file name for log [%s].",
418
 
                         r->in.backupfile->string, info->logname ) );
419
 
        }
420
 
 
421
 
        /* check for WRITE access to the file */
422
 
 
423
 
        if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) )
424
 
                return NT_STATUS_ACCESS_DENIED;
425
 
 
426
 
        /* Force a close and reopen */
427
 
 
428
 
        elog_close_tdb( info->etdb, True );
429
 
        become_root();
430
 
        info->etdb = elog_open_tdb( info->logname, True, False );
431
 
        unbecome_root();
432
 
 
433
 
        if ( !info->etdb )
434
 
                return NT_STATUS_ACCESS_DENIED;
435
 
 
436
 
        return NT_STATUS_OK;
437
 
}
438
 
 
439
 
/********************************************************************
440
 
 _eventlog_CloseEventLog
441
 
 ********************************************************************/
442
 
 
443
 
NTSTATUS _eventlog_CloseEventLog(pipes_struct * p,
444
 
                                 struct eventlog_CloseEventLog *r)
445
 
{
446
 
        NTSTATUS status;
447
 
 
448
 
        status = elog_close( p, r->in.handle );
449
 
        if (!NT_STATUS_IS_OK(status)) {
450
 
                return status;
451
 
        }
452
 
 
453
 
        ZERO_STRUCTP(r->out.handle);
454
 
 
455
 
        return NT_STATUS_OK;
456
 
}
457
 
 
458
 
/********************************************************************
459
 
 _eventlog_ReadEventLogW
460
 
 ********************************************************************/
461
 
 
462
 
NTSTATUS _eventlog_ReadEventLogW(pipes_struct *p,
463
 
                                 struct eventlog_ReadEventLogW *r)
464
 
{
465
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
466
 
        uint32_t num_records_read = 0;
467
 
        int bytes_left, record_number;
468
 
        uint32_t elog_read_type, elog_read_dir;
469
 
 
470
 
        if (!info) {
471
 
                return NT_STATUS_INVALID_HANDLE;
472
 
        }
473
 
 
474
 
        info->flags     = r->in.flags;
475
 
        bytes_left      = r->in.number_of_bytes;
476
 
 
477
 
        if (!info->etdb) {
478
 
                return NT_STATUS_ACCESS_DENIED;
479
 
        }
480
 
 
481
 
        /* check for valid flags.  Can't use the sequential and seek flags together */
482
 
 
483
 
        elog_read_type = r->in.flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ);
484
 
        elog_read_dir  = r->in.flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ);
485
 
 
486
 
        if (r->in.flags == 0 ||
487
 
            elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) ||
488
 
            elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ))
489
 
        {
490
 
                DEBUG(3,("_eventlog_ReadEventLogW: "
491
 
                        "Invalid flags [0x%08x] for ReadEventLog\n",
492
 
                        r->in.flags));
493
 
                return NT_STATUS_INVALID_PARAMETER;
494
 
        }
495
 
 
496
 
        /* a sequential read should ignore the offset */
497
 
 
498
 
        if (elog_read_type & EVENTLOG_SEQUENTIAL_READ) {
499
 
                record_number = info->current_record;
500
 
        } else {
501
 
                record_number = r->in.offset;
502
 
        }
503
 
 
504
 
        if (r->in.number_of_bytes == 0) {
505
 
                struct EVENTLOGRECORD *e;
506
 
                e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
507
 
                                      record_number);
508
 
                if (!e) {
509
 
                        return NT_STATUS_END_OF_FILE;
510
 
                }
511
 
                *r->out.real_size = e->Length;
512
 
                return NT_STATUS_BUFFER_TOO_SMALL;
513
 
        }
514
 
 
515
 
        while (bytes_left > 0) {
516
 
 
517
 
                DATA_BLOB blob;
518
 
                enum ndr_err_code ndr_err;
519
 
                struct EVENTLOGRECORD *e;
520
 
 
521
 
                e = evlog_pull_record(p->mem_ctx, ELOG_TDB_CTX(info->etdb),
522
 
                                      record_number);
523
 
                if (!e) {
524
 
                        break;
525
 
                }
526
 
 
527
 
                ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, NULL, e,
528
 
                              (ndr_push_flags_fn_t)ndr_push_EVENTLOGRECORD);
529
 
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
530
 
                        return ndr_map_error2ntstatus(ndr_err);
531
 
                }
532
 
 
533
 
                if (DEBUGLEVEL >= 10) {
534
 
                        NDR_PRINT_DEBUG(EVENTLOGRECORD, e);
535
 
                }
536
 
 
537
 
                if (blob.length > r->in.number_of_bytes) {
538
 
                        *r->out.real_size = blob.length;
539
 
                        return NT_STATUS_BUFFER_TOO_SMALL;
540
 
                }
541
 
 
542
 
                if (*r->out.sent_size + blob.length > r->in.number_of_bytes) {
543
 
                        break;
544
 
                }
545
 
 
546
 
                bytes_left -= blob.length;
547
 
 
548
 
                if (info->flags & EVENTLOG_FORWARDS_READ) {
549
 
                        record_number++;
550
 
                } else {
551
 
                        record_number--;
552
 
                }
553
 
 
554
 
                /* update the eventlog record pointer */
555
 
 
556
 
                info->current_record = record_number;
557
 
 
558
 
                memcpy(&r->out.data[*(r->out.sent_size)],
559
 
                       blob.data, blob.length);
560
 
                *(r->out.sent_size) += blob.length;
561
 
 
562
 
                num_records_read++;
563
 
        }
564
 
 
565
 
        if (r->in.offset == 0 && record_number == 0 && *r->out.sent_size == 0) {
566
 
                return NT_STATUS_END_OF_FILE;
567
 
        }
568
 
 
569
 
        return NT_STATUS_OK;
570
 
}
571
 
 
572
 
/********************************************************************
573
 
 _eventlog_GetOldestRecord
574
 
 ********************************************************************/
575
 
 
576
 
NTSTATUS _eventlog_GetOldestRecord(pipes_struct *p,
577
 
                                   struct eventlog_GetOldestRecord *r)
578
 
{
579
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
580
 
 
581
 
        if (info == NULL) {
582
 
                return NT_STATUS_INVALID_HANDLE;
583
 
        }
584
 
 
585
 
        if ( !( get_oldest_entry_hook( info ) ) )
586
 
                return NT_STATUS_ACCESS_DENIED;
587
 
 
588
 
        *r->out.oldest_entry = info->oldest_entry;
589
 
 
590
 
        return NT_STATUS_OK;
591
 
}
592
 
 
593
 
/********************************************************************
594
 
_eventlog_GetNumRecords
595
 
 ********************************************************************/
596
 
 
597
 
NTSTATUS _eventlog_GetNumRecords(pipes_struct *p,
598
 
                                 struct eventlog_GetNumRecords *r)
599
 
{
600
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, r->in.handle );
601
 
 
602
 
        if (info == NULL) {
603
 
                return NT_STATUS_INVALID_HANDLE;
604
 
        }
605
 
 
606
 
        if ( !( get_num_records_hook( info ) ) )
607
 
                return NT_STATUS_ACCESS_DENIED;
608
 
 
609
 
        *r->out.number = info->num_records;
610
 
 
611
 
        return NT_STATUS_OK;
612
 
}
613
 
 
614
 
NTSTATUS _eventlog_BackupEventLogW(pipes_struct *p, struct eventlog_BackupEventLogW *r)
615
 
{
616
 
        p->rng_fault_state = True;
617
 
        return NT_STATUS_NOT_IMPLEMENTED;
618
 
}
619
 
 
620
 
/********************************************************************
621
 
_eventlog_GetLogInformation
622
 
 ********************************************************************/
623
 
 
624
 
NTSTATUS _eventlog_GetLogInformation(pipes_struct *p,
625
 
                                     struct eventlog_GetLogInformation *r)
626
 
{
627
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
628
 
        struct EVENTLOG_FULL_INFORMATION f;
629
 
        enum ndr_err_code ndr_err;
630
 
        DATA_BLOB blob;
631
 
 
632
 
        if (!info) {
633
 
                return NT_STATUS_INVALID_HANDLE;
634
 
        }
635
 
 
636
 
        if (r->in.level != 0) {
637
 
                return NT_STATUS_INVALID_LEVEL;
638
 
        }
639
 
 
640
 
        *r->out.bytes_needed = 4;
641
 
 
642
 
        if (r->in.buf_size < 4) {
643
 
                return NT_STATUS_BUFFER_TOO_SMALL;
644
 
        }
645
 
 
646
 
        /* FIXME: this should be retrieved from the handle */
647
 
        f.full = false;
648
 
 
649
 
        ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, NULL, &f,
650
 
                      (ndr_push_flags_fn_t)ndr_push_EVENTLOG_FULL_INFORMATION);
651
 
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
652
 
                return ndr_map_error2ntstatus(ndr_err);
653
 
        }
654
 
 
655
 
        if (DEBUGLEVEL >= 10) {
656
 
                NDR_PRINT_DEBUG(EVENTLOG_FULL_INFORMATION, &f);
657
 
        }
658
 
 
659
 
        memcpy(r->out.buffer, blob.data, 4);
660
 
 
661
 
        return NT_STATUS_OK;
662
 
}
663
 
 
664
 
/********************************************************************
665
 
_eventlog_FlushEventLog
666
 
 ********************************************************************/
667
 
 
668
 
NTSTATUS _eventlog_FlushEventLog(pipes_struct *p,
669
 
                                 struct eventlog_FlushEventLog *r)
670
 
{
671
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
672
 
        if (!info) {
673
 
                return NT_STATUS_INVALID_HANDLE;
674
 
        }
675
 
 
676
 
        return NT_STATUS_ACCESS_DENIED;
677
 
}
678
 
 
679
 
/********************************************************************
680
 
 ********************************************************************/
681
 
 
682
 
static NTSTATUS evlog_report_to_record(TALLOC_CTX *mem_ctx,
683
 
                                       const struct eventlog_ReportEventW *r,
684
 
                                       const char *logname,
685
 
                                       struct EVENTLOGRECORD *e)
686
 
{
687
 
        uint32_t i;
688
 
        ZERO_STRUCTP(e);
689
 
 
690
 
        e->TimeGenerated        = r->in.timestamp;
691
 
        e->TimeWritten          = time(NULL);
692
 
        e->EventID              = r->in.event_id;
693
 
        e->EventType            = r->in.event_type;
694
 
        e->NumStrings           = r->in.num_of_strings;
695
 
        e->EventCategory        = r->in.event_category;
696
 
        e->ReservedFlags        = r->in.flags;
697
 
        e->DataLength           = r->in.data_size;
698
 
        e->SourceName           = talloc_strdup(mem_ctx, logname);
699
 
        NT_STATUS_HAVE_NO_MEMORY(e->SourceName);
700
 
        if (r->in.servername->string) {
701
 
                e->Computername = r->in.servername->string;
702
 
        } else {
703
 
                e->Computername = talloc_strdup(mem_ctx, "");
704
 
                NT_STATUS_HAVE_NO_MEMORY(e->Computername);
705
 
        }
706
 
        if (r->in.user_sid) {
707
 
                e->UserSid      = *r->in.user_sid;
708
 
        }
709
 
        e->Strings              = talloc_array(mem_ctx, const char *, e->NumStrings);
710
 
        NT_STATUS_HAVE_NO_MEMORY(e->Strings);
711
 
 
712
 
        for (i=0; i < e->NumStrings; i++) {
713
 
                e->Strings[i] = talloc_strdup(e->Strings,
714
 
                                              r->in.strings[i]->string);
715
 
                NT_STATUS_HAVE_NO_MEMORY(e->Strings[i]);
716
 
        }
717
 
        e->Data                 = r->in.data;
718
 
 
719
 
        return NT_STATUS_OK;
720
 
}
721
 
 
722
 
/********************************************************************
723
 
_eventlog_ReportEventW
724
 
 ********************************************************************/
725
 
 
726
 
NTSTATUS _eventlog_ReportEventW(pipes_struct *p,
727
 
                                struct eventlog_ReportEventW *r)
728
 
{
729
 
        NTSTATUS status;
730
 
        struct EVENTLOGRECORD record;
731
 
 
732
 
        EVENTLOG_INFO *info = find_eventlog_info_by_hnd(p, r->in.handle);
733
 
        if (!info) {
734
 
                return NT_STATUS_INVALID_HANDLE;
735
 
        }
736
 
 
737
 
        status = evlog_report_to_record(p->mem_ctx, r, info->logname, &record);
738
 
        if (!NT_STATUS_IS_OK(status)) {
739
 
                return status;
740
 
        }
741
 
 
742
 
        status = evlog_push_record(p->mem_ctx,
743
 
                                   ELOG_TDB_CTX(info->etdb),
744
 
                                   &record,
745
 
                                   r->out.record_number);
746
 
        if (!NT_STATUS_IS_OK(status)) {
747
 
                return status;
748
 
        }
749
 
 
750
 
        return NT_STATUS_OK;
751
 
}
752
 
 
753
 
/********************************************************************
754
 
 ********************************************************************/
755
 
 
756
 
NTSTATUS _eventlog_DeregisterEventSource(pipes_struct *p, struct eventlog_DeregisterEventSource *r)
757
 
{
758
 
        p->rng_fault_state = True;
759
 
        return NT_STATUS_NOT_IMPLEMENTED;
760
 
}
761
 
 
762
 
NTSTATUS _eventlog_ChangeNotify(pipes_struct *p, struct eventlog_ChangeNotify *r)
763
 
{
764
 
        p->rng_fault_state = True;
765
 
        return NT_STATUS_NOT_IMPLEMENTED;
766
 
}
767
 
 
768
 
NTSTATUS _eventlog_RegisterEventSourceW(pipes_struct *p, struct eventlog_RegisterEventSourceW *r)
769
 
{
770
 
        p->rng_fault_state = True;
771
 
        return NT_STATUS_NOT_IMPLEMENTED;
772
 
}
773
 
 
774
 
NTSTATUS _eventlog_OpenBackupEventLogW(pipes_struct *p, struct eventlog_OpenBackupEventLogW *r)
775
 
{
776
 
        p->rng_fault_state = True;
777
 
        return NT_STATUS_NOT_IMPLEMENTED;
778
 
}
779
 
 
780
 
NTSTATUS _eventlog_ClearEventLogA(pipes_struct *p, struct eventlog_ClearEventLogA *r)
781
 
{
782
 
        p->rng_fault_state = True;
783
 
        return NT_STATUS_NOT_IMPLEMENTED;
784
 
}
785
 
 
786
 
NTSTATUS _eventlog_BackupEventLogA(pipes_struct *p, struct eventlog_BackupEventLogA *r)
787
 
{
788
 
        p->rng_fault_state = True;
789
 
        return NT_STATUS_NOT_IMPLEMENTED;
790
 
}
791
 
 
792
 
NTSTATUS _eventlog_OpenEventLogA(pipes_struct *p, struct eventlog_OpenEventLogA *r)
793
 
{
794
 
        p->rng_fault_state = True;
795
 
        return NT_STATUS_NOT_IMPLEMENTED;
796
 
}
797
 
 
798
 
NTSTATUS _eventlog_RegisterEventSourceA(pipes_struct *p, struct eventlog_RegisterEventSourceA *r)
799
 
{
800
 
        p->rng_fault_state = True;
801
 
        return NT_STATUS_NOT_IMPLEMENTED;
802
 
}
803
 
 
804
 
NTSTATUS _eventlog_OpenBackupEventLogA(pipes_struct *p, struct eventlog_OpenBackupEventLogA *r)
805
 
{
806
 
        p->rng_fault_state = True;
807
 
        return NT_STATUS_NOT_IMPLEMENTED;
808
 
}
809
 
 
810
 
NTSTATUS _eventlog_ReadEventLogA(pipes_struct *p, struct eventlog_ReadEventLogA *r)
811
 
{
812
 
        p->rng_fault_state = True;
813
 
        return NT_STATUS_NOT_IMPLEMENTED;
814
 
}
815
 
 
816
 
NTSTATUS _eventlog_ReportEventA(pipes_struct *p, struct eventlog_ReportEventA *r)
817
 
{
818
 
        p->rng_fault_state = True;
819
 
        return NT_STATUS_NOT_IMPLEMENTED;
820
 
}
821
 
 
822
 
NTSTATUS _eventlog_RegisterClusterSvc(pipes_struct *p, struct eventlog_RegisterClusterSvc *r)
823
 
{
824
 
        p->rng_fault_state = True;
825
 
        return NT_STATUS_NOT_IMPLEMENTED;
826
 
}
827
 
 
828
 
NTSTATUS _eventlog_DeregisterClusterSvc(pipes_struct *p, struct eventlog_DeregisterClusterSvc *r)
829
 
{
830
 
        p->rng_fault_state = True;
831
 
        return NT_STATUS_NOT_IMPLEMENTED;
832
 
}
833
 
 
834
 
NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClusterEvents *r)
835
 
{
836
 
        p->rng_fault_state = True;
837
 
        return NT_STATUS_NOT_IMPLEMENTED;
838
 
}
839
 
 
840
 
NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r)
841
 
{
842
 
        p->rng_fault_state = True;
843
 
        return NT_STATUS_NOT_IMPLEMENTED;
844
 
}