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/>.
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
)
35 basefile
= strrchr(file
, '\\');
36 if (basefile
== NULL
) {
45 NTSTATUS
printing_tdb_migrate_form(TALLOC_CTX
*mem_ctx
,
46 struct rpc_pipe_client
*winreg_pipe
,
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
;
58 blob
= data_blob_const(data
, length
);
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
) {
75 DEBUG(2, ("Migrating Form: %s\n", key_name
));
77 f1
.form_name
= key_name
;
80 f1
.size
.width
= r
.width
;
81 f1
.size
.height
= r
.length
;
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
,
91 if (W_ERROR_EQUAL(result
, WERR_FILE_EXISTS
)) {
92 /* Don't migrate form if it already exists. */
95 if (!W_ERROR_IS_OK(result
)) {
96 return werror_to_ntstatus(result
);
102 NTSTATUS
printing_tdb_migrate_driver(TALLOC_CTX
*mem_ctx
,
103 struct rpc_pipe_client
*winreg_pipe
,
104 const char *key_name
,
107 bool do_string_conversion
)
109 struct dcerpc_binding_handle
*b
= winreg_pipe
->binding_handle
;
110 enum ndr_err_code ndr_err
;
111 struct ntprinting_driver r
;
112 struct spoolss_AddDriverInfoCtr d
;
113 struct spoolss_AddDriverInfo3 d3
;
114 struct spoolss_StringArray a
;
117 const char *driver_name
;
118 uint32_t driver_version
;
121 blob
= data_blob_const(data
, length
);
125 if (do_string_conversion
) {
126 r
.string_flags
= LIBNDR_FLAG_STR_ASCII
;
129 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &r
,
130 (ndr_pull_flags_fn_t
)ndr_pull_ntprinting_driver
);
131 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
132 DEBUG(2, ("Driver pull failed: %s\n",
133 ndr_errstr(ndr_err
)));
134 return NT_STATUS_NO_MEMORY
;
137 DEBUG(2, ("Migrating Printer Driver: %s\n", key_name
));
142 /* remove paths from file names */
143 if (r
.dependent_files
!= NULL
) {
144 for (i
= 0 ; r
.dependent_files
[i
] != NULL
; i
++) {
145 r
.dependent_files
[i
] = driver_file_basename(r
.dependent_files
[i
]);
148 a
.string
= r
.dependent_files
;
150 r
.driverpath
= driver_file_basename(r
.driverpath
);
151 r
.configfile
= driver_file_basename(r
.configfile
);
152 r
.datafile
= driver_file_basename(r
.datafile
);
153 r
.helpfile
= driver_file_basename(r
.helpfile
);
155 d3
.architecture
= r
.environment
;
156 d3
.config_file
= r
.configfile
;
157 d3
.data_file
= r
.datafile
;
158 d3
.default_datatype
= r
.defaultdatatype
;
159 d3
.dependent_files
= &a
;
160 d3
.driver_path
= r
.driverpath
;
161 d3
.help_file
= r
.helpfile
;
162 d3
.monitor_name
= r
.monitorname
;
163 d3
.driver_name
= r
.name
;
164 d3
.version
= r
.version
;
169 result
= winreg_add_driver(mem_ctx
,
174 if (!W_ERROR_IS_OK(result
)) {
175 return werror_to_ntstatus(result
);
181 NTSTATUS
printing_tdb_migrate_printer(TALLOC_CTX
*mem_ctx
,
182 struct rpc_pipe_client
*winreg_pipe
,
183 const char *key_name
,
186 bool do_string_conversion
)
188 struct dcerpc_binding_handle
*b
= winreg_pipe
->binding_handle
;
189 enum ndr_err_code ndr_err
;
190 struct ntprinting_printer r
;
191 struct spoolss_SetPrinterInfo2 info2
;
192 struct spoolss_DeviceMode dm
;
193 struct spoolss_DevmodeContainer devmode_ctr
;
198 uint32_t info2_mask
= (SPOOLSS_PRINTER_INFO_ALL
)
199 & ~SPOOLSS_PRINTER_INFO_SECDESC
;
201 if (strequal(key_name
, "printers")) {
205 blob
= data_blob_const(data
, length
);
209 if (do_string_conversion
) {
210 r
.info
.string_flags
= LIBNDR_FLAG_STR_ASCII
;
213 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &r
,
214 (ndr_pull_flags_fn_t
) ndr_pull_ntprinting_printer
);
215 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
216 DEBUG(2, ("printer pull failed: %s\n",
217 ndr_errstr(ndr_err
)));
218 return NT_STATUS_NO_MEMORY
;
221 DEBUG(2, ("Migrating Printer: %s\n", key_name
));
223 ZERO_STRUCT(devmode_ctr
);
225 /* Create printer info level 2 */
228 info2
.attributes
= r
.info
.attributes
;
229 info2
.averageppm
= r
.info
.averageppm
;
230 info2
.cjobs
= r
.info
.cjobs
;
231 info2
.comment
= r
.info
.comment
;
232 info2
.datatype
= r
.info
.datatype
;
233 info2
.defaultpriority
= r
.info
.default_priority
;
234 info2
.drivername
= r
.info
.drivername
;
235 info2
.location
= r
.info
.location
;
236 info2
.parameters
= r
.info
.parameters
;
237 info2
.portname
= r
.info
.portname
;
238 info2
.printername
= r
.info
.printername
;
239 info2
.printprocessor
= r
.info
.printprocessor
;
240 info2
.priority
= r
.info
.priority
;
241 info2
.sepfile
= r
.info
.sepfile
;
242 info2
.sharename
= r
.info
.sharename
;
243 info2
.starttime
= r
.info
.starttime
;
244 info2
.status
= r
.info
.status
;
245 info2
.untiltime
= r
.info
.untiltime
;
247 /* Create Device Mode */
248 if (r
.devmode
== NULL
) {
249 info2_mask
&= ~SPOOLSS_PRINTER_INFO_DEVMODE
;
253 dm
.bitsperpel
= r
.devmode
->bitsperpel
;
254 dm
.collate
= r
.devmode
->collate
;
255 dm
.color
= r
.devmode
->color
;
256 dm
.copies
= r
.devmode
->copies
;
257 dm
.defaultsource
= r
.devmode
->defaultsource
;
258 dm
.devicename
= r
.devmode
->devicename
;
259 dm
.displayflags
= r
.devmode
->displayflags
;
260 dm
.displayfrequency
= r
.devmode
->displayfrequency
;
261 dm
.dithertype
= r
.devmode
->dithertype
;
262 dm
.driverversion
= r
.devmode
->driverversion
;
263 dm
.duplex
= r
.devmode
->duplex
;
264 dm
.fields
= r
.devmode
->fields
;
265 dm
.formname
= r
.devmode
->formname
;
266 dm
.icmintent
= r
.devmode
->icmintent
;
267 dm
.icmmethod
= r
.devmode
->icmmethod
;
268 dm
.logpixels
= r
.devmode
->logpixels
;
269 dm
.mediatype
= r
.devmode
->mediatype
;
270 dm
.orientation
= r
.devmode
->orientation
;
271 dm
.panningheight
= r
.devmode
->pelsheight
;
272 dm
.panningwidth
= r
.devmode
->panningwidth
;
273 dm
.paperlength
= r
.devmode
->paperlength
;
274 dm
.papersize
= r
.devmode
->papersize
;
275 dm
.paperwidth
= r
.devmode
->paperwidth
;
276 dm
.pelsheight
= r
.devmode
->pelsheight
;
277 dm
.pelswidth
= r
.devmode
->pelswidth
;
278 dm
.printquality
= r
.devmode
->printquality
;
279 dm
.size
= r
.devmode
->size
;
280 dm
.scale
= r
.devmode
->scale
;
281 dm
.specversion
= r
.devmode
->specversion
;
282 dm
.ttoption
= r
.devmode
->ttoption
;
283 dm
.yresolution
= r
.devmode
->yresolution
;
285 if (r
.devmode
->nt_dev_private
!= NULL
) {
286 dm
.driverextra_data
.data
= r
.devmode
->nt_dev_private
->data
;
287 dm
.driverextra_data
.length
= r
.devmode
->nt_dev_private
->length
;
288 dm
.__driverextra_length
= r
.devmode
->nt_dev_private
->length
;
291 devmode_ctr
.devmode
= &dm
;
294 result
= winreg_update_printer(mem_ctx
, b
,
300 if (!W_ERROR_IS_OK(result
)) {
301 DEBUG(2, ("SetPrinter(%s) level 2 refused -- %s.\n",
302 key_name
, win_errstr(result
)));
303 status
= werror_to_ntstatus(result
);
307 /* migrate printerdata */
308 for (j
= 0; j
< r
.count
; j
++) {
312 if (r
.printer_data
[j
].type
== REG_NONE
) {
316 keyname
= r
.printer_data
[j
].name
;
317 valuename
= strchr(keyname
, '\\');
318 if (valuename
== NULL
) {
325 result
= winreg_set_printer_dataex(mem_ctx
, b
,
329 r
.printer_data
[j
].type
,
330 r
.printer_data
[j
].data
.data
,
331 r
.printer_data
[j
].data
.length
);
332 if (!W_ERROR_IS_OK(result
)) {
333 DEBUG(2, ("SetPrinterDataEx: printer [%s], keyname [%s], "
334 "valuename [%s] refused -- %s.\n",
335 key_name
, keyname
, valuename
,
336 win_errstr(result
)));
337 status
= werror_to_ntstatus(result
);
342 status
= NT_STATUS_OK
;
348 NTSTATUS
printing_tdb_migrate_secdesc(TALLOC_CTX
*mem_ctx
,
349 struct rpc_pipe_client
*winreg_pipe
,
350 const char *key_name
,
354 struct dcerpc_binding_handle
*b
= winreg_pipe
->binding_handle
;
355 enum ndr_err_code ndr_err
;
356 struct sec_desc_buf secdesc_ctr
;
360 if (strequal(key_name
, "printers")) {
364 blob
= data_blob_const(data
, length
);
366 ZERO_STRUCT(secdesc_ctr
);
368 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &secdesc_ctr
,
369 (ndr_pull_flags_fn_t
)ndr_pull_sec_desc_buf
);
370 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
371 DEBUG(2, ("security descriptor pull failed: %s\n",
372 ndr_errstr(ndr_err
)));
373 return NT_STATUS_NO_MEMORY
;
376 DEBUG(2, ("Migrating Security Descriptor: %s\n", key_name
));
378 result
= winreg_set_printer_secdesc(mem_ctx
, b
,
381 if (!W_ERROR_IS_OK(result
)) {
382 return werror_to_ntstatus(result
);