s3-auth Use the common gensec_ntlmssp_update in gensec_ntlmssp3_server
[ira/wip.git] / source3 / utils / net_printing.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Local printing tdb migration interface
5
6    Copyright (C) Guenther Deschner 2010
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 "system/filesys.h"
24 #include "utils/net.h"
25 #include "rpc_client/rpc_client.h"
26 #include "rpc_client/cli_pipe.h"
27 #include "librpc/gen_ndr/ndr_ntprinting.h"
28 #include "librpc/gen_ndr/ndr_spoolss.h"
29 #include "../libcli/security/security.h"
30 #include "../librpc/gen_ndr/ndr_security.h"
31 #include "../librpc/gen_ndr/ndr_winreg.h"
32 #include "util_tdb.h"
33 #include "printing/nt_printing_migrate.h"
34
35 #define FORMS_PREFIX "FORMS/"
36 #define DRIVERS_PREFIX "DRIVERS/"
37 #define PRINTERS_PREFIX "PRINTERS/"
38 #define SECDESC_PREFIX "SECDESC/"
39
40 static void dump_form(TALLOC_CTX *mem_ctx,
41                       const char *key_name,
42                       unsigned char *data,
43                       size_t length)
44 {
45         enum ndr_err_code ndr_err;
46         DATA_BLOB blob;
47         char *s;
48         struct ntprinting_form r;
49
50         printf("found form: %s\n", key_name);
51
52         blob = data_blob_const(data, length);
53
54         ZERO_STRUCT(r);
55
56         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
57                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
58         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
59                 d_fprintf(stderr, _("form pull failed: %s\n"),
60                           ndr_errstr(ndr_err));
61                 return;
62         }
63
64         s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
65         if (s) {
66                 printf("%s\n", s);
67         }
68 }
69
70 static void dump_driver(TALLOC_CTX *mem_ctx,
71                         const char *key_name,
72                         unsigned char *data,
73                         size_t length)
74 {
75         enum ndr_err_code ndr_err;
76         DATA_BLOB blob;
77         char *s;
78         struct ntprinting_driver r;
79
80         printf("found driver: %s\n", key_name);
81
82         blob = data_blob_const(data, length);
83
84         ZERO_STRUCT(r);
85
86         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
87                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
88         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
89                 d_fprintf(stderr, _("driver pull failed: %s\n"),
90                           ndr_errstr(ndr_err));
91                 return;
92         }
93
94         s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
95         if (s) {
96                 printf("%s\n", s);
97         }
98 }
99
100 static void dump_printer(TALLOC_CTX *mem_ctx,
101                          const char *key_name,
102                          unsigned char *data,
103                          size_t length)
104 {
105         enum ndr_err_code ndr_err;
106         DATA_BLOB blob;
107         char *s;
108         struct ntprinting_printer r;
109
110         printf("found printer: %s\n", key_name);
111
112         blob = data_blob_const(data, length);
113
114         ZERO_STRUCT(r);
115
116         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
117                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
118         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
119                 d_fprintf(stderr, _("printer pull failed: %s\n"),
120                           ndr_errstr(ndr_err));
121                 return;
122         }
123
124         s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
125         if (s) {
126                 printf("%s\n", s);
127         }
128 }
129
130 static void dump_sd(TALLOC_CTX *mem_ctx,
131                     const char *key_name,
132                     unsigned char *data,
133                     size_t length)
134 {
135         enum ndr_err_code ndr_err;
136         DATA_BLOB blob;
137         char *s;
138         struct sec_desc_buf r;
139
140         printf("found security descriptor: %s\n", key_name);
141
142         blob = data_blob_const(data, length);
143
144         ZERO_STRUCT(r);
145
146         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
147                    (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
148         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
149                 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
150                           ndr_errstr(ndr_err));
151                 return;
152         }
153
154         s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
155         if (s) {
156                 printf("%s\n", s);
157         }
158 }
159
160
161 static int net_printing_dump(struct net_context *c, int argc,
162                              const char **argv)
163 {
164         int ret = -1;
165         TALLOC_CTX *ctx = talloc_stackframe();
166         TDB_CONTEXT *tdb;
167         TDB_DATA kbuf, dbuf;
168
169         if (argc < 1 || c->display_usage) {
170                 d_fprintf(stderr, "%s\nnet printing dump <file.tdb>\n",
171                           _("Usage:"));
172                 goto done;
173         }
174
175         tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
176         if (!tdb) {
177                 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
178                 goto done;
179         }
180
181         for (kbuf = tdb_firstkey_compat(tdb);
182              kbuf.dptr;
183              kbuf = tdb_nextkey_compat(tdb, kbuf))
184         {
185                 dbuf = tdb_fetch_compat(tdb, kbuf);
186                 if (!dbuf.dptr) {
187                         continue;
188                 }
189
190                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
191                         dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize);
192                         SAFE_FREE(dbuf.dptr);
193                         continue;
194                 }
195
196                 if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
197                         dump_driver(ctx, (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize);
198                         SAFE_FREE(dbuf.dptr);
199                         continue;
200                 }
201
202                 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
203                         dump_printer(ctx, (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize);
204                         SAFE_FREE(dbuf.dptr);
205                         continue;
206                 }
207
208                 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
209                         dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
210                         SAFE_FREE(dbuf.dptr);
211                         continue;
212                 }
213
214         }
215
216         ret = 0;
217
218  done:
219         talloc_free(ctx);
220         return ret;
221 }
222
223 static NTSTATUS printing_migrate_internal(struct net_context *c,
224                                           const struct dom_sid *domain_sid,
225                                           const char *domain_name,
226                                           struct cli_state *cli,
227                                           struct rpc_pipe_client *winreg_pipe,
228                                           TALLOC_CTX *mem_ctx,
229                                           int argc,
230                                           const char **argv)
231 {
232         TALLOC_CTX *tmp_ctx;
233         TDB_CONTEXT *tdb;
234         TDB_DATA kbuf, dbuf;
235         NTSTATUS status;
236
237         tmp_ctx = talloc_new(mem_ctx);
238         if (tmp_ctx == NULL) {
239                 return NT_STATUS_NO_MEMORY;
240         }
241
242         tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
243         if (tdb == NULL) {
244                 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
245                 status = NT_STATUS_NO_SUCH_FILE;
246                 goto done;
247         }
248
249         for (kbuf = tdb_firstkey_compat(tdb);
250              kbuf.dptr;
251              kbuf = tdb_nextkey_compat(tdb, kbuf))
252         {
253                 dbuf = tdb_fetch_compat(tdb, kbuf);
254                 if (!dbuf.dptr) {
255                         continue;
256                 }
257
258                 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
259                         printing_tdb_migrate_form(tmp_ctx,
260                                      winreg_pipe,
261                                      (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
262                                      dbuf.dptr,
263                                      dbuf.dsize);
264                         SAFE_FREE(dbuf.dptr);
265                         continue;
266                 }
267
268                 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
269                         printing_tdb_migrate_driver(tmp_ctx,
270                                        winreg_pipe,
271                                        (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
272                                        dbuf.dptr,
273                                        dbuf.dsize);
274                         SAFE_FREE(dbuf.dptr);
275                         continue;
276                 }
277
278                 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
279                         printing_tdb_migrate_printer(tmp_ctx,
280                                         winreg_pipe,
281                                         (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
282                                         dbuf.dptr,
283                                         dbuf.dsize);
284                         SAFE_FREE(dbuf.dptr);
285                         continue;
286                 }
287                 SAFE_FREE(dbuf.dptr);
288         }
289
290         for (kbuf = tdb_firstkey_compat(tdb);
291              kbuf.dptr;
292              kbuf = tdb_nextkey_compat(tdb, kbuf))
293         {
294                 dbuf = tdb_fetch_compat(tdb, kbuf);
295                 if (!dbuf.dptr) {
296                         continue;
297                 }
298
299                 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
300                         printing_tdb_migrate_secdesc(tmp_ctx,
301                                         winreg_pipe,
302                                         (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
303                                         dbuf.dptr,
304                                         dbuf.dsize);
305                         SAFE_FREE(dbuf.dptr);
306                         continue;
307                 }
308                 SAFE_FREE(dbuf.dptr);
309
310         }
311
312         status = NT_STATUS_OK;
313
314  done:
315         talloc_free(tmp_ctx);
316         return status;
317 }
318
319 static int net_printing_migrate(struct net_context *c,
320                                 int argc,
321                                 const char **argv)
322 {
323         if (argc < 1 || c->display_usage) {
324                 d_printf(  "%s\n"
325                            "net printing migrate <file.tdb>\n"
326                            "    %s\n",
327                          _("Usage:"),
328                          _("Migrate tdb printing files to new storage"));
329                 return 0;
330         }
331
332         return run_rpc_command(c,
333                                NULL,
334                                &ndr_table_winreg,
335                                0,
336                                printing_migrate_internal,
337                                argc,
338                                argv);
339 }
340 /**
341  * 'net printing' entrypoint.
342  * @param argc  Standard main() style argc.
343  * @param argv  Standard main() style argv. Initial components are already
344  *              stripped.
345  **/
346
347 int net_printing(struct net_context *c, int argc, const char **argv)
348 {
349         int ret = -1;
350
351         struct functable func[] = {
352                 {
353                         "dump",
354                         net_printing_dump,
355                         NET_TRANSPORT_LOCAL,
356                         N_("Dump printer databases"),
357                         N_("net printing dump\n"
358                            "    Dump tdb printing file")
359                 },
360
361                 {
362                         "migrate",
363                         net_printing_migrate,
364                         NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
365                         N_("Migrate printer databases"),
366                         N_("net printing migrate\n"
367                            "    Migrate tdb printing files to new storage")
368                 },
369
370         { NULL, NULL, 0, NULL, NULL }
371         };
372
373         ret = net_run_function(c, argc, argv, "net printing", func);
374
375         return ret;
376 }