s3:registry avoid leaking an old regsubkey_ctr on regsubkey_ctr_init
[Samba/gebeck_regimport.git] / source3 / printing / nt_printing_migrate.c
blob44800014e8487c6c60ca4b82a5efaac3e18341b8
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_IS_OK(result)) {
77 return werror_to_ntstatus(result);
80 return NT_STATUS_OK;
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)
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;
100 blob = data_blob_const(data, length);
102 ZERO_STRUCT(r);
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;
112 DEBUG(2, ("Migrating Printer Driver: %s\n", key_name));
114 ZERO_STRUCT(d3);
115 ZERO_STRUCT(a);
117 a.string = r.dependent_files;
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;
130 d.level = 3;
131 d.info.info3 = &d3;
133 result = winreg_add_driver(mem_ctx,
136 &driver_name,
137 &driver_version);
138 if (!W_ERROR_IS_OK(result)) {
139 return werror_to_ntstatus(result);
142 return NT_STATUS_OK;
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)
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;
164 if (strequal(key_name, "printers")) {
165 return NT_STATUS_OK;
168 blob = data_blob_const(data, length);
170 ZERO_STRUCT(r);
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;
180 DEBUG(2, ("Migrating Printer: %s\n", key_name));
182 ZERO_STRUCT(devmode_ctr);
184 /* Create printer info level 2 */
185 ZERO_STRUCT(info2);
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;
206 /* Create Device Mode */
207 if (r.devmode == NULL) {
208 info2_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
209 } else {
210 ZERO_STRUCT(dm);
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;
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;
250 devmode_ctr.devmode = &dm;
252 info2.devmode_ptr = 1;
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;
268 /* migrate printerdata */
269 for (j = 0; j < r.count; j++) {
270 char *valuename;
271 const char *keyname;
273 if (r.printer_data[j].type == REG_NONE) {
274 continue;
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++;
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;
303 status = NT_STATUS_OK;
304 done:
306 return status;
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)
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;
321 if (strequal(key_name, "printers")) {
322 return NT_STATUS_OK;
325 blob = data_blob_const(data, length);
327 ZERO_STRUCT(secdesc_ctr);
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;
337 DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name));
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);
346 return NT_STATUS_OK;