2009-02-12 14:10:16 +03:00
/*
* Unix SMB / CIFS implementation .
* RPC Pipe client / server routines
* Copyright ( C ) Guenther Deschner 2009.
*
* 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"
2010-06-03 11:57:50 +04:00
# include "../librpc/gen_ndr/ndr_spoolss.h"
2010-07-31 02:47:20 +04:00
# include "rpc_client/init_spoolss.h"
2011-07-05 04:15:35 +04:00
# include "../libcli/security/security.h"
# include "secrets.h"
# include "passdb/machine_sid.h"
2009-02-12 14:10:16 +03:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool init_systemtime ( struct spoolss_Time * r ,
struct tm * unixtime )
{
if ( ! r | | ! unixtime ) {
return false ;
}
r - > year = unixtime - > tm_year + 1900 ;
r - > month = unixtime - > tm_mon + 1 ;
r - > day_of_week = unixtime - > tm_wday ;
r - > day = unixtime - > tm_mday ;
r - > hour = unixtime - > tm_hour ;
r - > minute = unixtime - > tm_min ;
r - > second = unixtime - > tm_sec ;
r - > millisecond = 0 ;
return true ;
}
2009-03-16 18:52:37 +03:00
2010-05-07 17:26:41 +04:00
time_t spoolss_Time_to_time_t ( const struct spoolss_Time * r )
{
2017-07-11 14:50:09 +03:00
struct tm unixtime = {
. tm_year = r - > year - 1900 ,
. tm_mon = r - > month - 1 ,
. tm_wday = r - > day_of_week ,
. tm_mday = r - > day ,
. tm_hour = r - > hour ,
. tm_min = r - > minute ,
. tm_sec = r - > second ,
} ;
2010-05-07 17:26:41 +04:00
return mktime ( & unixtime ) ;
}
2016-09-23 18:10:22 +03:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool spoolss_timestr_to_NTTIME ( const char * str ,
NTTIME * data )
{
struct tm tm ;
time_t t ;
if ( strequal ( str , " 01/01/1601 " ) ) {
* data = 0 ;
return true ;
}
ZERO_STRUCT ( tm ) ;
if ( sscanf ( str , " %d/%d/%d " ,
& tm . tm_mon , & tm . tm_mday , & tm . tm_year ) ! = 3 ) {
return false ;
}
tm . tm_mon - = 1 ;
tm . tm_year - = 1900 ;
tm . tm_isdst = - 1 ;
t = mktime ( & tm ) ;
unix_to_nt_time ( data , t ) ;
return true ;
}
2016-09-23 18:11:27 +03:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool spoolss_driver_version_to_qword ( const char * str ,
uint64_t * data )
{
2016-11-11 18:35:03 +03:00
unsigned int v1 , v2 , v3 , v4 = 0 ;
2016-09-23 18:11:27 +03:00
2016-11-11 18:35:03 +03:00
if ( ( sscanf ( str , " %u.%u.%u.%u " , & v1 , & v2 , & v3 , & v4 ) ! = 4 ) & &
( sscanf ( str , " %u.%u.%u " , & v1 , & v2 , & v3 ) ! = 3 ) )
{
2016-09-23 18:11:27 +03:00
return false ;
}
* data = ( ( uint64_t ) ( v1 & 0xFFFF ) < < 48 ) +
( ( uint64_t ) ( v2 & 0xFFFF ) < < 32 ) +
( ( uint64_t ) ( v3 & 0xFFFF ) < < 16 ) +
( uint64_t ) ( v4 & 0xFFFF ) ;
return true ;
}
2009-03-16 18:52:37 +03:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR pull_spoolss_PrinterData ( TALLOC_CTX * mem_ctx ,
const DATA_BLOB * blob ,
union spoolss_PrinterData * data ,
enum winreg_Type type )
{
enum ndr_err_code ndr_err ;
2010-05-10 02:42:06 +04:00
ndr_err = ndr_pull_union_blob ( blob , mem_ctx , data , type ,
2009-03-16 18:52:37 +03:00
( ndr_pull_flags_fn_t ) ndr_pull_spoolss_PrinterData ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2015-12-03 17:24:21 +03:00
return WERR_GEN_FAILURE ;
2009-03-16 18:52:37 +03:00
}
return WERR_OK ;
}
2009-03-16 18:53:41 +03:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR push_spoolss_PrinterData ( TALLOC_CTX * mem_ctx , DATA_BLOB * blob ,
enum winreg_Type type ,
union spoolss_PrinterData * data )
{
enum ndr_err_code ndr_err ;
2010-05-10 02:42:06 +04:00
ndr_err = ndr_push_union_blob ( blob , mem_ctx , data , type ,
2009-03-16 18:53:41 +03:00
( ndr_push_flags_fn_t ) ndr_push_spoolss_PrinterData ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
2015-12-03 17:24:21 +03:00
return WERR_GEN_FAILURE ;
2009-03-16 18:53:41 +03:00
}
return WERR_OK ;
}
2010-06-03 18:30:55 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void spoolss_printerinfo2_to_setprinterinfo2 ( const struct spoolss_PrinterInfo2 * i ,
struct spoolss_SetPrinterInfo2 * s )
{
s - > servername = i - > servername ;
s - > printername = i - > printername ;
s - > sharename = i - > sharename ;
s - > portname = i - > portname ;
s - > drivername = i - > drivername ;
s - > comment = i - > comment ;
s - > location = i - > location ;
2016-11-11 18:29:20 +03:00
s - > devmode_ptr = 0 ;
2010-06-03 18:30:55 +04:00
s - > sepfile = i - > sepfile ;
s - > printprocessor = i - > printprocessor ;
s - > datatype = i - > datatype ;
s - > parameters = i - > parameters ;
2016-11-11 18:29:20 +03:00
s - > secdesc_ptr = 0 ;
2010-06-03 18:30:55 +04:00
s - > attributes = i - > attributes ;
s - > priority = i - > priority ;
s - > defaultpriority = i - > defaultpriority ;
s - > starttime = i - > starttime ;
s - > untiltime = i - > untiltime ;
s - > status = i - > status ;
s - > cjobs = i - > cjobs ;
s - > averageppm = i - > averageppm ;
}
2011-07-05 04:12:24 +04:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool driver_info_ctr_to_info8 ( struct spoolss_AddDriverInfoCtr * r ,
struct spoolss_DriverInfo8 * _info8 )
{
struct spoolss_DriverInfo8 info8 ;
ZERO_STRUCT ( info8 ) ;
switch ( r - > level ) {
case 3 :
info8 . version = r - > info . info3 - > version ;
info8 . driver_name = r - > info . info3 - > driver_name ;
info8 . architecture = r - > info . info3 - > architecture ;
info8 . driver_path = r - > info . info3 - > driver_path ;
info8 . data_file = r - > info . info3 - > data_file ;
info8 . config_file = r - > info . info3 - > config_file ;
info8 . help_file = r - > info . info3 - > help_file ;
info8 . monitor_name = r - > info . info3 - > monitor_name ;
info8 . default_datatype = r - > info . info3 - > default_datatype ;
if ( r - > info . info3 - > dependent_files & & r - > info . info3 - > dependent_files - > string ) {
info8 . dependent_files = r - > info . info3 - > dependent_files - > string ;
}
break ;
case 6 :
info8 . version = r - > info . info6 - > version ;
info8 . driver_name = r - > info . info6 - > driver_name ;
info8 . architecture = r - > info . info6 - > architecture ;
info8 . driver_path = r - > info . info6 - > driver_path ;
info8 . data_file = r - > info . info6 - > data_file ;
info8 . config_file = r - > info . info6 - > config_file ;
info8 . help_file = r - > info . info6 - > help_file ;
info8 . monitor_name = r - > info . info6 - > monitor_name ;
info8 . default_datatype = r - > info . info6 - > default_datatype ;
if ( r - > info . info6 - > dependent_files & & r - > info . info6 - > dependent_files - > string ) {
info8 . dependent_files = r - > info . info6 - > dependent_files - > string ;
}
info8 . driver_date = r - > info . info6 - > driver_date ;
info8 . driver_version = r - > info . info6 - > driver_version ;
info8 . manufacturer_name = r - > info . info6 - > manufacturer_name ;
info8 . manufacturer_url = r - > info . info6 - > manufacturer_url ;
info8 . hardware_id = r - > info . info6 - > hardware_id ;
info8 . provider = r - > info . info6 - > provider ;
break ;
case 8 :
info8 . version = r - > info . info8 - > version ;
info8 . driver_name = r - > info . info8 - > driver_name ;
info8 . architecture = r - > info . info8 - > architecture ;
info8 . driver_path = r - > info . info8 - > driver_path ;
info8 . data_file = r - > info . info8 - > data_file ;
info8 . config_file = r - > info . info8 - > config_file ;
info8 . help_file = r - > info . info8 - > help_file ;
info8 . monitor_name = r - > info . info8 - > monitor_name ;
info8 . default_datatype = r - > info . info8 - > default_datatype ;
if ( r - > info . info8 - > dependent_files & & r - > info . info8 - > dependent_files - > string ) {
info8 . dependent_files = r - > info . info8 - > dependent_files - > string ;
}
if ( r - > info . info8 - > previous_names & & r - > info . info8 - > previous_names - > string ) {
info8 . previous_names = r - > info . info8 - > previous_names - > string ;
}
info8 . driver_date = r - > info . info8 - > driver_date ;
info8 . driver_version = r - > info . info8 - > driver_version ;
info8 . manufacturer_name = r - > info . info8 - > manufacturer_name ;
info8 . manufacturer_url = r - > info . info8 - > manufacturer_url ;
info8 . hardware_id = r - > info . info8 - > hardware_id ;
info8 . provider = r - > info . info8 - > provider ;
info8 . print_processor = r - > info . info8 - > print_processor ;
info8 . vendor_setup = r - > info . info8 - > vendor_setup ;
if ( r - > info . info8 - > color_profiles & & r - > info . info8 - > color_profiles - > string ) {
info8 . color_profiles = r - > info . info8 - > color_profiles - > string ;
}
info8 . inf_path = r - > info . info8 - > inf_path ;
info8 . printer_driver_attributes = r - > info . info8 - > printer_driver_attributes ;
if ( r - > info . info8 - > core_driver_dependencies & & r - > info . info8 - > core_driver_dependencies - > string ) {
info8 . core_driver_dependencies = r - > info . info8 - > core_driver_dependencies - > string ;
}
info8 . min_inbox_driver_ver_date = r - > info . info8 - > min_inbox_driver_ver_date ;
info8 . min_inbox_driver_ver_version = r - > info . info8 - > min_inbox_driver_ver_version ;
break ;
default :
return false ;
}
* _info8 = info8 ;
return true ;
}
2011-07-05 04:15:35 +04:00
/****************************************************************************
Create and allocate a default devicemode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR spoolss_create_default_devmode ( TALLOC_CTX * mem_ctx ,
const char * devicename ,
struct spoolss_DeviceMode * * devmode )
{
struct spoolss_DeviceMode * dm ;
char * dname ;
dm = talloc_zero ( mem_ctx , struct spoolss_DeviceMode ) ;
if ( dm = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2011-07-05 04:15:35 +04:00
}
dname = talloc_asprintf ( dm , " %s " , devicename ) ;
if ( dname = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2011-07-05 04:15:35 +04:00
}
if ( strlen ( dname ) > MAXDEVICENAME ) {
dname [ MAXDEVICENAME ] = ' \0 ' ;
}
dm - > devicename = dname ;
dm - > formname = talloc_strdup ( dm , " Letter " ) ;
if ( dm - > formname = = NULL ) {
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2011-07-05 04:15:35 +04:00
}
dm - > specversion = DMSPEC_NT4_AND_ABOVE ;
dm - > driverversion = 0x0400 ;
dm - > size = 0x00DC ;
dm - > __driverextra_length = 0 ;
dm - > fields = DEVMODE_FORMNAME |
DEVMODE_TTOPTION |
DEVMODE_PRINTQUALITY |
DEVMODE_DEFAULTSOURCE |
DEVMODE_COPIES |
DEVMODE_SCALE |
DEVMODE_PAPERSIZE |
DEVMODE_ORIENTATION ;
dm - > orientation = DMORIENT_PORTRAIT ;
dm - > papersize = DMPAPER_LETTER ;
dm - > paperlength = 0 ;
dm - > paperwidth = 0 ;
dm - > scale = 0x64 ;
dm - > copies = 1 ;
dm - > defaultsource = DMBIN_FORMSOURCE ;
dm - > printquality = DMRES_HIGH ; /* 0x0258 */
dm - > color = DMRES_MONOCHROME ;
dm - > duplex = DMDUP_SIMPLEX ;
dm - > yresolution = 0 ;
dm - > ttoption = DMTT_SUBDEV ;
dm - > collate = DMCOLLATE_FALSE ;
dm - > icmmethod = 0 ;
dm - > icmintent = 0 ;
dm - > mediatype = 0 ;
dm - > dithertype = 0 ;
dm - > logpixels = 0 ;
dm - > bitsperpel = 0 ;
dm - > pelswidth = 0 ;
dm - > pelsheight = 0 ;
dm - > displayflags = 0 ;
dm - > displayfrequency = 0 ;
dm - > reserved1 = 0 ;
dm - > reserved2 = 0 ;
dm - > panningwidth = 0 ;
dm - > panningheight = 0 ;
dm - > driverextra_data . data = NULL ;
dm - > driverextra_data . length = 0 ;
* devmode = dm ;
return WERR_OK ;
}
WERROR spoolss_create_default_secdesc ( TALLOC_CTX * mem_ctx ,
struct spoolss_security_descriptor * * secdesc )
{
struct security_ace ace [ 7 ] ; /* max number of ace entries */
int i = 0 ;
uint32_t sa ;
struct security_acl * psa = NULL ;
struct security_descriptor * psd = NULL ;
struct dom_sid adm_sid ;
size_t sd_size ;
/* Create an ACE where Everyone is allowed to print */
sa = PRINTER_ACE_PRINT ;
init_sec_ace ( & ace [ i + + ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
/* Add the domain admins group if we are a DC */
if ( IS_DC ) {
struct dom_sid domadmins_sid ;
sid_compose ( & domadmins_sid , get_global_sam_sid ( ) ,
DOMAIN_RID_ADMINS ) ;
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & domadmins_sid ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & domadmins_sid , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
}
else if ( secrets_fetch_domain_sid ( lp_workgroup ( ) , & adm_sid ) ) {
sid_append_rid ( & adm_sid , DOMAIN_RID_ADMINISTRATOR ) ;
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & adm_sid ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & adm_sid , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
}
/* add BUILTIN\Administrators as FULL CONTROL */
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
/* add BUILTIN\Print Operators as FULL CONTROL */
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Print_Operators ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Print_Operators ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
/* Make the security descriptor owned by the BUILTIN\Administrators */
/* The ACL revision number in rpc_secdesc.h differs from the one
created by NT when setting ACE entries in printer
descriptors . NT4 complains about the property being edited by a
NT5 machine . */
if ( ( psa = make_sec_acl ( mem_ctx , NT4_ACL_REVISION , i , ace ) ) ! = NULL ) {
psd = make_sec_desc ( mem_ctx ,
SD_REVISION ,
SEC_DESC_SELF_RELATIVE ,
& global_sid_Builtin_Administrators ,
& global_sid_Builtin_Administrators ,
NULL ,
psa ,
& sd_size ) ;
}
if ( psd = = NULL ) {
DEBUG ( 0 , ( " construct_default_printer_sd: Failed to make SEC_DESC. \n " ) ) ;
2015-12-03 17:24:15 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2011-07-05 04:15:35 +04:00
}
DEBUG ( 4 , ( " construct_default_printer_sdb: size = %u. \n " ,
( unsigned int ) sd_size ) ) ;
* secdesc = psd ;
return WERR_OK ;
}
2016-09-08 22:23:54 +03:00
const char * spoolss_get_short_filesys_environment ( const char * environment )
{
if ( strequal ( environment , SPOOLSS_ARCHITECTURE_x64 ) ) {
return " amd64 " ;
} else if ( strequal ( environment , SPOOLSS_ARCHITECTURE_NT_X86 ) ) {
return " x86 " ;
} else {
return NULL ;
}
}
2018-08-31 18:36:19 +03:00
2018-08-31 20:28:58 +03:00
/* Windows 7 and Windows Server 2008 R2 */
# define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6
# define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1
# define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007
2018-08-31 18:36:19 +03:00
WERROR spoolss_init_spoolss_UserLevel1 ( TALLOC_CTX * mem_ctx ,
const char * username ,
struct spoolss_UserLevel1 * r )
{
ZERO_STRUCTP ( r ) ;
r - > size = 28 ;
r - > client = talloc_asprintf ( mem_ctx , " \\ \\ %s " , lp_netbios_name ( ) ) ;
W_ERROR_HAVE_NO_MEMORY ( r - > client ) ;
r - > user = talloc_strdup ( mem_ctx , username ) ;
W_ERROR_HAVE_NO_MEMORY ( r - > user ) ;
r - > processor = 0 ;
r - > major = lp_parm_int ( GLOBAL_SECTION_SNUM ,
" spoolss_client " , " os_major " ,
GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT ) ;
r - > minor = lp_parm_int ( GLOBAL_SECTION_SNUM ,
" spoolss_client " , " os_minor " ,
GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT ) ;
r - > build = lp_parm_int ( GLOBAL_SECTION_SNUM ,
" spoolss_client " , " os_build " ,
GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT ) ;
return WERR_OK ;
}