s3-rpcclient: add eventlog_reporteventsource command.
[kai/samba-autobuild/.git] / source3 / rpcclient / cmd_eventlog.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Günther Deschner 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "rpcclient.h"
23
24 static NTSTATUS get_eventlog_handle(struct rpc_pipe_client *cli,
25                                     TALLOC_CTX *mem_ctx,
26                                     const char *log,
27                                     struct policy_handle *handle)
28 {
29         NTSTATUS status;
30         struct eventlog_OpenUnknown0 unknown0;
31         struct lsa_String logname, servername;
32
33         unknown0.unknown0 = 0x005c;
34         unknown0.unknown1 = 0x0001;
35
36         init_lsa_String(&logname, log);
37         init_lsa_String(&servername, NULL);
38
39         status = rpccli_eventlog_OpenEventLogW(cli, mem_ctx,
40                                                &unknown0,
41                                                &logname,
42                                                &servername,
43                                                0x00000001, /* major */
44                                                0x00000001, /* minor */
45                                                handle);
46         if (!NT_STATUS_IS_OK(status)) {
47                 return status;
48         }
49
50         return NT_STATUS_OK;
51 }
52
53 static NTSTATUS cmd_eventlog_readlog(struct rpc_pipe_client *cli,
54                                      TALLOC_CTX *mem_ctx,
55                                      int argc,
56                                      const char **argv)
57 {
58         NTSTATUS status;
59         struct policy_handle handle;
60
61         uint32_t flags = EVENTLOG_BACKWARDS_READ |
62                          EVENTLOG_SEQUENTIAL_READ;
63         uint32_t offset = 0;
64         uint32_t number_of_bytes = 0;
65         uint8_t *data = NULL;
66         uint32_t sent_size = 0;
67         uint32_t real_size = 0;
68
69         if (argc < 2 || argc > 4) {
70                 printf("Usage: %s logname [offset]\n", argv[0]);
71                 return NT_STATUS_OK;
72         }
73
74         if (argc >= 3) {
75                 offset = atoi(argv[2]);
76         }
77
78         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
79         if (!NT_STATUS_IS_OK(status)) {
80                 return status;
81         }
82
83         while (1) {
84                 status = rpccli_eventlog_ReadEventLogW(cli, mem_ctx,
85                                                        &handle,
86                                                        flags,
87                                                        offset,
88                                                        number_of_bytes,
89                                                        data,
90                                                        &sent_size,
91                                                        &real_size);
92                 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL) &&
93                     real_size > 0 ) {
94                         number_of_bytes = real_size;
95                         data = talloc_array(mem_ctx, uint8_t, real_size);
96                         continue;
97                 }
98
99                 number_of_bytes = 0;
100
101                 if (!NT_STATUS_IS_OK(status)) {
102                         goto done;
103                 }
104
105                 {
106                         enum ndr_err_code ndr_err;
107                         DATA_BLOB blob;
108                         struct eventlog_Record rec;
109
110                         blob = data_blob_const(data, sent_size);
111
112                         ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, NULL,
113                                                            &rec,
114                                                            (ndr_pull_flags_fn_t)ndr_pull_eventlog_Record);
115                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
116                                 status = ndr_map_error2ntstatus(ndr_err);
117                                 goto done;
118                         }
119
120                         NDR_PRINT_DEBUG(eventlog_Record, &rec);
121                 }
122
123                 offset++;
124         }
125
126  done:
127         rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle);
128
129         return status;
130 }
131
132 static NTSTATUS cmd_eventlog_numrecords(struct rpc_pipe_client *cli,
133                                         TALLOC_CTX *mem_ctx,
134                                         int argc,
135                                         const char **argv)
136 {
137         NTSTATUS status;
138         struct policy_handle handle;
139         uint32_t number = 0;
140
141         if (argc != 2) {
142                 printf("Usage: %s logname\n", argv[0]);
143                 return NT_STATUS_OK;
144         }
145
146         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
147         if (!NT_STATUS_IS_OK(status)) {
148                 return status;
149         }
150
151         status = rpccli_eventlog_GetNumRecords(cli, mem_ctx,
152                                                &handle,
153                                                &number);
154         if (!NT_STATUS_IS_OK(status)) {
155                 goto done;
156         }
157
158         printf("number of records: %d\n", number);
159
160  done:
161         rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle);
162
163         return status;
164 }
165
166 static NTSTATUS cmd_eventlog_oldestrecord(struct rpc_pipe_client *cli,
167                                           TALLOC_CTX *mem_ctx,
168                                           int argc,
169                                           const char **argv)
170 {
171         NTSTATUS status;
172         struct policy_handle handle;
173         uint32_t oldest_entry = 0;
174
175         if (argc != 2) {
176                 printf("Usage: %s logname\n", argv[0]);
177                 return NT_STATUS_OK;
178         }
179
180         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
181         if (!NT_STATUS_IS_OK(status)) {
182                 return status;
183         }
184
185         status = rpccli_eventlog_GetOldestRecord(cli, mem_ctx,
186                                                  &handle,
187                                                  &oldest_entry);
188         if (!NT_STATUS_IS_OK(status)) {
189                 goto done;
190         }
191
192         printf("oldest entry: %d\n", oldest_entry);
193
194  done:
195         rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle);
196
197         return status;
198 }
199
200 static NTSTATUS cmd_eventlog_reportevent(struct rpc_pipe_client *cli,
201                                          TALLOC_CTX *mem_ctx,
202                                          int argc,
203                                          const char **argv)
204 {
205         NTSTATUS status;
206         struct policy_handle handle;
207
208         uint16_t num_of_strings = 1;
209         uint32_t data_size = 0;
210         struct lsa_String servername;
211         struct lsa_String *strings;
212         uint8_t *data = NULL;
213         uint32_t record_number = 0;
214         time_t time_written = 0;
215
216         if (argc != 2) {
217                 printf("Usage: %s logname\n", argv[0]);
218                 return NT_STATUS_OK;
219         }
220
221         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
222         if (!NT_STATUS_IS_OK(status)) {
223                 return status;
224         }
225
226         strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
227         if (!strings) {
228                 return NT_STATUS_NO_MEMORY;
229         }
230
231         init_lsa_String(&strings[0], "test event written by rpcclient\n");
232         init_lsa_String(&servername, NULL);
233
234         status = rpccli_eventlog_ReportEventW(cli, mem_ctx,
235                                               &handle,
236                                               time(NULL),
237                                               EVENTLOG_INFORMATION_TYPE,
238                                               0, /* event_category */
239                                               0, /* event_id */
240                                               num_of_strings,
241                                               data_size,
242                                               &servername,
243                                               NULL, /* user_sid */
244                                               &strings,
245                                               data,
246                                               0, /* flags */
247                                               &record_number,
248                                               &time_written);
249
250         if (!NT_STATUS_IS_OK(status)) {
251                 goto done;
252         }
253
254         printf("entry: %d written at %s\n", record_number,
255                 http_timestring(talloc_tos(), time_written));
256
257  done:
258         rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle);
259
260         return status;
261 }
262
263 static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli,
264                                                TALLOC_CTX *mem_ctx,
265                                                int argc,
266                                                const char **argv)
267 {
268         NTSTATUS status;
269         struct policy_handle handle;
270
271         uint16_t num_of_strings = 1;
272         uint32_t data_size = 0;
273         struct lsa_String servername, sourcename;
274         struct lsa_String *strings;
275         uint8_t *data = NULL;
276         uint32_t record_number = 0;
277         time_t time_written = 0;
278
279         if (argc != 2) {
280                 printf("Usage: %s logname\n", argv[0]);
281                 return NT_STATUS_OK;
282         }
283
284         status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle);
285         if (!NT_STATUS_IS_OK(status)) {
286                 return status;
287         }
288
289         strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings);
290         if (!strings) {
291                 return NT_STATUS_NO_MEMORY;
292         }
293
294         init_lsa_String(&strings[0], "test event written by rpcclient\n");
295         init_lsa_String(&servername, NULL);
296         init_lsa_String(&sourcename, "rpcclient");
297
298         status = rpccli_eventlog_ReportEventAndSourceW(cli, mem_ctx,
299                                                        &handle,
300                                                        time(NULL),
301                                                        EVENTLOG_INFORMATION_TYPE,
302                                                        0, /* event_category */
303                                                        0, /* event_id */
304                                                        &sourcename,
305                                                        num_of_strings,
306                                                        data_size,
307                                                        &servername,
308                                                        NULL, /* user_sid */
309                                                        &strings,
310                                                        data,
311                                                        0, /* flags */
312                                                        &record_number,
313                                                        &time_written);
314         if (!NT_STATUS_IS_OK(status)) {
315                 goto done;
316         }
317
318         printf("entry: %d written at %s\n", record_number,
319                 http_timestring(talloc_tos(), time_written));
320
321  done:
322         rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle);
323
324         return status;
325 }
326
327
328 struct cmd_set eventlog_commands[] = {
329         { "EVENTLOG" },
330         { "eventlog_readlog",           RPC_RTYPE_NTSTATUS,     cmd_eventlog_readlog,           NULL,   &ndr_table_eventlog.syntax_id,  NULL,   "Read Eventlog", "" },
331         { "eventlog_numrecord",         RPC_RTYPE_NTSTATUS,     cmd_eventlog_numrecords,        NULL,   &ndr_table_eventlog.syntax_id,  NULL,   "Get number of records", "" },
332         { "eventlog_oldestrecord",      RPC_RTYPE_NTSTATUS,     cmd_eventlog_oldestrecord,      NULL,   &ndr_table_eventlog.syntax_id,  NULL,   "Get oldest record", "" },
333         { "eventlog_reportevent",       RPC_RTYPE_NTSTATUS,     cmd_eventlog_reportevent,       NULL,   &ndr_table_eventlog.syntax_id,  NULL,   "Report event", "" },
334         { "eventlog_reporteventsource", RPC_RTYPE_NTSTATUS,     cmd_eventlog_reporteventsource, NULL,   &ndr_table_eventlog.syntax_id,  NULL,   "Report event and source", "" },
335         { NULL }
336 };