s3-net: use printing_migrate library, and eliminate duplicate code.
[Samba/vl.git] / source3 / utils / net_printing.c
blobc919d3775e2ff665e12012b5e8b0a250ce28ed95
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Local printing tdb migration interface
6 Copyright (C) Guenther Deschner 2010
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.
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.
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/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "utils/net.h"
25 #include "rpc_client/rpc_client.h"
26 #include "librpc/gen_ndr/ndr_ntprinting.h"
27 #include "librpc/gen_ndr/ndr_spoolss.h"
28 #include "../libcli/security/security.h"
29 #include "../librpc/gen_ndr/ndr_security.h"
30 #include "util_tdb.h"
31 #include "printing/nt_printing_migrate.h"
33 #define FORMS_PREFIX "FORMS/"
34 #define DRIVERS_PREFIX "DRIVERS/"
35 #define PRINTERS_PREFIX "PRINTERS/"
36 #define SECDESC_PREFIX "SECDESC/"
38 static void dump_form(TALLOC_CTX *mem_ctx,
39 const char *key_name,
40 unsigned char *data,
41 size_t length)
43 enum ndr_err_code ndr_err;
44 DATA_BLOB blob;
45 char *s;
46 struct ntprinting_form r;
48 printf("found form: %s\n", key_name);
50 blob = data_blob_const(data, length);
52 ZERO_STRUCT(r);
54 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
55 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
56 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
57 d_fprintf(stderr, _("form pull failed: %s\n"),
58 ndr_errstr(ndr_err));
59 return;
62 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_form, &r);
63 if (s) {
64 printf("%s\n", s);
68 static void dump_driver(TALLOC_CTX *mem_ctx,
69 const char *key_name,
70 unsigned char *data,
71 size_t length)
73 enum ndr_err_code ndr_err;
74 DATA_BLOB blob;
75 char *s;
76 struct ntprinting_driver r;
78 printf("found driver: %s\n", key_name);
80 blob = data_blob_const(data, length);
82 ZERO_STRUCT(r);
84 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
85 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
86 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
87 d_fprintf(stderr, _("driver pull failed: %s\n"),
88 ndr_errstr(ndr_err));
89 return;
92 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_driver, &r);
93 if (s) {
94 printf("%s\n", s);
98 static void dump_printer(TALLOC_CTX *mem_ctx,
99 const char *key_name,
100 unsigned char *data,
101 size_t length)
103 enum ndr_err_code ndr_err;
104 DATA_BLOB blob;
105 char *s;
106 struct ntprinting_printer r;
108 printf("found printer: %s\n", key_name);
110 blob = data_blob_const(data, length);
112 ZERO_STRUCT(r);
114 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
115 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_printer);
116 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
117 d_fprintf(stderr, _("printer pull failed: %s\n"),
118 ndr_errstr(ndr_err));
119 return;
122 s = NDR_PRINT_STRUCT_STRING(mem_ctx, ntprinting_printer, &r);
123 if (s) {
124 printf("%s\n", s);
128 static void dump_sd(TALLOC_CTX *mem_ctx,
129 const char *key_name,
130 unsigned char *data,
131 size_t length)
133 enum ndr_err_code ndr_err;
134 DATA_BLOB blob;
135 char *s;
136 struct sec_desc_buf r;
138 printf("found security descriptor: %s\n", key_name);
140 blob = data_blob_const(data, length);
142 ZERO_STRUCT(r);
144 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
145 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
146 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
147 d_fprintf(stderr, _("security descriptor pull failed: %s\n"),
148 ndr_errstr(ndr_err));
149 return;
152 s = NDR_PRINT_STRUCT_STRING(mem_ctx, sec_desc_buf, &r);
153 if (s) {
154 printf("%s\n", s);
159 static int net_printing_dump(struct net_context *c, int argc,
160 const char **argv)
162 int ret = -1;
163 TALLOC_CTX *ctx = talloc_stackframe();
164 TDB_CONTEXT *tdb;
165 TDB_DATA kbuf, dbuf;
167 if (argc < 1 || c->display_usage) {
168 d_fprintf(stderr, "%s\nnet printing dump <file.tdb>\n",
169 _("Usage:"));
170 goto done;
173 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
174 if (!tdb) {
175 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
176 goto done;
179 for (kbuf = tdb_firstkey_compat(tdb);
180 kbuf.dptr;
181 kbuf = tdb_nextkey_compat(tdb, kbuf))
183 dbuf = tdb_fetch_compat(tdb, kbuf);
184 if (!dbuf.dptr) {
185 continue;
188 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
189 dump_form(ctx, (const char *)kbuf.dptr+strlen(FORMS_PREFIX), dbuf.dptr, dbuf.dsize);
190 SAFE_FREE(dbuf.dptr);
191 continue;
194 if (strncmp((const char *)kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
195 dump_driver(ctx, (const char *)kbuf.dptr+strlen(DRIVERS_PREFIX), dbuf.dptr, dbuf.dsize);
196 SAFE_FREE(dbuf.dptr);
197 continue;
200 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
201 dump_printer(ctx, (const char *)kbuf.dptr+strlen(PRINTERS_PREFIX), dbuf.dptr, dbuf.dsize);
202 SAFE_FREE(dbuf.dptr);
203 continue;
206 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
207 dump_sd(ctx, (const char *)kbuf.dptr+strlen(SECDESC_PREFIX), dbuf.dptr, dbuf.dsize);
208 SAFE_FREE(dbuf.dptr);
209 continue;
214 ret = 0;
216 done:
217 talloc_free(ctx);
218 return ret;
221 static NTSTATUS printing_migrate_internal(struct net_context *c,
222 const struct dom_sid *domain_sid,
223 const char *domain_name,
224 struct cli_state *cli,
225 struct rpc_pipe_client *pipe_hnd,
226 TALLOC_CTX *mem_ctx,
227 int argc,
228 const char **argv)
230 TALLOC_CTX *tmp_ctx;
231 TDB_CONTEXT *tdb;
232 TDB_DATA kbuf, dbuf;
233 NTSTATUS status;
235 tmp_ctx = talloc_new(mem_ctx);
236 if (tmp_ctx == NULL) {
237 return NT_STATUS_NO_MEMORY;
240 tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
241 if (tdb == NULL) {
242 d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
243 status = NT_STATUS_NO_SUCH_FILE;
244 goto done;
247 for (kbuf = tdb_firstkey_compat(tdb);
248 kbuf.dptr;
249 kbuf = tdb_nextkey_compat(tdb, kbuf))
251 dbuf = tdb_fetch_compat(tdb, kbuf);
252 if (!dbuf.dptr) {
253 continue;
256 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
257 printing_tdb_migrate_form(tmp_ctx,
258 pipe_hnd,
259 (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
260 dbuf.dptr,
261 dbuf.dsize);
262 SAFE_FREE(dbuf.dptr);
263 continue;
266 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
267 printing_tdb_migrate_driver(tmp_ctx,
268 pipe_hnd,
269 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
270 dbuf.dptr,
271 dbuf.dsize);
272 SAFE_FREE(dbuf.dptr);
273 continue;
276 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
277 printing_tdb_migrate_printer(tmp_ctx,
278 pipe_hnd,
279 (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
280 dbuf.dptr,
281 dbuf.dsize);
282 SAFE_FREE(dbuf.dptr);
283 continue;
286 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
287 printing_tdb_migrate_secdesc(tmp_ctx,
288 pipe_hnd,
289 (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
290 dbuf.dptr,
291 dbuf.dsize);
292 SAFE_FREE(dbuf.dptr);
293 continue;
298 status = NT_STATUS_OK;
300 done:
301 talloc_free(tmp_ctx);
302 return status;
305 static int net_printing_migrate(struct net_context *c,
306 int argc,
307 const char **argv)
309 if (argc < 1 || c->display_usage) {
310 d_printf( "%s\n"
311 "net printing migrate <file.tdb>\n"
312 " %s\n",
313 _("Usage:"),
314 _("Migrate tdb printing files to new storage"));
315 return 0;
318 return run_rpc_command(c,
319 NULL,
320 &ndr_table_spoolss.syntax_id,
322 printing_migrate_internal,
323 argc,
324 argv);
327 * 'net printing' entrypoint.
328 * @param argc Standard main() style argc.
329 * @param argv Standard main() style argv. Initial components are already
330 * stripped.
333 int net_printing(struct net_context *c, int argc, const char **argv)
335 int ret = -1;
337 struct functable func[] = {
339 "dump",
340 net_printing_dump,
341 NET_TRANSPORT_LOCAL,
342 N_("Dump printer databases"),
343 N_("net printing dump\n"
344 " Dump tdb printing file")
348 "migrate",
349 net_printing_migrate,
350 NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC,
351 N_("Migrate printer databases"),
352 N_("net printing migrate\n"
353 " Migrate tdb printing files to new storage")
356 { NULL, NULL, 0, NULL, NULL }
359 ret = net_run_function(c, argc, argv, "net printing", func);
361 return ret;