net rpc share allowedusers: Allow restricting shares
[garming/samba-autobuild/.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 #include "lib/eventlog/eventlog.h"
25
26 /**
27  * Dump an *evt win32 eventlog file
28  *
29  * @param argc  Standard main() style argc.
30  * @param argv  Standard main() style argv. Initial components are already
31  *              stripped.
32  *
33  * @return A shell status integer (0 for success).
34  **/
35
36 static int net_eventlog_dump(struct net_context *c, int argc,
37                              const char **argv)
38 {
39         int ret = -1;
40         TALLOC_CTX *ctx = talloc_stackframe();
41         enum ndr_err_code ndr_err;
42         DATA_BLOB blob;
43         struct EVENTLOG_EVT_FILE evt;
44         char *s;
45
46         if (argc < 1 || c->display_usage) {
47                 d_fprintf(stderr, "%s\nnet eventlog dump <file.evt>\n",
48                           _("Usage:"));
49                 goto done;
50         }
51
52         blob.data = (uint8_t *)file_load(argv[0], &blob.length, 0, ctx);
53         if (!blob.data) {
54                 d_fprintf(stderr, _("failed to load evt file: %s\n"), argv[0]);
55                 goto done;
56         }
57
58         ndr_err = ndr_pull_struct_blob(&blob, ctx, &evt,
59                    (ndr_pull_flags_fn_t)ndr_pull_EVENTLOG_EVT_FILE);
60         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
61                 d_fprintf(stderr, _("evt pull failed: %s\n"),
62                           ndr_errstr(ndr_err));
63                 goto done;
64         }
65
66         s = NDR_PRINT_STRUCT_STRING(ctx, EVENTLOG_EVT_FILE, &evt);
67         if (s) {
68                 printf("%s\n", s);
69         }
70
71         ret = 0;
72  done:
73         TALLOC_FREE(ctx);
74         return ret;
75 }
76
77 /**
78  * Import an *evt win32 eventlog file to internal tdb representation
79  *
80  * @param argc  Standard main() style argc.
81  * @param argv  Standard main() style argv. Initial components are already
82  *              stripped.
83  *
84  * @return A shell status integer (0 for success).
85  **/
86
87 static int net_eventlog_import(struct net_context *c, int argc,
88                                const char **argv)
89 {
90         int ret = -1;
91         TALLOC_CTX *ctx = talloc_stackframe();
92         NTSTATUS status;
93         enum ndr_err_code ndr_err;
94         DATA_BLOB blob;
95         uint32_t num_records = 0;
96         uint32_t i;
97         ELOG_TDB *etdb = NULL;
98
99         struct EVENTLOGHEADER evt_header;
100         struct EVENTLOG_EVT_FILE evt;
101
102         if (argc < 2 || c->display_usage) {
103                 d_fprintf(stderr,
104                           "%s\nnet eventlog import <file> <eventlog>\n",
105                           _("Usage:"));
106                 goto done;
107         }
108
109         blob.data = (uint8_t *)file_load(argv[0], &blob.length, 0, ctx);
110         if (!blob.data) {
111                 d_fprintf(stderr, _("failed to load evt file: %s\n"), argv[0]);
112                 goto done;
113         }
114
115         /* dump_data(0, blob.data, blob.length); */
116         ndr_err = ndr_pull_struct_blob(&blob, ctx, &evt_header,
117                    (ndr_pull_flags_fn_t)ndr_pull_EVENTLOGHEADER);
118         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
119                 d_fprintf(stderr, _("evt header pull failed: %s\n"),
120                           ndr_errstr(ndr_err));
121                 goto done;
122         }
123
124         if (evt_header.Flags & ELF_LOGFILE_HEADER_WRAP) {
125                 d_fprintf(stderr, _("input file is wrapped, cannot proceed\n"));
126                 goto done;
127         }
128
129         ndr_err = ndr_pull_struct_blob(&blob, ctx, &evt,
130                    (ndr_pull_flags_fn_t)ndr_pull_EVENTLOG_EVT_FILE);
131         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
132                 d_fprintf(stderr, _("evt pull failed: %s\n"),
133                           ndr_errstr(ndr_err));
134                 goto done;
135         }
136
137         /* NDR_PRINT_DEBUG(EVENTLOG_EVT_FILE, &evt); */
138
139         etdb = elog_open_tdb(argv[1], false, false);
140         if (!etdb) {
141                 d_fprintf(stderr, _("can't open the eventlog TDB (%s)\n"),
142                           argv[1]);
143                 goto done;
144         }
145
146         num_records = evt.hdr.CurrentRecordNumber - evt.hdr.OldestRecordNumber;
147
148         for (i=0; i<num_records; i++) {
149                 uint32_t record_number;
150                 struct eventlog_Record_tdb e;
151
152                 status = evlog_evt_entry_to_tdb_entry(ctx, &evt.records[i], &e);
153                 if (!NT_STATUS_IS_OK(status)) {
154                         goto done;
155                 }
156
157                 status = evlog_push_record_tdb(ctx, ELOG_TDB_CTX(etdb),
158                                                &e, &record_number);
159                 if (!NT_STATUS_IS_OK(status)) {
160                         d_fprintf(stderr,
161                                   _("can't write to the eventlog: %s\n"),
162                                   nt_errstr(status));
163                         goto done;
164                 }
165         }
166
167         printf(_("wrote %d entries to tdb\n"), i);
168
169         ret = 0;
170  done:
171
172         elog_close_tdb(etdb, false);
173
174         TALLOC_FREE(ctx);
175         return ret;
176 }
177
178 /**
179  * Export internal eventlog tdb representation to an *evt win32 eventlog file
180  *
181  * @param argc  Standard main() style argc.
182  * @param argv  Standard main() style argv. Initial components are already
183  *              stripped.
184  *
185  * @return A shell status integer (0 for success).
186  **/
187
188 static int net_eventlog_export(struct net_context *c, int argc,
189                                const char **argv)
190 {
191         int ret = -1;
192         NTSTATUS status;
193         TALLOC_CTX *ctx = talloc_stackframe();
194         DATA_BLOB blob;
195         uint32_t num_records = 0;
196         ELOG_TDB *etdb = NULL;
197
198         if (argc < 2 || c->display_usage) {
199                 d_fprintf(stderr,
200                           "%s\nnet eventlog export <file> <eventlog>\n",
201                           _("Usage:"));
202                 goto done;
203         }
204
205         etdb = elog_open_tdb(argv[1], false, true);
206         if (!etdb) {
207                 d_fprintf(stderr, _("can't open the eventlog TDB (%s)\n"),
208                           argv[1]);
209                 goto done;
210         }
211
212         status = evlog_convert_tdb_to_evt(ctx, etdb, &blob, &num_records);
213         if (!NT_STATUS_IS_OK(status)) {
214                 goto done;
215         }
216
217         if (!file_save(argv[0], blob.data, blob.length)) {
218                 d_fprintf(stderr, _("failed to save evt file: %s\n"), argv[0]);
219                 goto done;
220         }
221
222         ret = 0;
223  done:
224
225         elog_close_tdb(etdb, false);
226
227         TALLOC_FREE(ctx);
228         return ret;
229 }
230
231 /**
232  * 'net rpc eventlog' entrypoint.
233  * @param argc  Standard main() style argc.
234  * @param argv  Standard main() style argv. Initial components are already
235  *              stripped.
236  **/
237
238 int net_eventlog(struct net_context *c, int argc, const char **argv)
239 {
240         int ret = -1;
241
242         struct functable func[] = {
243                 {
244                         "dump",
245                         net_eventlog_dump,
246                         NET_TRANSPORT_LOCAL,
247                         N_("Dump eventlog"),
248                         N_("net eventlog dump\n"
249                            "    Dump win32 *.evt eventlog file")
250                 },
251                 {
252                         "import",
253                         net_eventlog_import,
254                         NET_TRANSPORT_LOCAL,
255                         N_("Import eventlog"),
256                         N_("net eventlog import\n"
257                            "    Import win32 *.evt eventlog file")
258                 },
259                 {
260                         "export",
261                         net_eventlog_export,
262                         NET_TRANSPORT_LOCAL,
263                         N_("Export eventlog"),
264                         N_("net eventlog export\n"
265                            "    Export win32 *.evt eventlog file")
266                 },
267
268
269         { NULL, NULL, 0, NULL, NULL }
270         };
271
272         ret = net_run_function(c, argc, argv, "net eventlog", func);
273
274         return ret;
275 }