2010-06-15 15:37:44 +04:00
/*
* Unix SMB / CIFS implementation .
* RPC Pipe client / server routines
*
* Copyright ( c ) Andreas Schneider 2010.
2011-11-18 21:54:56 +04:00
* Copyright ( C ) Bjoern Baumbach < bb @ sernet . de > 2011
2010-06-15 15:37:44 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "printing/nt_printing_migrate.h"
2011-04-13 16:32:16 +04:00
# include "rpc_client/rpc_client.h"
2010-06-15 15:37:44 +04:00
# include "librpc/gen_ndr/ndr_ntprinting.h"
2011-01-15 14:06:09 +03:00
# include "librpc/gen_ndr/ndr_spoolss_c.h"
2010-06-15 15:37:44 +04:00
# include "librpc/gen_ndr/ndr_security.h"
2011-07-04 21:47:07 +04:00
# include "rpc_client/cli_winreg_spoolss.h"
2011-07-01 16:57:32 +04:00
2011-11-18 21:54:56 +04:00
static const char * driver_file_basename ( const char * file )
{
const char * basefile ;
basefile = strrchr ( file , ' \\ ' ) ;
if ( basefile = = NULL ) {
basefile = file ;
} else {
basefile + + ;
}
return basefile ;
}
2011-07-01 16:57:32 +04:00
NTSTATUS printing_tdb_migrate_form ( TALLOC_CTX * mem_ctx ,
2011-07-01 17:39:11 +04:00
struct rpc_pipe_client * winreg_pipe ,
2011-07-01 16:57:32 +04:00
const char * key_name ,
unsigned char * data ,
size_t length )
2010-06-15 15:37:44 +04:00
{
2011-07-04 21:47:07 +04:00
struct dcerpc_binding_handle * b = winreg_pipe - > binding_handle ;
2010-06-15 15:37:44 +04:00
enum ndr_err_code ndr_err ;
struct ntprinting_form r ;
struct spoolss_AddFormInfo1 f1 ;
DATA_BLOB blob ;
WERROR result ;
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_ntprinting_form ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 2 , ( " Form pull failed: %s \n " ,
ndr_errstr ( ndr_err ) ) ) ;
return NT_STATUS_NO_MEMORY ;
}
/* Don't migrate builtin forms */
if ( r . flag = = SPOOLSS_FORM_BUILTIN ) {
return NT_STATUS_OK ;
}
DEBUG ( 2 , ( " Migrating Form: %s \n " , key_name ) ) ;
f1 . form_name = key_name ;
f1 . flags = r . flag ;
f1 . size . width = r . width ;
f1 . size . height = r . length ;
f1 . area . top = r . top ;
f1 . area . right = r . right ;
f1 . area . bottom = r . bottom ;
f1 . area . left = r . left ;
2011-07-04 21:47:07 +04:00
result = winreg_printer_addform1 ( mem_ctx ,
b ,
& f1 ) ;
2011-09-06 16:09:47 +04:00
if ( W_ERROR_EQUAL ( result , WERR_FILE_EXISTS ) ) {
/* Don't migrate form if it already exists. */
result = WERR_OK ;
}
2011-07-04 21:47:07 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
return werror_to_ntstatus ( result ) ;
2010-06-15 15:37:44 +04:00
}
2011-07-04 21:47:07 +04:00
return NT_STATUS_OK ;
2010-06-15 15:37:44 +04:00
}
2011-07-01 16:57:32 +04:00
NTSTATUS printing_tdb_migrate_driver ( TALLOC_CTX * mem_ctx ,
2011-07-01 17:39:11 +04:00
struct rpc_pipe_client * winreg_pipe ,
2011-07-01 16:57:32 +04:00
const char * key_name ,
unsigned char * data ,
2013-03-12 14:39:08 +04:00
size_t length ,
bool do_string_conversion )
2010-06-15 15:37:44 +04:00
{
2011-07-04 21:47:07 +04:00
struct dcerpc_binding_handle * b = winreg_pipe - > binding_handle ;
2010-06-15 15:37:44 +04:00
enum ndr_err_code ndr_err ;
struct ntprinting_driver r ;
struct spoolss_AddDriverInfoCtr d ;
struct spoolss_AddDriverInfo3 d3 ;
struct spoolss_StringArray a ;
DATA_BLOB blob ;
WERROR result ;
2011-07-04 21:47:07 +04:00
const char * driver_name ;
uint32_t driver_version ;
2011-11-18 21:54:56 +04:00
int i ;
2010-06-15 15:37:44 +04:00
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
2013-03-12 14:39:08 +04:00
if ( do_string_conversion ) {
r . string_flags = LIBNDR_FLAG_STR_ASCII ;
}
2010-06-15 15:37:44 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_ntprinting_driver ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 2 , ( " Driver pull failed: %s \n " ,
ndr_errstr ( ndr_err ) ) ) ;
return NT_STATUS_NO_MEMORY ;
}
DEBUG ( 2 , ( " Migrating Printer Driver: %s \n " , key_name ) ) ;
ZERO_STRUCT ( d3 ) ;
ZERO_STRUCT ( a ) ;
2011-11-18 21:54:56 +04:00
/* remove paths from file names */
if ( r . dependent_files ! = NULL ) {
for ( i = 0 ; r . dependent_files [ i ] ! = NULL ; i + + ) {
r . dependent_files [ i ] = driver_file_basename ( r . dependent_files [ i ] ) ;
}
}
2010-06-15 15:37:44 +04:00
a . string = r . dependent_files ;
2011-11-18 21:54:56 +04:00
r . driverpath = driver_file_basename ( r . driverpath ) ;
r . configfile = driver_file_basename ( r . configfile ) ;
r . datafile = driver_file_basename ( r . datafile ) ;
r . helpfile = driver_file_basename ( r . helpfile ) ;
2010-06-15 15:37:44 +04:00
d3 . architecture = r . environment ;
d3 . config_file = r . configfile ;
d3 . data_file = r . datafile ;
d3 . default_datatype = r . defaultdatatype ;
d3 . dependent_files = & a ;
d3 . driver_path = r . driverpath ;
d3 . help_file = r . helpfile ;
d3 . monitor_name = r . monitorname ;
d3 . driver_name = r . name ;
d3 . version = r . version ;
d . level = 3 ;
d . info . info3 = & d3 ;
2011-07-04 21:47:07 +04:00
result = winreg_add_driver ( mem_ctx ,
b ,
& d ,
& driver_name ,
& driver_version ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
return werror_to_ntstatus ( result ) ;
2010-06-15 15:37:44 +04:00
}
2011-07-04 21:47:07 +04:00
return NT_STATUS_OK ;
2010-06-15 15:37:44 +04:00
}
2011-07-01 16:57:32 +04:00
NTSTATUS printing_tdb_migrate_printer ( TALLOC_CTX * mem_ctx ,
2011-07-01 17:39:11 +04:00
struct rpc_pipe_client * winreg_pipe ,
2011-07-01 16:57:32 +04:00
const char * key_name ,
unsigned char * data ,
2013-03-12 14:39:08 +04:00
size_t length ,
bool do_string_conversion )
2010-06-15 15:37:44 +04:00
{
2011-07-04 21:47:07 +04:00
struct dcerpc_binding_handle * b = winreg_pipe - > binding_handle ;
2010-06-15 15:37:44 +04:00
enum ndr_err_code ndr_err ;
struct ntprinting_printer r ;
struct spoolss_SetPrinterInfo2 info2 ;
struct spoolss_DeviceMode dm ;
struct spoolss_DevmodeContainer devmode_ctr ;
DATA_BLOB blob ;
NTSTATUS status ;
WERROR result ;
int j ;
2011-07-05 13:34:47 +04:00
uint32_t info2_mask = ( SPOOLSS_PRINTER_INFO_ALL )
& ~ SPOOLSS_PRINTER_INFO_SECDESC ;
2010-06-15 15:37:44 +04:00
if ( strequal ( key_name , " printers " ) ) {
return NT_STATUS_OK ;
}
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
2013-03-12 14:39:08 +04:00
if ( do_string_conversion ) {
r . info . string_flags = LIBNDR_FLAG_STR_ASCII ;
}
2010-06-15 15:37:44 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_ntprinting_printer ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 2 , ( " printer pull failed: %s \n " ,
ndr_errstr ( ndr_err ) ) ) ;
return NT_STATUS_NO_MEMORY ;
}
DEBUG ( 2 , ( " Migrating Printer: %s \n " , key_name ) ) ;
ZERO_STRUCT ( devmode_ctr ) ;
/* Create printer info level 2 */
ZERO_STRUCT ( info2 ) ;
info2 . attributes = r . info . attributes ;
info2 . averageppm = r . info . averageppm ;
info2 . cjobs = r . info . cjobs ;
info2 . comment = r . info . comment ;
info2 . datatype = r . info . datatype ;
info2 . defaultpriority = r . info . default_priority ;
info2 . drivername = r . info . drivername ;
info2 . location = r . info . location ;
info2 . parameters = r . info . parameters ;
info2 . portname = r . info . portname ;
info2 . printername = r . info . printername ;
info2 . printprocessor = r . info . printprocessor ;
info2 . priority = r . info . priority ;
info2 . sepfile = r . info . sepfile ;
info2 . sharename = r . info . sharename ;
info2 . starttime = r . info . starttime ;
info2 . status = r . info . status ;
info2 . untiltime = r . info . untiltime ;
/* Create Device Mode */
2011-07-05 13:34:47 +04:00
if ( r . devmode = = NULL ) {
info2_mask & = ~ SPOOLSS_PRINTER_INFO_DEVMODE ;
} else {
2010-06-15 15:37:44 +04:00
ZERO_STRUCT ( dm ) ;
dm . bitsperpel = r . devmode - > bitsperpel ;
dm . collate = r . devmode - > collate ;
dm . color = r . devmode - > color ;
dm . copies = r . devmode - > copies ;
dm . defaultsource = r . devmode - > defaultsource ;
dm . devicename = r . devmode - > devicename ;
dm . displayflags = r . devmode - > displayflags ;
dm . displayfrequency = r . devmode - > displayfrequency ;
dm . dithertype = r . devmode - > dithertype ;
dm . driverversion = r . devmode - > driverversion ;
dm . duplex = r . devmode - > duplex ;
dm . fields = r . devmode - > fields ;
dm . formname = r . devmode - > formname ;
dm . icmintent = r . devmode - > icmintent ;
dm . icmmethod = r . devmode - > icmmethod ;
dm . logpixels = r . devmode - > logpixels ;
dm . mediatype = r . devmode - > mediatype ;
dm . orientation = r . devmode - > orientation ;
dm . panningheight = r . devmode - > pelsheight ;
dm . panningwidth = r . devmode - > panningwidth ;
dm . paperlength = r . devmode - > paperlength ;
dm . papersize = r . devmode - > papersize ;
dm . paperwidth = r . devmode - > paperwidth ;
dm . pelsheight = r . devmode - > pelsheight ;
dm . pelswidth = r . devmode - > pelswidth ;
dm . printquality = r . devmode - > printquality ;
2011-06-15 14:46:55 +04:00
dm . size = r . devmode - > size ;
2010-06-15 15:37:44 +04:00
dm . scale = r . devmode - > scale ;
dm . specversion = r . devmode - > specversion ;
dm . ttoption = r . devmode - > ttoption ;
dm . yresolution = r . devmode - > yresolution ;
if ( r . devmode - > nt_dev_private ! = NULL ) {
dm . driverextra_data . data = r . devmode - > nt_dev_private - > data ;
dm . driverextra_data . length = r . devmode - > nt_dev_private - > length ;
dm . __driverextra_length = r . devmode - > nt_dev_private - > length ;
}
devmode_ctr . devmode = & dm ;
}
2011-07-04 21:47:07 +04:00
result = winreg_update_printer ( mem_ctx , b ,
key_name ,
2011-07-05 13:34:47 +04:00
info2_mask ,
2011-07-04 21:47:07 +04:00
& info2 ,
& dm ,
NULL ) ;
2011-01-15 14:06:09 +03:00
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 2 , ( " SetPrinter(%s) level 2 refused -- %s. \n " ,
key_name , win_errstr ( result ) ) ) ;
status = werror_to_ntstatus ( result ) ;
goto done ;
}
2010-06-15 15:37:44 +04:00
/* migrate printerdata */
for ( j = 0 ; j < r . count ; j + + ) {
char * valuename ;
2011-05-06 01:22:11 +04:00
const char * keyname ;
2010-06-15 15:37:44 +04:00
if ( r . printer_data [ j ] . type = = REG_NONE ) {
continue ;
}
2011-05-06 01:22:11 +04:00
keyname = r . printer_data [ j ] . name ;
2010-06-15 15:37:44 +04:00
valuename = strchr ( keyname , ' \\ ' ) ;
if ( valuename = = NULL ) {
continue ;
} else {
valuename [ 0 ] = ' \0 ' ;
valuename + + ;
}
2011-07-04 21:47:07 +04:00
result = winreg_set_printer_dataex ( mem_ctx , b ,
key_name ,
keyname ,
valuename ,
r . printer_data [ j ] . type ,
r . printer_data [ j ] . data . data ,
r . printer_data [ j ] . data . length ) ;
2011-01-15 14:06:09 +03:00
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 2 , ( " SetPrinterDataEx: printer [%s], keyname [%s], "
" valuename [%s] refused -- %s. \n " ,
key_name , keyname , valuename ,
win_errstr ( result ) ) ) ;
status = werror_to_ntstatus ( result ) ;
break ;
}
2010-06-15 15:37:44 +04:00
}
2011-07-05 13:34:47 +04:00
status = NT_STATUS_OK ;
2010-06-15 15:37:44 +04:00
done :
return status ;
}
2011-07-01 16:57:32 +04:00
NTSTATUS printing_tdb_migrate_secdesc ( TALLOC_CTX * mem_ctx ,
2011-07-01 17:39:11 +04:00
struct rpc_pipe_client * winreg_pipe ,
2011-07-01 16:57:32 +04:00
const char * key_name ,
unsigned char * data ,
size_t length )
2010-06-15 15:37:44 +04:00
{
2011-07-04 21:47:07 +04:00
struct dcerpc_binding_handle * b = winreg_pipe - > binding_handle ;
2010-06-15 15:37:44 +04:00
enum ndr_err_code ndr_err ;
struct sec_desc_buf secdesc_ctr ;
DATA_BLOB blob ;
WERROR result ;
if ( strequal ( key_name , " printers " ) ) {
return NT_STATUS_OK ;
}
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & secdesc_ctr ,
( ndr_pull_flags_fn_t ) ndr_pull_sec_desc_buf ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 2 , ( " security descriptor pull failed: %s \n " ,
ndr_errstr ( ndr_err ) ) ) ;
return NT_STATUS_NO_MEMORY ;
}
DEBUG ( 2 , ( " Migrating Security Descriptor: %s \n " , key_name ) ) ;
2011-07-04 21:47:07 +04:00
result = winreg_set_printer_secdesc ( mem_ctx , b ,
2010-06-15 15:37:44 +04:00
key_name ,
2011-07-04 21:47:07 +04:00
secdesc_ctr . sd ) ;
2011-01-15 14:06:09 +03:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2011-07-04 21:47:07 +04:00
return werror_to_ntstatus ( result ) ;
2011-01-15 14:06:09 +03:00
}
2010-06-15 15:37:44 +04:00
2011-07-04 21:47:07 +04:00
return NT_STATUS_OK ;
2010-06-15 15:37:44 +04:00
}