s3-printing: fill info2_mask in printer migration
[vlendec/samba-autobuild/.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 "rpc_client/rpc_client.h"
25 #include "librpc/gen_ndr/ndr_ntprinting.h"
26 #include "librpc/gen_ndr/ndr_spoolss_c.h"
27 #include "librpc/gen_ndr/ndr_security.h"
28 #include "rpc_client/cli_winreg_spoolss.h"
29
30 NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx,
31                                    struct rpc_pipe_client *winreg_pipe,
32                                    const char *key_name,
33                                    unsigned char *data,
34                                    size_t length)
35 {
36         struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
37         enum ndr_err_code ndr_err;
38         struct ntprinting_form r;
39         struct spoolss_AddFormInfo1 f1;
40         DATA_BLOB blob;
41         WERROR result;
42
43         blob = data_blob_const(data, length);
44
45         ZERO_STRUCT(r);
46
47         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
48                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
49         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
50                 DEBUG(2, ("Form pull failed: %s\n",
51                           ndr_errstr(ndr_err)));
52                 return NT_STATUS_NO_MEMORY;
53         }
54
55         /* Don't migrate builtin forms */
56         if (r.flag == SPOOLSS_FORM_BUILTIN) {
57                 return NT_STATUS_OK;
58         }
59
60         DEBUG(2, ("Migrating Form: %s\n", key_name));
61
62         f1.form_name = key_name;
63         f1.flags = r.flag;
64
65         f1.size.width = r.width;
66         f1.size.height = r.length;
67
68         f1.area.top = r.top;
69         f1.area.right = r.right;
70         f1.area.bottom = r.bottom;
71         f1.area.left = r.left;
72
73         result = winreg_printer_addform1(mem_ctx,
74                                          b,
75                                          &f1);
76         if (!W_ERROR_IS_OK(result)) {
77                 return werror_to_ntstatus(result);
78         }
79
80         return NT_STATUS_OK;
81 }
82
83 NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
84                                      struct rpc_pipe_client *winreg_pipe,
85                                      const char *key_name,
86                                      unsigned char *data,
87                                      size_t length)
88 {
89         struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
90         enum ndr_err_code ndr_err;
91         struct ntprinting_driver r;
92         struct spoolss_AddDriverInfoCtr d;
93         struct spoolss_AddDriverInfo3 d3;
94         struct spoolss_StringArray a;
95         DATA_BLOB blob;
96         WERROR result;
97         const char *driver_name;
98         uint32_t driver_version;
99
100         blob = data_blob_const(data, length);
101
102         ZERO_STRUCT(r);
103
104         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
105                    (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
106         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
107                 DEBUG(2, ("Driver pull failed: %s\n",
108                           ndr_errstr(ndr_err)));
109                 return NT_STATUS_NO_MEMORY;
110         }
111
112         DEBUG(2, ("Migrating Printer Driver: %s\n", key_name));
113
114         ZERO_STRUCT(d3);
115         ZERO_STRUCT(a);
116
117         a.string = r.dependent_files;
118
119         d3.architecture = r.environment;
120         d3.config_file = r.configfile;
121         d3.data_file = r.datafile;
122         d3.default_datatype = r.defaultdatatype;
123         d3.dependent_files = &a;
124         d3.driver_path = r.driverpath;
125         d3.help_file = r.helpfile;
126         d3.monitor_name = r.monitorname;
127         d3.driver_name = r.name;
128         d3.version = r.version;
129
130         d.level = 3;
131         d.info.info3 = &d3;
132
133         result = winreg_add_driver(mem_ctx,
134                                    b,
135                                    &d,
136                                    &driver_name,
137                                    &driver_version);
138         if (!W_ERROR_IS_OK(result)) {
139                 return werror_to_ntstatus(result);
140         }
141
142         return NT_STATUS_OK;
143 }
144
145 NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
146                                       struct rpc_pipe_client *winreg_pipe,
147                                       const char *key_name,
148                                       unsigned char *data,
149                                       size_t length)
150 {
151         struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
152         enum ndr_err_code ndr_err;
153         struct ntprinting_printer r;
154         struct spoolss_SetPrinterInfo2 info2;
155         struct spoolss_DeviceMode dm;
156         struct spoolss_DevmodeContainer devmode_ctr;
157         DATA_BLOB blob;
158         NTSTATUS status;
159         WERROR result;
160         int j;
161         uint32_t info2_mask = (SPOOLSS_PRINTER_INFO_ALL)
162                                 & ~SPOOLSS_PRINTER_INFO_SECDESC;
163
164         if (strequal(key_name, "printers")) {
165                 return NT_STATUS_OK;
166         }
167
168         blob = data_blob_const(data, length);
169
170         ZERO_STRUCT(r);
171
172         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
173                    (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
174         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
175                 DEBUG(2, ("printer pull failed: %s\n",
176                           ndr_errstr(ndr_err)));
177                 return NT_STATUS_NO_MEMORY;
178         }
179
180         DEBUG(2, ("Migrating Printer: %s\n", key_name));
181
182         ZERO_STRUCT(devmode_ctr);
183
184         /* Create printer info level 2 */
185         ZERO_STRUCT(info2);
186
187         info2.attributes = r.info.attributes;
188         info2.averageppm = r.info.averageppm;
189         info2.cjobs = r.info.cjobs;
190         info2.comment = r.info.comment;
191         info2.datatype = r.info.datatype;
192         info2.defaultpriority = r.info.default_priority;
193         info2.drivername = r.info.drivername;
194         info2.location = r.info.location;
195         info2.parameters = r.info.parameters;
196         info2.portname = r.info.portname;
197         info2.printername = r.info.printername;
198         info2.printprocessor = r.info.printprocessor;
199         info2.priority = r.info.priority;
200         info2.sepfile = r.info.sepfile;
201         info2.sharename = r.info.sharename;
202         info2.starttime = r.info.starttime;
203         info2.status = r.info.status;
204         info2.untiltime = r.info.untiltime;
205
206         /* Create Device Mode */
207         if (r.devmode == NULL) {
208                 info2_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
209         } else {
210                 ZERO_STRUCT(dm);
211
212                 dm.bitsperpel              = r.devmode->bitsperpel;
213                 dm.collate                 = r.devmode->collate;
214                 dm.color                   = r.devmode->color;
215                 dm.copies                  = r.devmode->copies;
216                 dm.defaultsource           = r.devmode->defaultsource;
217                 dm.devicename              = r.devmode->devicename;
218                 dm.displayflags            = r.devmode->displayflags;
219                 dm.displayfrequency        = r.devmode->displayfrequency;
220                 dm.dithertype              = r.devmode->dithertype;
221                 dm.driverversion           = r.devmode->driverversion;
222                 dm.duplex                  = r.devmode->duplex;
223                 dm.fields                  = r.devmode->fields;
224                 dm.formname                = r.devmode->formname;
225                 dm.icmintent               = r.devmode->icmintent;
226                 dm.icmmethod               = r.devmode->icmmethod;
227                 dm.logpixels               = r.devmode->logpixels;
228                 dm.mediatype               = r.devmode->mediatype;
229                 dm.orientation             = r.devmode->orientation;
230                 dm.panningheight           = r.devmode->pelsheight;
231                 dm.panningwidth            = r.devmode->panningwidth;
232                 dm.paperlength             = r.devmode->paperlength;
233                 dm.papersize               = r.devmode->papersize;
234                 dm.paperwidth              = r.devmode->paperwidth;
235                 dm.pelsheight              = r.devmode->pelsheight;
236                 dm.pelswidth               = r.devmode->pelswidth;
237                 dm.printquality            = r.devmode->printquality;
238                 dm.size                    = r.devmode->size;
239                 dm.scale                   = r.devmode->scale;
240                 dm.specversion             = r.devmode->specversion;
241                 dm.ttoption                = r.devmode->ttoption;
242                 dm.yresolution             = r.devmode->yresolution;
243
244                 if (r.devmode->nt_dev_private != NULL) {
245                         dm.driverextra_data.data   = r.devmode->nt_dev_private->data;
246                         dm.driverextra_data.length = r.devmode->nt_dev_private->length;
247                         dm.__driverextra_length    = r.devmode->nt_dev_private->length;
248                 }
249
250                 devmode_ctr.devmode = &dm;
251
252                 info2.devmode_ptr = 1;
253         }
254
255         result = winreg_update_printer(mem_ctx, b,
256                                        key_name,
257                                        info2_mask,
258                                        &info2,
259                                        &dm,
260                                        NULL);
261         if (!W_ERROR_IS_OK(result)) {
262                 DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n",
263                           key_name, win_errstr(result)));
264                 status = werror_to_ntstatus(result);
265                 goto done;
266         }
267
268         /* migrate printerdata */
269         for (j = 0; j < r.count; j++) {
270                 char *valuename;
271                 const char *keyname;
272
273                 if (r.printer_data[j].type == REG_NONE) {
274                         continue;
275                 }
276
277                 keyname = r.printer_data[j].name;
278                 valuename = strchr(keyname, '\\');
279                 if (valuename == NULL) {
280                         continue;
281                 } else {
282                         valuename[0] = '\0';
283                         valuename++;
284                 }
285
286                 result = winreg_set_printer_dataex(mem_ctx, b,
287                                                    key_name,
288                                                    keyname,
289                                                    valuename,
290                                                    r.printer_data[j].type,
291                                                    r.printer_data[j].data.data,
292                                                    r.printer_data[j].data.length);
293                 if (!W_ERROR_IS_OK(result)) {
294                         DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], "
295                                   "valuename [%s] refused -- %s.\n",
296                                   key_name, keyname, valuename,
297                                   win_errstr(result)));
298                         status = werror_to_ntstatus(result);
299                         break;
300                 }
301         }
302
303         status = NT_STATUS_OK;
304  done:
305
306         return status;
307 }
308
309 NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx,
310                                       struct rpc_pipe_client *winreg_pipe,
311                                       const char *key_name,
312                                       unsigned char *data,
313                                       size_t length)
314 {
315         struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
316         enum ndr_err_code ndr_err;
317         struct sec_desc_buf secdesc_ctr;
318         DATA_BLOB blob;
319         WERROR result;
320
321         if (strequal(key_name, "printers")) {
322                 return NT_STATUS_OK;
323         }
324
325         blob = data_blob_const(data, length);
326
327         ZERO_STRUCT(secdesc_ctr);
328
329         ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
330                    (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
331         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
332                 DEBUG(2, ("security descriptor pull failed: %s\n",
333                           ndr_errstr(ndr_err)));
334                 return NT_STATUS_NO_MEMORY;
335         }
336
337         DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name));
338
339         result = winreg_set_printer_secdesc(mem_ctx, b,
340                                             key_name,
341                                             secdesc_ctr.sd);
342         if (!W_ERROR_IS_OK(result)) {
343                 return werror_to_ntstatus(result);
344         }
345
346         return NT_STATUS_OK;
347 }