s3-docs: overrided -> overridden
[Samba.git] / source3 / printing / nt_printing_migrate.c
blob6eb2f449986bd1cfe66ecad31bc2282adb38f433
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
5 * Copyright (c) Andreas Schneider 2010.
6 * Copyright (C) Bjoern Baumbach <bb@sernet.de> 2011
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "printing/nt_printing_migrate.h"
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_client/cli_winreg_spoolss.h"
31 static const char *driver_file_basename(const char *file)
33 const char *basefile;
35 basefile = strrchr(file, '\\');
36 if (basefile == NULL) {
37 basefile = file;
38 } else {
39 basefile++;
42 return basefile;
45 NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx,
46 struct rpc_pipe_client *winreg_pipe,
47 const char *key_name,
48 unsigned char *data,
49 size_t length)
51 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
52 enum ndr_err_code ndr_err;
53 struct ntprinting_form r;
54 struct spoolss_AddFormInfo1 f1;
55 DATA_BLOB blob;
56 WERROR result;
58 blob = data_blob_const(data, length);
60 ZERO_STRUCT(r);
62 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
63 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_form);
64 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
65 DEBUG(2, ("Form pull failed: %s\n",
66 ndr_errstr(ndr_err)));
67 return NT_STATUS_NO_MEMORY;
70 /* Don't migrate builtin forms */
71 if (r.flag == SPOOLSS_FORM_BUILTIN) {
72 return NT_STATUS_OK;
75 DEBUG(2, ("Migrating Form: %s\n", key_name));
77 f1.form_name = key_name;
78 f1.flags = r.flag;
80 f1.size.width = r.width;
81 f1.size.height = r.length;
83 f1.area.top = r.top;
84 f1.area.right = r.right;
85 f1.area.bottom = r.bottom;
86 f1.area.left = r.left;
88 result = winreg_printer_addform1(mem_ctx,
90 &f1);
91 if (W_ERROR_EQUAL(result, WERR_FILE_EXISTS)) {
92 /* Don't migrate form if it already exists. */
93 result = WERR_OK;
95 if (!W_ERROR_IS_OK(result)) {
96 return werror_to_ntstatus(result);
99 return NT_STATUS_OK;
102 NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
103 struct rpc_pipe_client *winreg_pipe,
104 const char *key_name,
105 unsigned char *data,
106 size_t length)
108 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
109 enum ndr_err_code ndr_err;
110 struct ntprinting_driver r;
111 struct spoolss_AddDriverInfoCtr d;
112 struct spoolss_AddDriverInfo3 d3;
113 struct spoolss_StringArray a;
114 DATA_BLOB blob;
115 WERROR result;
116 const char *driver_name;
117 uint32_t driver_version;
118 int i;
120 blob = data_blob_const(data, length);
122 ZERO_STRUCT(r);
124 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
125 (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
126 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
127 DEBUG(2, ("Driver pull failed: %s\n",
128 ndr_errstr(ndr_err)));
129 return NT_STATUS_NO_MEMORY;
132 DEBUG(2, ("Migrating Printer Driver: %s\n", key_name));
134 ZERO_STRUCT(d3);
135 ZERO_STRUCT(a);
137 /* remove paths from file names */
138 if (r.dependent_files != NULL) {
139 for (i = 0 ; r.dependent_files[i] != NULL; i++) {
140 r.dependent_files[i] = driver_file_basename(r.dependent_files[i]);
143 a.string = r.dependent_files;
145 r.driverpath = driver_file_basename(r.driverpath);
146 r.configfile = driver_file_basename(r.configfile);
147 r.datafile = driver_file_basename(r.datafile);
148 r.helpfile = driver_file_basename(r.helpfile);
150 d3.architecture = r.environment;
151 d3.config_file = r.configfile;
152 d3.data_file = r.datafile;
153 d3.default_datatype = r.defaultdatatype;
154 d3.dependent_files = &a;
155 d3.driver_path = r.driverpath;
156 d3.help_file = r.helpfile;
157 d3.monitor_name = r.monitorname;
158 d3.driver_name = r.name;
159 d3.version = r.version;
161 d.level = 3;
162 d.info.info3 = &d3;
164 result = winreg_add_driver(mem_ctx,
167 &driver_name,
168 &driver_version);
169 if (!W_ERROR_IS_OK(result)) {
170 return werror_to_ntstatus(result);
173 return NT_STATUS_OK;
176 NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
177 struct rpc_pipe_client *winreg_pipe,
178 const char *key_name,
179 unsigned char *data,
180 size_t length)
182 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
183 enum ndr_err_code ndr_err;
184 struct ntprinting_printer r;
185 struct spoolss_SetPrinterInfo2 info2;
186 struct spoolss_DeviceMode dm;
187 struct spoolss_DevmodeContainer devmode_ctr;
188 DATA_BLOB blob;
189 NTSTATUS status;
190 WERROR result;
191 int j;
192 uint32_t info2_mask = (SPOOLSS_PRINTER_INFO_ALL)
193 & ~SPOOLSS_PRINTER_INFO_SECDESC;
195 if (strequal(key_name, "printers")) {
196 return NT_STATUS_OK;
199 blob = data_blob_const(data, length);
201 ZERO_STRUCT(r);
203 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
204 (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
205 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
206 DEBUG(2, ("printer pull failed: %s\n",
207 ndr_errstr(ndr_err)));
208 return NT_STATUS_NO_MEMORY;
211 DEBUG(2, ("Migrating Printer: %s\n", key_name));
213 ZERO_STRUCT(devmode_ctr);
215 /* Create printer info level 2 */
216 ZERO_STRUCT(info2);
218 info2.attributes = r.info.attributes;
219 info2.averageppm = r.info.averageppm;
220 info2.cjobs = r.info.cjobs;
221 info2.comment = r.info.comment;
222 info2.datatype = r.info.datatype;
223 info2.defaultpriority = r.info.default_priority;
224 info2.drivername = r.info.drivername;
225 info2.location = r.info.location;
226 info2.parameters = r.info.parameters;
227 info2.portname = r.info.portname;
228 info2.printername = r.info.printername;
229 info2.printprocessor = r.info.printprocessor;
230 info2.priority = r.info.priority;
231 info2.sepfile = r.info.sepfile;
232 info2.sharename = r.info.sharename;
233 info2.starttime = r.info.starttime;
234 info2.status = r.info.status;
235 info2.untiltime = r.info.untiltime;
237 /* Create Device Mode */
238 if (r.devmode == NULL) {
239 info2_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
240 } else {
241 ZERO_STRUCT(dm);
243 dm.bitsperpel = r.devmode->bitsperpel;
244 dm.collate = r.devmode->collate;
245 dm.color = r.devmode->color;
246 dm.copies = r.devmode->copies;
247 dm.defaultsource = r.devmode->defaultsource;
248 dm.devicename = r.devmode->devicename;
249 dm.displayflags = r.devmode->displayflags;
250 dm.displayfrequency = r.devmode->displayfrequency;
251 dm.dithertype = r.devmode->dithertype;
252 dm.driverversion = r.devmode->driverversion;
253 dm.duplex = r.devmode->duplex;
254 dm.fields = r.devmode->fields;
255 dm.formname = r.devmode->formname;
256 dm.icmintent = r.devmode->icmintent;
257 dm.icmmethod = r.devmode->icmmethod;
258 dm.logpixels = r.devmode->logpixels;
259 dm.mediatype = r.devmode->mediatype;
260 dm.orientation = r.devmode->orientation;
261 dm.panningheight = r.devmode->pelsheight;
262 dm.panningwidth = r.devmode->panningwidth;
263 dm.paperlength = r.devmode->paperlength;
264 dm.papersize = r.devmode->papersize;
265 dm.paperwidth = r.devmode->paperwidth;
266 dm.pelsheight = r.devmode->pelsheight;
267 dm.pelswidth = r.devmode->pelswidth;
268 dm.printquality = r.devmode->printquality;
269 dm.size = r.devmode->size;
270 dm.scale = r.devmode->scale;
271 dm.specversion = r.devmode->specversion;
272 dm.ttoption = r.devmode->ttoption;
273 dm.yresolution = r.devmode->yresolution;
275 if (r.devmode->nt_dev_private != NULL) {
276 dm.driverextra_data.data = r.devmode->nt_dev_private->data;
277 dm.driverextra_data.length = r.devmode->nt_dev_private->length;
278 dm.__driverextra_length = r.devmode->nt_dev_private->length;
281 devmode_ctr.devmode = &dm;
283 info2.devmode_ptr = 1;
286 result = winreg_update_printer(mem_ctx, b,
287 key_name,
288 info2_mask,
289 &info2,
290 &dm,
291 NULL);
292 if (!W_ERROR_IS_OK(result)) {
293 DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n",
294 key_name, win_errstr(result)));
295 status = werror_to_ntstatus(result);
296 goto done;
299 /* migrate printerdata */
300 for (j = 0; j < r.count; j++) {
301 char *valuename;
302 char *keyname;
304 if (r.printer_data[j].type == REG_NONE) {
305 continue;
308 keyname = CONST_DISCARD(char *, r.printer_data[j].name);
309 valuename = strchr(keyname, '\\');
310 if (valuename == NULL) {
311 continue;
312 } else {
313 valuename[0] = '\0';
314 valuename++;
317 result = winreg_set_printer_dataex(mem_ctx, b,
318 key_name,
319 keyname,
320 valuename,
321 r.printer_data[j].type,
322 r.printer_data[j].data.data,
323 r.printer_data[j].data.length);
324 if (!W_ERROR_IS_OK(result)) {
325 DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], "
326 "valuename [%s] refused -- %s.\n",
327 key_name, keyname, valuename,
328 win_errstr(result)));
329 status = werror_to_ntstatus(result);
330 break;
334 status = NT_STATUS_OK;
335 done:
337 return status;
340 NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx,
341 struct rpc_pipe_client *winreg_pipe,
342 const char *key_name,
343 unsigned char *data,
344 size_t length)
346 struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
347 enum ndr_err_code ndr_err;
348 struct sec_desc_buf secdesc_ctr;
349 DATA_BLOB blob;
350 WERROR result;
352 if (strequal(key_name, "printers")) {
353 return NT_STATUS_OK;
356 blob = data_blob_const(data, length);
358 ZERO_STRUCT(secdesc_ctr);
360 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &secdesc_ctr,
361 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
362 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
363 DEBUG(2, ("security descriptor pull failed: %s\n",
364 ndr_errstr(ndr_err)));
365 return NT_STATUS_NO_MEMORY;
368 DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name));
370 result = winreg_set_printer_secdesc(mem_ctx, b,
371 key_name,
372 secdesc_ctr.sd);
373 if (!W_ERROR_IS_OK(result)) {
374 return werror_to_ntstatus(result);
377 return NT_STATUS_OK;