s3:net: refactor getting of secdesc out of net_registry_getsd()
[ira/wip.git] / source3 / utils / net_eventlog.c
1 /*
2  * Samba Unix/Linux SMB client library
3  * Distributed SMB/CIFS Server Management Utility
4  * Local win32 eventlog interface
5  *
6  * Copyright (C) Guenther Deschner 2009
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "utils/net.h"
24
25 /**
26  * Dump an *evt win32 eventlog file
27  *
28  * @param argc  Standard main() style argc.
29  * @param argv  Standard main() style argv. Initial components are already
30  *              stripped.
31  *
32  * @return A shell status integer (0 for success).
33  **/
34
35 static int net_eventlog_dump(struct net_context *c, int argc,
36                              const char **argv)
37 {
38         int ret = -1;
39         TALLOC_CTX *ctx = talloc_stackframe();
40         enum ndr_err_code ndr_err;
41         DATA_BLOB blob;
42         struct EVENTLOG_EVT_FILE evt;
43         char *s;
44
45         if (argc < 1 || c->display_usage) {
46                 d_fprintf(stderr, "%s\nnet eventlog dump <file.evt>\n",
47                           _("Usage:"));
48                 goto done;
49         }
50
51         blob.data = (uint8_t *)file_load(argv[0], &blob.length, 0, ctx);
52         if (!blob.data) {
53                 d_fprintf(stderr, _("failed to load evt file: %s\n"), argv[0]);
54                 goto done;
55         }
56
57         ndr_err = ndr_pull_struct_blob(&blob, ctx, NULL, &evt,
58                    (ndr_pull_flags_fn_t)ndr_pull_EVENTLOG_EVT_FILE);
59         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
60                 d_fprintf(stderr, _("evt pull failed: %s\n"),
61                           ndr_errstr(ndr_err));
62                 goto done;
63         }
64
65         s = NDR_PRINT_STRUCT_STRING(ctx, EVENTLOG_EVT_FILE, &evt);
66         if (s) {
67                 printf("%s\n", s);
68         }
69
70         ret = 0;
71  done:
72         TALLOC_FREE(ctx);
73         return ret;
74 }
75
76 /**
77  * Import an *evt win32 eventlog file to internal tdb representation
78  *
79  * @param argc  Standard main() style argc.
80  * @param argv  Standard main() style argv. Initial components are already
81  *              stripped.
82  *
83  * @return A shell status integer (0 for success).
84  **/
85
86 static int net_eventlog_import(struct net_context *c, int argc,
87                                const char **argv)
88 {
89         int ret = -1;
90         TALLOC_CTX *ctx = talloc_stackframe();
91         NTSTATUS status;
92         enum ndr_err_code ndr_err;
93         DATA_BLOB blob;
94         uint32_t num_records = 0;
95         uint32_t i;
96         ELOG_TDB *etdb = NULL;
97
98         struct EVENTLOGHEADER evt_header;
99         struct EVENTLOG_EVT_FILE evt;
100
101         if (argc < 2 || c->display_usage) {
102                 d_fprintf(stderr,
103                           "%s\nnet eventlog import <file> <eventlog>\n",
104                           _("Usage:"));
105                 goto done;
106         }
107
108         blob.data = (uint8_t *)file_load(argv[0], &blob.length, 0, ctx);
109         if (!blob.data) {
110                 d_fprintf(stderr, _("failed to load evt file: %s\n"), argv[0]);
111                 goto done;
112         }
113
114         /* dump_data(0, blob.data, blob.length); */
115         ndr_err = ndr_pull_struct_blob(&blob, ctx, NULL, &evt_header,
116                    (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGHEADER);
117         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
118                 d_fprintf(stderr, _("evt header pull failed: %s\n"),
119                           ndr_errstr(ndr_err));
120                 goto done;
121         }
122
123         if (evt_header.Flags & ELF_LOGFILE_HEADER_WRAP) {
124                 d_fprintf(stderr, _("input file is wrapped, cannot proceed\n"));
125                 goto done;
126         }
127
128         ndr_err = ndr_pull_struct_blob(&blob, ctx, NULL, &evt,
129                    (ndr_pull_flags_fn_t)ndr_pull_EVENTLOG_EVT_FILE);
130         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
131                 d_fprintf(stderr, _("evt pull failed: %s\n"),
132                           ndr_errstr(ndr_err));
133                 goto done;
134         }
135
136         /* NDR_PRINT_DEBUG(EVENTLOG_EVT_FILE, &evt); */
137
138         etdb = elog_open_tdb(argv[1], false, false);
139         if (!etdb) {
140                 d_fprintf(stderr, _("can't open the eventlog TDB (%s)\n"),
141                           argv[1]);
142                 goto done;
143         }
144
145         num_records = evt.hdr.CurrentRecordNumber - evt.hdr.OldestRecordNumber;
146
147         for (i=0; i<num_records; i++) {
148                 uint32_t record_number;
149                 struct eventlog_Record_tdb e;
150
151                 status = evlog_evt_entry_to_tdb_entry(ctx, &evt.records[i], &e);
152                 if (!NT_STATUS_IS_OK(status)) {
153                         goto done;
154                 }
155
156                 status = evlog_push_record_tdb(ctx, ELOG_TDB_CTX(etdb),
157                                                &e, &record_number);
158                 if (!NT_STATUS_IS_OK(status)) {
159                         d_fprintf(stderr,
160                                   _("can't write to the eventlog: %s\n"),
161                                   nt_errstr(status));
162                         goto done;
163                 }
164         }
165
166         printf(_("wrote %d entries to tdb\n"), i);
167
168         ret = 0;
169  done:
170
171         elog_close_tdb(etdb, false);
172
173         TALLOC_FREE(ctx);
174         return ret;
175 }
176
177 /**
178  * Export internal eventlog tdb representation to an *evt win32 eventlog file
179  *
180  * @param argc  Standard main() style argc.
181  * @param argv  Standard main() style argv. Initial components are already
182  *              stripped.
183  *
184  * @return A shell status integer (0 for success).
185  **/
186
187 static int net_eventlog_export(struct net_context *c, int argc,
188                                const char **argv)
189 {
190         int ret = -1;
191         NTSTATUS status;
192         TALLOC_CTX *ctx = talloc_stackframe();
193         DATA_BLOB blob;
194         uint32_t num_records = 0;
195         ELOG_TDB *etdb = NULL;
196
197         if (argc < 2 || c->display_usage) {
198                 d_fprintf(stderr,
199                           "%s\nnet eventlog export <file> <eventlog>\n",
200                           _("Usage:"));
201                 goto done;
202         }
203
204         etdb = elog_open_tdb(argv[1], false, true);
205         if (!etdb) {
206                 d_fprintf(stderr, _("can't open the eventlog TDB (%s)\n"),
207                           argv[1]);
208                 goto done;
209         }
210
211         status = evlog_convert_tdb_to_evt(ctx, etdb, &blob, &num_records);
212         if (!NT_STATUS_IS_OK(status)) {
213                 goto done;
214         }
215
216         if (!file_save(argv[0], blob.data, blob.length)) {
217                 d_fprintf(stderr, _("failed to save evt file: %s\n"), argv[0]);
218                 goto done;
219         }
220
221         ret = 0;
222  done:
223
224         elog_close_tdb(etdb, false);
225
226         TALLOC_FREE(ctx);
227         return ret;
228 }
229
230 /**
231  * 'net rpc eventlog' entrypoint.
232  * @param argc  Standard main() style argc.
233  * @param argv  Standard main() style argv. Initial components are already
234  *              stripped.
235  **/
236
237 int net_eventlog(struct net_context *c, int argc, const char **argv)
238 {
239         int ret = -1;
240
241         struct functable func[] = {
242                 {
243                         "dump",
244                         net_eventlog_dump,
245                         NET_TRANSPORT_LOCAL,
246                         N_("Dump eventlog"),
247                         N_("net eventlog dump\n"
248                            "    Dump win32 *.evt eventlog file")
249                 },
250                 {
251                         "import",
252                         net_eventlog_import,
253                         NET_TRANSPORT_LOCAL,
254                         N_("Import eventlog"),
255                         N_("net eventlog import\n"
256                            "    Import win32 *.evt eventlog file")
257                 },
258                 {
259                         "export",
260                         net_eventlog_export,
261                         NET_TRANSPORT_LOCAL,
262                         N_("Export eventlog"),
263                         N_("net eventlog export\n"
264                            "    Export win32 *.evt eventlog file")
265                 },
266
267
268         { NULL, NULL, 0, NULL, NULL }
269         };
270
271         ret = net_run_function(c, argc, argv, "net eventlog", func);
272
273         return ret;
274 }