VERSION: Bump version up to 4.0.25.
[Samba.git] / source3 / printing / nt_printing_migrate.c
blobce42a06527dbc388b9a99ba2db3e7ab5604cf54c
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
5 * Copyright (c) Andreas Schneider 2010.
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.
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.
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/>.
21 #include "includes.h"
22 #include "printing/nt_printing_migrate.h"
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"
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)
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;
43 blob = data_blob_const(data, length);
45 ZERO_STRUCT(r);
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;
55 /* Don't migrate builtin forms */
56 if (r.flag == SPOOLSS_FORM_BUILTIN) {
57 return NT_STATUS_OK;
60 DEBUG(2, ("Migrating Form: %s\n", key_name));
62 f1.form_name = key_name;
63 f1.flags = r.flag;
65 f1.size.width = r.width;
66 f1.size.height = r.length;
68 f1.area.top = r.top;
69 f1.area.right = r.right;
70 f1.area.bottom = r.bottom;
71 f1.area.left = r.left;
73 result = winreg_printer_addform1(mem_ctx,
75 &f1);
76 if (W_ERROR_EQUAL(result, WERR_FILE_EXISTS)) {
77 /* Don't migrate form if it already exists. */
78 result = WERR_OK;
80 if (!W_ERROR_IS_OK(result)) {
81 return werror_to_ntstatus(result);
84 return NT_STATUS_OK;
87 NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
88 struct rpc_pipe_client *winreg_pipe,
89 const char *key_name,
90 unsigned char *data,
91 size_t length,
92 bool do_string_conversion)
94 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
95 enum ndr_err_code ndr_err;
96 struct ntprinting_driver r;
97 struct spoolss_AddDriverInfoCtr d;
98 struct spoolss_AddDriverInfo3 d3;
99 struct spoolss_StringArray a;
100 DATA_BLOB blob;
101 WERROR result;
102 const char *driver_name;
103 uint32_t driver_version;
105 blob = data_blob_const(data, length);
107 ZERO_STRUCT(r);
109 if (do_string_conversion) {
110 r.string_flags = LIBNDR_FLAG_STR_ASCII;
113 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
114 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
115 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
116 DEBUG(2, ("Driver pull failed: %s\n",
117 ndr_errstr(ndr_err)));
118 return NT_STATUS_NO_MEMORY;
121 DEBUG(2, ("Migrating Printer Driver: %s\n", key_name));
123 ZERO_STRUCT(d3);
124 ZERO_STRUCT(a);
126 a.string = r.dependent_files;
128 d3.architecture = r.environment;
129 d3.config_file = r.configfile;
130 d3.data_file = r.datafile;
131 d3.default_datatype = r.defaultdatatype;
132 d3.dependent_files = &a;
133 d3.driver_path = r.driverpath;
134 d3.help_file = r.helpfile;
135 d3.monitor_name = r.monitorname;
136 d3.driver_name = r.name;
137 d3.version = r.version;
139 d.level = 3;
140 d.info.info3 = &d3;
142 result = winreg_add_driver(mem_ctx,
145 &driver_name,
146 &driver_version);
147 if (!W_ERROR_IS_OK(result)) {
148 return werror_to_ntstatus(result);
151 return NT_STATUS_OK;
154 NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
155 struct rpc_pipe_client *winreg_pipe,
156 const char *key_name,
157 unsigned char *data,
158 size_t length,
159 bool do_string_conversion)
161 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
162 enum ndr_err_code ndr_err;
163 struct ntprinting_printer r;
164 struct spoolss_SetPrinterInfo2 info2;
165 struct spoolss_DeviceMode dm;
166 struct spoolss_DevmodeContainer devmode_ctr;
167 DATA_BLOB blob;
168 NTSTATUS status;
169 WERROR result;
170 int j;
171 uint32_t info2_mask = (SPOOLSS_PRINTER_INFO_ALL)
172 & ~SPOOLSS_PRINTER_INFO_SECDESC;
174 if (strequal(key_name, "printers")) {
175 return NT_STATUS_OK;
178 blob = data_blob_const(data, length);
180 ZERO_STRUCT(r);
182 if (do_string_conversion) {
183 r.info.string_flags = LIBNDR_FLAG_STR_ASCII;
186 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
187 (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
188 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
189 DEBUG(2, ("printer pull failed: %s\n",
190 ndr_errstr(ndr_err)));
191 return NT_STATUS_NO_MEMORY;
194 DEBUG(2, ("Migrating Printer: %s\n", key_name));
196 ZERO_STRUCT(devmode_ctr);
198 /* Create printer info level 2 */
199 ZERO_STRUCT(info2);
201 info2.attributes = r.info.attributes;
202 info2.averageppm = r.info.averageppm;
203 info2.cjobs = r.info.cjobs;
204 info2.comment = r.info.comment;
205 info2.datatype = r.info.datatype;
206 info2.defaultpriority = r.info.default_priority;
207 info2.drivername = r.info.drivername;
208 info2.location = r.info.location;
209 info2.parameters = r.info.parameters;
210 info2.portname = r.info.portname;
211 info2.printername = r.info.printername;
212 info2.printprocessor = r.info.printprocessor;
213 info2.priority = r.info.priority;
214 info2.sepfile = r.info.sepfile;
215 info2.sharename = r.info.sharename;
216 info2.starttime = r.info.starttime;
217 info2.status = r.info.status;
218 info2.untiltime = r.info.untiltime;
220 /* Create Device Mode */
221 if (r.devmode == NULL) {
222 info2_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
223 } else {
224 ZERO_STRUCT(dm);
226 dm.bitsperpel = r.devmode->bitsperpel;
227 dm.collate = r.devmode->collate;
228 dm.color = r.devmode->color;
229 dm.copies = r.devmode->copies;
230 dm.defaultsource = r.devmode->defaultsource;
231 dm.devicename = r.devmode->devicename;
232 dm.displayflags = r.devmode->displayflags;
233 dm.displayfrequency = r.devmode->displayfrequency;
234 dm.dithertype = r.devmode->dithertype;
235 dm.driverversion = r.devmode->driverversion;
236 dm.duplex = r.devmode->duplex;
237 dm.fields = r.devmode->fields;
238 dm.formname = r.devmode->formname;
239 dm.icmintent = r.devmode->icmintent;
240 dm.icmmethod = r.devmode->icmmethod;
241 dm.logpixels = r.devmode->logpixels;
242 dm.mediatype = r.devmode->mediatype;
243 dm.orientation = r.devmode->orientation;
244 dm.panningheight = r.devmode->pelsheight;
245 dm.panningwidth = r.devmode->panningwidth;
246 dm.paperlength = r.devmode->paperlength;
247 dm.papersize = r.devmode->papersize;
248 dm.paperwidth = r.devmode->paperwidth;
249 dm.pelsheight = r.devmode->pelsheight;
250 dm.pelswidth = r.devmode->pelswidth;
251 dm.printquality = r.devmode->printquality;
252 dm.size = r.devmode->size;
253 dm.scale = r.devmode->scale;
254 dm.specversion = r.devmode->specversion;
255 dm.ttoption = r.devmode->ttoption;
256 dm.yresolution = r.devmode->yresolution;
258 if (r.devmode->nt_dev_private != NULL) {
259 dm.driverextra_data.data = r.devmode->nt_dev_private->data;
260 dm.driverextra_data.length = r.devmode->nt_dev_private->length;
261 dm.__driverextra_length = r.devmode->nt_dev_private->length;
264 devmode_ctr.devmode = &dm;
266 info2.devmode_ptr = 1;
269 result = winreg_update_printer(mem_ctx, b,
270 key_name,
271 info2_mask,
272 &info2,
273 &dm,
274 NULL);
275 if (!W_ERROR_IS_OK(result)) {
276 DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n",
277 key_name, win_errstr(result)));
278 status = werror_to_ntstatus(result);
279 goto done;
282 /* migrate printerdata */
283 for (j = 0; j < r.count; j++) {
284 char *valuename;
285 const char *keyname;
287 if (r.printer_data[j].type == REG_NONE) {
288 continue;
291 keyname = r.printer_data[j].name;
292 valuename = strchr(keyname, '\\');
293 if (valuename == NULL) {
294 continue;
295 } else {
296 valuename[0] = '\0';
297 valuename++;
300 result = winreg_set_printer_dataex(mem_ctx, b,
301 key_name,
302 keyname,
303 valuename,
304 r.printer_data[j].type,
305 r.printer_data[j].data.data,
306 r.printer_data[j].data.length);
307 if (!W_ERROR_IS_OK(result)) {
308 DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], "
309 "valuename [%s] refused -- %s.\n",
310 key_name, keyname, valuename,
311 win_errstr(result)));
312 status = werror_to_ntstatus(result);
313 break;
317 status = NT_STATUS_OK;
318 done:
320 return status;
323 NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx,
324 struct rpc_pipe_client *winreg_pipe,
325 const char *key_name,
326 unsigned char *data,
327 size_t length)
329 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
330 enum ndr_err_code ndr_err;
331 struct sec_desc_buf secdesc_ctr;
332 DATA_BLOB blob;
333 WERROR result;
335 if (strequal(key_name, "printers")) {
336 return NT_STATUS_OK;
339 blob = data_blob_const(data, length);
341 ZERO_STRUCT(secdesc_ctr);
343 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
344 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
345 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
346 DEBUG(2, ("security descriptor pull failed: %s\n",
347 ndr_errstr(ndr_err)));
348 return NT_STATUS_NO_MEMORY;
351 DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name));
353 result = winreg_set_printer_secdesc(mem_ctx, b,
354 key_name,
355 secdesc_ctr.sd);
356 if (!W_ERROR_IS_OK(result)) {
357 return werror_to_ntstatus(result);
360 return NT_STATUS_OK;