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