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