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