0cc151918a8828476800f4a37eabafc8ce55393f
[rusty/samba.git] / source3 / printing / nt_printing_migrate.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *
5  *  Copyright (c) Andreas Schneider            2010.
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 "system/filesys.h"
23 #include "printing/nt_printing_migrate.h"
24
25 #include "rpc_client/rpc_client.h"
26 #include "librpc/gen_ndr/ndr_ntprinting.h"
27 #include "librpc/gen_ndr/ndr_spoolss_c.h"
28 #include "librpc/gen_ndr/ndr_security.h"
29 #include "rpc_server/rpc_ncacn_np.h"
30 #include "auth.h"
31 #include "util_tdb.h"
32
33 #define FORMS_PREFIX "FORMS/"
34 #define DRIVERS_PREFIX "DRIVERS/"
35 #define PRINTERS_PREFIX "PRINTERS/"
36 #define SECDESC_PREFIX "SECDESC/"
37
38 static NTSTATUS migrate_form(TALLOC_CTX *mem_ctx,
39                          struct rpc_pipe_client *pipe_hnd,
40                          const char *key_name,
41                          unsigned char *data,
42                          size_t length)
43 {
44         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
45         struct spoolss_DevmodeContainer devmode_ctr;
46         struct policy_handle hnd;
47         enum ndr_err_code ndr_err;
48         struct ntprinting_form r;
49         union spoolss_AddFormInfo f;
50         struct spoolss_AddFormInfo1 f1;
51         const char *srv_name_slash;
52         DATA_BLOB blob;
53         NTSTATUS status;
54         WERROR result;
55
56
57         blob = data_blob_const(data, length);
58
59         ZERO_STRUCT(r);
60
61         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
62                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
63         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
64                 DEBUG(2, ("Form pull failed: %s\n",
65                           ndr_errstr(ndr_err)));
66                 return NT_STATUS_NO_MEMORY;
67         }
68
69         /* Don't migrate builtin forms */
70         if (r.flag == SPOOLSS_FORM_BUILTIN) {
71                 return NT_STATUS_OK;
72         }
73
74         DEBUG(2, ("Migrating Form: %s\n", key_name));
75
76         srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
77         if (srv_name_slash == NULL) {
78                 return NT_STATUS_NO_MEMORY;
79         }
80
81         ZERO_STRUCT(devmode_ctr);
82
83         status = dcerpc_spoolss_OpenPrinter(b,
84                                             mem_ctx,
85                                             srv_name_slash,
86                                             NULL,
87                                             devmode_ctr,
88                                             SEC_FLAG_MAXIMUM_ALLOWED,
89                                             &hnd,
90                                             &result);
91         if (!NT_STATUS_IS_OK(status)) {
92                 DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n",
93                           srv_name_slash, nt_errstr(status)));
94                 return status;
95         }
96         if (!W_ERROR_IS_OK(result)) {
97                 DEBUG(2, ("OpenPrinter(%s) failed: %s\n",
98                           srv_name_slash, win_errstr(result)));
99                 status = werror_to_ntstatus(result);
100                 return status;
101         }
102
103         f1.form_name = key_name;
104         f1.flags = r.flag;
105
106         f1.size.width = r.width;
107         f1.size.height = r.length;
108
109         f1.area.top = r.top;
110         f1.area.right = r.right;
111         f1.area.bottom = r.bottom;
112         f1.area.left = r.left;
113
114         f.info1 = &f1;
115
116         status = dcerpc_spoolss_AddForm(b,
117                                         mem_ctx,
118                                         &hnd,
119                                         1,
120                                         f,
121                                         &result);
122         if (!NT_STATUS_IS_OK(status)) {
123                 DEBUG(2, ("dcerpc_spoolss_AddForm(%s) refused -- %s.\n",
124                           f.info1->form_name, nt_errstr(status)));
125         } else if (!W_ERROR_IS_OK(result)) {
126                 DEBUG(2, ("AddForm(%s) refused -- %s.\n",
127                           f.info1->form_name, win_errstr(result)));
128                 status = werror_to_ntstatus(result);
129         }
130
131         dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
132
133         return status;
134 }
135
136 static NTSTATUS migrate_driver(TALLOC_CTX *mem_ctx,
137                                struct rpc_pipe_client *pipe_hnd,
138                                const char *key_name,
139                                unsigned char *data,
140                                size_t length)
141 {
142         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
143         const char *srv_name_slash;
144         enum ndr_err_code ndr_err;
145         struct ntprinting_driver r;
146         struct spoolss_AddDriverInfoCtr d;
147         struct spoolss_AddDriverInfo3 d3;
148         struct spoolss_StringArray a;
149         DATA_BLOB blob;
150         NTSTATUS status;
151         WERROR result;
152
153         blob = data_blob_const(data, length);
154
155         ZERO_STRUCT(r);
156
157         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
158                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
159         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
160                 DEBUG(2, ("Driver pull failed: %s\n",
161                           ndr_errstr(ndr_err)));
162                 return NT_STATUS_NO_MEMORY;
163         }
164
165         DEBUG(2, ("Migrating Printer Driver: %s\n", key_name));
166
167         srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
168         if (srv_name_slash == NULL) {
169                 return NT_STATUS_NO_MEMORY;
170         }
171
172         ZERO_STRUCT(d3);
173         ZERO_STRUCT(a);
174
175         a.string = r.dependent_files;
176
177         d3.architecture = r.environment;
178         d3.config_file = r.configfile;
179         d3.data_file = r.datafile;
180         d3.default_datatype = r.defaultdatatype;
181         d3.dependent_files = &a;
182         d3.driver_path = r.driverpath;
183         d3.help_file = r.helpfile;
184         d3.monitor_name = r.monitorname;
185         d3.driver_name = r.name;
186         d3.version = r.version;
187
188         d.level = 3;
189         d.info.info3 = &d3;
190
191         status = dcerpc_spoolss_AddPrinterDriver(b,
192                                                  mem_ctx,
193                                                  srv_name_slash,
194                                                  &d,
195                                                  &result);
196         if (!NT_STATUS_IS_OK(status)) {
197                 DEBUG(2, ("dcerpc_spoolss_AddPrinterDriver(%s) refused -- %s.\n",
198                           d3.driver_name, nt_errstr(status)));
199         } else if (!W_ERROR_IS_OK(result)) {
200                 DEBUG(2, ("AddPrinterDriver(%s) refused -- %s.\n",
201                           d3.driver_name, win_errstr(result)));
202                 status = werror_to_ntstatus(result);
203         }
204
205         return status;
206 }
207
208 static NTSTATUS migrate_printer(TALLOC_CTX *mem_ctx,
209                                 struct rpc_pipe_client *pipe_hnd,
210                                 const char *key_name,
211                                 unsigned char *data,
212                                 size_t length)
213 {
214         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
215         struct policy_handle hnd;
216         enum ndr_err_code ndr_err;
217         struct ntprinting_printer r;
218         struct spoolss_SetPrinterInfo2 info2;
219         struct spoolss_DeviceMode dm;
220         struct spoolss_SetPrinterInfoCtr info_ctr;
221         struct spoolss_DevmodeContainer devmode_ctr;
222         struct sec_desc_buf secdesc_ctr;
223         DATA_BLOB blob;
224         NTSTATUS status;
225         WERROR result;
226         int j;
227
228         if (strequal(key_name, "printers")) {
229                 return NT_STATUS_OK;
230         }
231
232         blob = data_blob_const(data, length);
233
234         ZERO_STRUCT(r);
235
236         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
237                    (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
238         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
239                 DEBUG(2, ("printer pull failed: %s\n",
240                           ndr_errstr(ndr_err)));
241                 return NT_STATUS_NO_MEMORY;
242         }
243
244         DEBUG(2, ("Migrating Printer: %s\n", key_name));
245
246         ZERO_STRUCT(devmode_ctr);
247
248         status = dcerpc_spoolss_OpenPrinter(b,
249                                             mem_ctx,
250                                             key_name,
251                                             NULL,
252                                             devmode_ctr,
253                                             SEC_FLAG_MAXIMUM_ALLOWED,
254                                             &hnd,
255                                             &result);
256         if (!NT_STATUS_IS_OK(status)) {
257                 DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n",
258                           key_name, nt_errstr(status)));
259                 return status;
260         }
261         if (!W_ERROR_IS_OK(result)) {
262                 DEBUG(2, ("OpenPrinter(%s) failed: %s\n",
263                           key_name, win_errstr(result)));
264                 status = werror_to_ntstatus(result);
265                 return status;
266         }
267
268         /* Create printer info level 2 */
269         ZERO_STRUCT(info2);
270         ZERO_STRUCT(secdesc_ctr);
271
272         info2.attributes = r.info.attributes;
273         info2.averageppm = r.info.averageppm;
274         info2.cjobs = r.info.cjobs;
275         info2.comment = r.info.comment;
276         info2.datatype = r.info.datatype;
277         info2.defaultpriority = r.info.default_priority;
278         info2.drivername = r.info.drivername;
279         info2.location = r.info.location;
280         info2.parameters = r.info.parameters;
281         info2.portname = r.info.portname;
282         info2.printername = r.info.printername;
283         info2.printprocessor = r.info.printprocessor;
284         info2.priority = r.info.priority;
285         info2.sepfile = r.info.sepfile;
286         info2.sharename = r.info.sharename;
287         info2.starttime = r.info.starttime;
288         info2.status = r.info.status;
289         info2.untiltime = r.info.untiltime;
290
291         /* Create Device Mode */
292         if (r.devmode != NULL) {
293                 ZERO_STRUCT(dm);
294
295                 dm.bitsperpel              = r.devmode->bitsperpel;
296                 dm.collate                 = r.devmode->collate;
297                 dm.color                   = r.devmode->color;
298                 dm.copies                  = r.devmode->copies;
299                 dm.defaultsource           = r.devmode->defaultsource;
300                 dm.devicename              = r.devmode->devicename;
301                 dm.displayflags            = r.devmode->displayflags;
302                 dm.displayfrequency        = r.devmode->displayfrequency;
303                 dm.dithertype              = r.devmode->dithertype;
304                 dm.driverversion           = r.devmode->driverversion;
305                 dm.duplex                  = r.devmode->duplex;
306                 dm.fields                  = r.devmode->fields;
307                 dm.formname                = r.devmode->formname;
308                 dm.icmintent               = r.devmode->icmintent;
309                 dm.icmmethod               = r.devmode->icmmethod;
310                 dm.logpixels               = r.devmode->logpixels;
311                 dm.mediatype               = r.devmode->mediatype;
312                 dm.orientation             = r.devmode->orientation;
313                 dm.panningheight           = r.devmode->pelsheight;
314                 dm.panningwidth            = r.devmode->panningwidth;
315                 dm.paperlength             = r.devmode->paperlength;
316                 dm.papersize               = r.devmode->papersize;
317                 dm.paperwidth              = r.devmode->paperwidth;
318                 dm.pelsheight              = r.devmode->pelsheight;
319                 dm.pelswidth               = r.devmode->pelswidth;
320                 dm.printquality            = r.devmode->printquality;
321                 dm.size                    = r.devmode->size;
322                 dm.scale                   = r.devmode->scale;
323                 dm.specversion             = r.devmode->specversion;
324                 dm.ttoption                = r.devmode->ttoption;
325                 dm.yresolution             = r.devmode->yresolution;
326
327                 if (r.devmode->nt_dev_private != NULL) {
328                         dm.driverextra_data.data   = r.devmode->nt_dev_private->data;
329                         dm.driverextra_data.length = r.devmode->nt_dev_private->length;
330                         dm.__driverextra_length    = r.devmode->nt_dev_private->length;
331                 }
332
333                 devmode_ctr.devmode = &dm;
334
335                 info2.devmode_ptr = 1;
336         }
337
338         info_ctr.info.info2 = &info2;
339         info_ctr.level = 2;
340
341         status = dcerpc_spoolss_SetPrinter(b,
342                                            mem_ctx,
343                                            &hnd,
344                                            &info_ctr,
345                                            &devmode_ctr,
346                                            &secdesc_ctr,
347                                            0, /* command */
348                                            &result);
349         if (!NT_STATUS_IS_OK(status)) {
350                 DEBUG(2, ("dcerpc_spoolss_SetPrinter(%s) level 2 refused -- %s.\n",
351                           key_name, nt_errstr(status)));
352                 goto done;
353         }
354         if (!W_ERROR_IS_OK(result)) {
355                 DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n",
356                           key_name, win_errstr(result)));
357                 status = werror_to_ntstatus(result);
358                 goto done;
359         }
360
361         /* migrate printerdata */
362         for (j = 0; j < r.count; j++) {
363                 char *valuename;
364                 const char *keyname;
365
366                 if (r.printer_data[j].type == REG_NONE) {
367                         continue;
368                 }
369
370                 keyname = r.printer_data[j].name;
371                 valuename = strchr(keyname, '\\');
372                 if (valuename == NULL) {
373                         continue;
374                 } else {
375                         valuename[0] = '\0';
376                         valuename++;
377                 }
378
379                 status = dcerpc_spoolss_SetPrinterDataEx(b,
380                                                          mem_ctx,
381                                                          &hnd,
382                                                          keyname,
383                                                          valuename,
384                                                          r.printer_data[j].type,
385                                                          r.printer_data[j].data.data,
386                                                          r.printer_data[j].data.length,
387                                                          &result);
388                 if (!NT_STATUS_IS_OK(status)) {
389                         DEBUG(2, ("dcerpc_spoolss_SetPrinterDataEx: "
390                                   "printer [%s], keyname [%s], "
391                                   "valuename [%s] refused -- %s.\n",
392                                   key_name, keyname, valuename,
393                                   nt_errstr(status)));
394                         break;
395                 }
396                 if (!W_ERROR_IS_OK(result)) {
397                         DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], "
398                                   "valuename [%s] refused -- %s.\n",
399                                   key_name, keyname, valuename,
400                                   win_errstr(result)));
401                         status = werror_to_ntstatus(result);
402                         break;
403                 }
404         }
405
406  done:
407         dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
408
409         return status;
410 }
411
412 static NTSTATUS migrate_secdesc(TALLOC_CTX *mem_ctx,
413                                 struct rpc_pipe_client *pipe_hnd,
414                                 const char *key_name,
415                                 unsigned char *data,
416                                 size_t length)
417 {
418         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
419         struct policy_handle hnd;
420         enum ndr_err_code ndr_err;
421         struct sec_desc_buf secdesc_ctr;
422         struct spoolss_SetPrinterInfo3 info3;
423         struct spoolss_SetPrinterInfoCtr info_ctr;
424         struct spoolss_DevmodeContainer devmode_ctr;
425         DATA_BLOB blob;
426         NTSTATUS status;
427         WERROR result;
428
429         if (strequal(key_name, "printers")) {
430                 return NT_STATUS_OK;
431         }
432
433         blob = data_blob_const(data, length);
434
435         ZERO_STRUCT(secdesc_ctr);
436
437         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
438                    (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
439         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
440                 DEBUG(2, ("security descriptor pull failed: %s\n",
441                           ndr_errstr(ndr_err)));
442                 return NT_STATUS_NO_MEMORY;
443         }
444
445         DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name));
446
447         ZERO_STRUCT(devmode_ctr);
448
449         status = dcerpc_spoolss_OpenPrinter(b,
450                                             mem_ctx,
451                                             key_name,
452                                             NULL,
453                                             devmode_ctr,
454                                             SEC_FLAG_MAXIMUM_ALLOWED,
455                                             &hnd,
456                                             &result);
457         if (!NT_STATUS_IS_OK(status)) {
458                 DEBUG(2, ("dcerpc_spoolss_OpenPrinter(%s) failed: %s\n",
459                           key_name, nt_errstr(status)));
460                 return status;
461         }
462         if (W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME, result)) {
463                 DEBUG(3, ("Ignoring missing printer %s\n", key_name));
464                 return NT_STATUS_OK;
465         }
466         if (!W_ERROR_IS_OK(result)) {
467                 DEBUG(2, ("OpenPrinter(%s) failed: %s\n",
468                           key_name, win_errstr(result)));
469                 status = werror_to_ntstatus(result);
470                 return status;
471         }
472
473         ZERO_STRUCT(devmode_ctr);
474
475         info3.sec_desc_ptr = 1;
476
477         info_ctr.info.info3 = &info3;
478         info_ctr.level = 3;
479
480         status = dcerpc_spoolss_SetPrinter(b,
481                                            mem_ctx,
482                                            &hnd,
483                                            &info_ctr,
484                                            &devmode_ctr,
485                                            &secdesc_ctr,
486                                            0, /* command */
487                                            &result);
488         if (!NT_STATUS_IS_OK(status)) {
489                 DEBUG(2, ("dcerpc_spoolss_SetPrinter(%s) level 3 refused -- %s.\n",
490                           key_name, nt_errstr(status)));
491         } else if (!W_ERROR_IS_OK(result)) {
492                 DEBUG(2, ("SetPrinter(%s) level 3 refused -- %s.\n",
493                           key_name, win_errstr(result)));
494                 status = werror_to_ntstatus(result);
495         }
496
497         dcerpc_spoolss_ClosePrinter(b, mem_ctx, &hnd, &result);
498
499         return status;
500 }
501
502 static int rename_file_with_suffix(TALLOC_CTX *mem_ctx,
503                                    const char *path,
504                                    const char *suffix)
505 {
506         int rc = -1;
507         char *dst_path;
508
509         dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix);
510         if (dst_path == NULL) {
511                 DEBUG(3, ("error out of memory\n"));
512                 return rc;
513         }
514
515         rc = (rename(path, dst_path) != 0);
516
517         if (rc == 0) {
518                 DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
519         } else if (errno == ENOENT) {
520                 DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
521                 rc = 0;
522         } else {
523                 DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
524                           strerror(errno)));
525         }
526
527         TALLOC_FREE(dst_path);
528         return rc;
529 }
530
531 static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
532                                  const char *tdb_path,
533                                  struct rpc_pipe_client *pipe_hnd)
534 {
535         const char *backup_suffix = ".bak";
536         TDB_DATA kbuf, dbuf;
537         TDB_CONTEXT *tdb;
538         NTSTATUS status;
539         int rc;
540
541         tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600);
542         if (tdb == NULL && errno == ENOENT) {
543                 /* if we have no printers database then migration is
544                    considered successful */
545                 DEBUG(4, ("No printers database to migrate in %s\n", tdb_path));
546                 return NT_STATUS_OK;
547         }
548         if (tdb == NULL) {
549                 DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path));
550                 return NT_STATUS_NO_SUCH_FILE;
551         }
552
553         for (kbuf = tdb_firstkey_compat(tdb);
554              kbuf.dptr;
555              kbuf = tdb_nextkey_compat(tdb, kbuf))
556         {
557                 dbuf = tdb_fetch_compat(tdb, kbuf);
558                 if (!dbuf.dptr) {
559                         continue;
560                 }
561
562                 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
563                         status = migrate_form(mem_ctx,
564                                               pipe_hnd,
565                                               (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
566                                               dbuf.dptr,
567                                               dbuf.dsize);
568                         SAFE_FREE(dbuf.dptr);
569                         if (!NT_STATUS_IS_OK(status)) {
570                                 tdb_close(tdb);
571                                 return status;
572                         }
573                         continue;
574                 }
575
576                 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
577                         status = migrate_driver(mem_ctx,
578                                                 pipe_hnd,
579                                                 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
580                                                 dbuf.dptr,
581                                                 dbuf.dsize);
582                         SAFE_FREE(dbuf.dptr);
583                         if (!NT_STATUS_IS_OK(status)) {
584                                 tdb_close(tdb);
585                                 return status;
586                         }
587                         continue;
588                 }
589
590                 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
591                         status = migrate_printer(mem_ctx,
592                                                  pipe_hnd,
593                                                  (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
594                                                  dbuf.dptr,
595                                                  dbuf.dsize);
596                         SAFE_FREE(dbuf.dptr);
597                         if (!NT_STATUS_IS_OK(status)) {
598                                 tdb_close(tdb);
599                                 return status;
600                         }
601                         continue;
602                 }
603
604                 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
605                         status = migrate_secdesc(mem_ctx,
606                                                  pipe_hnd,
607                                                  (const char *) kbuf.dptr + strlen(SECDESC_PREFIX),
608                                                  dbuf.dptr,
609                                                  dbuf.dsize);
610                         SAFE_FREE(dbuf.dptr);
611                         if (!NT_STATUS_IS_OK(status)) {
612                                 tdb_close(tdb);
613                                 return status;
614                         }
615                         continue;
616                 }
617         }
618
619         tdb_close(tdb);
620
621         rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix);
622         if (rc != 0) {
623                 DEBUG(0, ("Error moving tdb to '%s%s'\n",
624                           tdb_path, backup_suffix));
625         }
626
627         return NT_STATUS_OK;
628 }
629
630 bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx)
631 {
632         const char *drivers_path = state_path("ntdrivers.tdb");
633         const char *printers_path = state_path("ntprinters.tdb");
634         const char *forms_path = state_path("ntforms.tdb");
635         bool drivers_exists = file_exist(drivers_path);
636         bool printers_exists = file_exist(printers_path);
637         bool forms_exists = file_exist(forms_path);
638         struct auth_serversupplied_info *session_info;
639         struct rpc_pipe_client *spoolss_pipe = NULL;
640         TALLOC_CTX *tmp_ctx = talloc_stackframe();
641         NTSTATUS status;
642
643         if (!drivers_exists && !printers_exists && !forms_exists) {
644                 return true;
645         }
646
647         status = make_session_info_system(tmp_ctx, &session_info);
648         if (!NT_STATUS_IS_OK(status)) {
649                 DEBUG(0, ("Couldn't create session_info: %s\n",
650                           nt_errstr(status)));
651                 talloc_free(tmp_ctx);
652                 return false;
653         }
654
655         status = rpc_pipe_open_interface(tmp_ctx,
656                                         &ndr_table_spoolss.syntax_id,
657                                         session_info,
658                                         NULL,
659                                         msg_ctx,
660                                         &spoolss_pipe);
661         if (!NT_STATUS_IS_OK(status)) {
662                 DEBUG(0, ("Couldn't open internal spoolss pipe: %s\n",
663                           nt_errstr(status)));
664                 talloc_free(tmp_ctx);
665                 return false;
666         }
667
668         if (drivers_exists) {
669                 status = migrate_internal(tmp_ctx, drivers_path, spoolss_pipe);
670                 if (!NT_STATUS_IS_OK(status)) {
671                         DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n",
672                           nt_errstr(status)));
673                         talloc_free(tmp_ctx);
674                         return false;
675                 }
676         }
677
678         if (printers_exists) {
679                 status = migrate_internal(tmp_ctx, printers_path, spoolss_pipe);
680                 if (!NT_STATUS_IS_OK(status)) {
681                         DEBUG(0, ("Couldn't migrate printers tdb file: %s\n",
682                                   nt_errstr(status)));
683                         talloc_free(tmp_ctx);
684                         return false;
685                 }
686         }
687
688         if (forms_exists) {
689                 status = migrate_internal(tmp_ctx, forms_path, spoolss_pipe);
690                 if (!NT_STATUS_IS_OK(status)) {
691                         DEBUG(0, ("Couldn't migrate forms tdb file: %s\n",
692                                   nt_errstr(status)));
693                         talloc_free(tmp_ctx);
694                         return false;
695                 }
696         }
697
698         talloc_free(tmp_ctx);
699         return true;
700 }