2002-02-01 19:15:53 +03:00
/*
Unix SMB / CIFS implementation .
2002-02-01 19:58:01 +03:00
ads ( active directory ) printer utility library
2002-02-01 19:15:53 +03:00
Copyright ( C ) Jim McDonough 2002
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 2 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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# ifdef HAVE_ADS
2002-02-02 05:04:01 +03:00
/*
find a printer given the name and the hostname
Note that results " res " may be allocated on return so that the
results can be used . It should be freed using ads_msgfree .
*/
ADS_STATUS ads_find_printer_on_server ( ADS_STRUCT * ads , void * * res ,
2002-11-13 02:20:50 +03:00
const char * printer , const char * servername )
2002-02-02 05:04:01 +03:00
{
ADS_STATUS status ;
2003-06-13 08:29:20 +04:00
char * srv_dn , * * srv_cn , * s ;
2002-02-02 05:04:01 +03:00
const char * attrs [ ] = { " * " , " nTSecurityDescriptor " , NULL } ;
status = ads_find_machine_acct ( ads , res , servername ) ;
if ( ! ADS_ERR_OK ( status ) ) {
DEBUG ( 1 , ( " ads_add_printer: cannot find host %s in ads \n " ,
servername ) ) ;
return status ;
}
srv_dn = ldap_get_dn ( ads - > ld , * res ) ;
2002-07-15 14:35:28 +04:00
srv_cn = ldap_explode_dn ( srv_dn , 1 ) ;
2002-02-02 05:04:01 +03:00
ads_msgfree ( ads , * res ) ;
2003-06-13 08:29:20 +04:00
asprintf ( & s , " (cn=%s-%s) " , srv_cn [ 0 ] , printer ) ;
status = ads_search ( ads , res , s , attrs ) ;
2002-02-02 05:04:01 +03:00
2002-07-15 14:35:28 +04:00
ldap_memfree ( srv_dn ) ;
ldap_value_free ( srv_cn ) ;
2003-06-13 08:29:20 +04:00
free ( s ) ;
2002-02-02 05:04:01 +03:00
return status ;
}
2003-07-03 09:08:51 +04:00
ADS_STATUS ads_find_printers ( ADS_STRUCT * ads , void * * res )
{
char * ldap_expr ;
const char * attrs [ ] = { " objectClass " , " printerName " , " location " , " driverName " ,
" serverName " , " description " , NULL } ;
/* For the moment only display all printers */
ldap_expr = " (&(!(showInAdvancedViewOnly=TRUE))(uncName=*) "
" (objectCategory=printQueue)) " ;
return ads_search ( ads , res , ldap_expr , attrs ) ;
}
2002-02-01 19:15:53 +03:00
/*
2002-11-18 22:59:58 +03:00
modify a printer entry in the directory
2002-02-01 19:15:53 +03:00
*/
ADS_STATUS ads_mod_printer_entry ( ADS_STRUCT * ads , char * prt_dn ,
2002-11-18 22:59:58 +03:00
TALLOC_CTX * ctx , const ADS_MODLIST * mods )
2002-02-01 19:15:53 +03:00
{
2002-11-18 22:59:58 +03:00
return ads_gen_mod ( ads , prt_dn , * mods ) ;
2002-02-01 19:15:53 +03:00
}
/*
add a printer to the directory
*/
2002-11-18 22:59:58 +03:00
ADS_STATUS ads_add_printer_entry ( ADS_STRUCT * ads , char * prt_dn ,
TALLOC_CTX * ctx , ADS_MODLIST * mods )
2002-02-01 19:15:53 +03:00
{
2002-11-18 22:59:58 +03:00
ads_mod_str ( ctx , mods , " objectClass " , " printQueue " ) ;
return ads_gen_add ( ads , prt_dn , * mods ) ;
}
2002-02-12 21:22:47 +03:00
2002-11-18 22:59:58 +03:00
/*
map a REG_SZ to an ldap mod
*/
static BOOL map_sz ( TALLOC_CTX * ctx , ADS_MODLIST * mods ,
const REGISTRY_VALUE * value )
{
char * str_value = NULL ;
2002-11-18 23:45:46 +03:00
ADS_STATUS status ;
2002-02-12 21:22:47 +03:00
2002-11-18 22:59:58 +03:00
if ( value - > type ! = REG_SZ )
return False ;
2002-02-12 21:22:47 +03:00
2002-11-18 22:59:58 +03:00
if ( value - > size & & * ( ( smb_ucs2_t * ) value - > data_p ) ) {
2003-02-19 15:31:16 +03:00
pull_ucs2_talloc ( ctx , & str_value , ( const smb_ucs2_t * ) value - > data_p ) ;
2002-11-18 23:45:46 +03:00
status = ads_mod_str ( ctx , mods , value - > valuename , str_value ) ;
return ADS_ERR_OK ( status ) ;
2002-11-18 22:59:58 +03:00
}
return True ;
}
2002-02-12 21:22:47 +03:00
2002-11-18 22:59:58 +03:00
/*
map a REG_DWORD to an ldap mod
*/
static BOOL map_dword ( TALLOC_CTX * ctx , ADS_MODLIST * mods ,
const REGISTRY_VALUE * value )
{
char * str_value = NULL ;
2002-11-18 23:45:46 +03:00
ADS_STATUS status ;
2002-02-12 21:22:47 +03:00
2002-11-18 22:59:58 +03:00
if ( value - > type ! = REG_DWORD )
return False ;
str_value = talloc_asprintf ( ctx , " %d " , * ( ( uint32 * ) value - > data_p ) ) ;
2002-11-18 23:45:46 +03:00
status = ads_mod_str ( ctx , mods , value - > valuename , str_value ) ;
return ADS_ERR_OK ( status ) ;
2002-11-18 22:59:58 +03:00
}
2002-02-12 21:22:47 +03:00
2002-11-18 22:59:58 +03:00
/*
map a boolean REG_BINARY to an ldap mod
*/
static BOOL map_bool ( TALLOC_CTX * ctx , ADS_MODLIST * mods ,
const REGISTRY_VALUE * value )
{
char * str_value ;
2002-11-18 23:45:46 +03:00
ADS_STATUS status ;
2002-02-01 19:15:53 +03:00
2002-11-18 22:59:58 +03:00
if ( ( value - > type ! = REG_BINARY ) | | ( value - > size ! = 1 ) )
return False ;
str_value = talloc_asprintf ( ctx , " %s " ,
* ( value - > data_p ) ? " TRUE " : " FALSE " ) ;
2002-11-18 23:45:46 +03:00
status = ads_mod_str ( ctx , mods , value - > valuename , str_value ) ;
return ADS_ERR_OK ( status ) ;
2002-02-01 19:15:53 +03:00
}
/*
2002-11-18 22:59:58 +03:00
map a REG_MULTI_SZ to an ldap mod
2002-02-01 19:15:53 +03:00
*/
2002-11-18 22:59:58 +03:00
static BOOL map_multi_sz ( TALLOC_CTX * ctx , ADS_MODLIST * mods ,
const REGISTRY_VALUE * value )
2002-02-01 19:15:53 +03:00
{
2002-11-18 22:59:58 +03:00
char * * str_values = NULL ;
smb_ucs2_t * cur_str = ( smb_ucs2_t * ) value - > data_p ;
uint32 size = 0 , num_vals = 0 , i = 0 ;
2002-11-18 23:45:46 +03:00
ADS_STATUS status ;
2002-11-18 22:59:58 +03:00
if ( value - > type ! = REG_MULTI_SZ )
return False ;
while ( cur_str & & * cur_str & & ( size < value - > size ) ) {
size + = 2 * ( strlen_w ( cur_str ) + 1 ) ;
cur_str + = strlen_w ( cur_str ) + 1 ;
num_vals + + ;
} ;
if ( num_vals ) {
str_values = talloc ( ctx ,
( num_vals + 1 ) * sizeof ( smb_ucs2_t * ) ) ;
memset ( str_values , ' \0 ' ,
( num_vals + 1 ) * sizeof ( smb_ucs2_t * ) ) ;
cur_str = ( smb_ucs2_t * ) value - > data_p ;
for ( i = 0 ; i < num_vals ; i + + )
2003-02-19 15:31:16 +03:00
cur_str + = pull_ucs2_talloc ( ctx , & str_values [ i ] ,
cur_str ) ;
2002-11-18 22:59:58 +03:00
2002-11-18 23:45:46 +03:00
status = ads_mod_strlist ( ctx , mods , value - > valuename ,
( const char * * ) str_values ) ;
return ADS_ERR_OK ( status ) ;
2002-11-18 22:59:58 +03:00
}
return True ;
}
2002-02-01 19:15:53 +03:00
2002-11-18 22:59:58 +03:00
struct valmap_to_ads {
2003-01-03 11:28:12 +03:00
const char * valname ;
2002-11-18 22:59:58 +03:00
BOOL ( * fn ) ( TALLOC_CTX * , ADS_MODLIST * , const REGISTRY_VALUE * ) ;
} ;
/*
map a REG_SZ to an ldap mod
*/
static void map_regval_to_ads ( TALLOC_CTX * ctx , ADS_MODLIST * mods ,
REGISTRY_VALUE * value )
{
2003-01-03 11:28:12 +03:00
const struct valmap_to_ads map [ ] = {
2002-12-03 22:42:39 +03:00
{ SPOOL_REG_ASSETNUMBER , map_sz } ,
{ SPOOL_REG_BYTESPERMINUTE , map_dword } ,
{ SPOOL_REG_DEFAULTPRIORITY , map_dword } ,
2002-12-05 22:13:40 +03:00
{ SPOOL_REG_DESCRIPTION , map_sz } ,
2002-12-03 22:42:39 +03:00
{ SPOOL_REG_DRIVERNAME , map_sz } ,
{ SPOOL_REG_DRIVERVERSION , map_dword } ,
{ SPOOL_REG_FLAGS , map_dword } ,
{ SPOOL_REG_LOCATION , map_sz } ,
{ SPOOL_REG_OPERATINGSYSTEM , map_sz } ,
{ SPOOL_REG_OPERATINGSYSTEMHOTFIX , map_sz } ,
{ SPOOL_REG_OPERATINGSYSTEMSERVICEPACK , map_sz } ,
{ SPOOL_REG_OPERATINGSYSTEMVERSION , map_sz } ,
{ SPOOL_REG_PORTNAME , map_multi_sz } ,
{ SPOOL_REG_PRINTATTRIBUTES , map_dword } ,
{ SPOOL_REG_PRINTBINNAMES , map_multi_sz } ,
{ SPOOL_REG_PRINTCOLLATE , map_bool } ,
{ SPOOL_REG_PRINTCOLOR , map_bool } ,
{ SPOOL_REG_PRINTDUPLEXSUPPORTED , map_bool } ,
{ SPOOL_REG_PRINTENDTIME , map_dword } ,
{ SPOOL_REG_PRINTFORMNAME , map_sz } ,
{ SPOOL_REG_PRINTKEEPPRINTEDJOBS , map_bool } ,
{ SPOOL_REG_PRINTLANGUAGE , map_multi_sz } ,
{ SPOOL_REG_PRINTMACADDRESS , map_sz } ,
{ SPOOL_REG_PRINTMAXCOPIES , map_sz } ,
{ SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED , map_dword } ,
{ SPOOL_REG_PRINTMAXXEXTENT , map_dword } ,
{ SPOOL_REG_PRINTMAXYEXTENT , map_dword } ,
{ SPOOL_REG_PRINTMEDIAREADY , map_multi_sz } ,
{ SPOOL_REG_PRINTMEDIASUPPORTED , map_multi_sz } ,
{ SPOOL_REG_PRINTMEMORY , map_dword } ,
{ SPOOL_REG_PRINTMINXEXTENT , map_dword } ,
{ SPOOL_REG_PRINTMINYEXTENT , map_dword } ,
{ SPOOL_REG_PRINTNETWORKADDRESS , map_sz } ,
{ SPOOL_REG_PRINTNOTIFY , map_sz } ,
{ SPOOL_REG_PRINTNUMBERUP , map_dword } ,
{ SPOOL_REG_PRINTORIENTATIONSSUPPORTED , map_multi_sz } ,
{ SPOOL_REG_PRINTOWNER , map_sz } ,
{ SPOOL_REG_PRINTPAGESPERMINUTE , map_dword } ,
{ SPOOL_REG_PRINTRATE , map_dword } ,
{ SPOOL_REG_PRINTRATEUNIT , map_sz } ,
{ SPOOL_REG_PRINTSEPARATORFILE , map_sz } ,
{ SPOOL_REG_PRINTSHARENAME , map_sz } ,
{ SPOOL_REG_PRINTSPOOLING , map_sz } ,
{ SPOOL_REG_PRINTSTAPLINGSUPPORTED , map_bool } ,
{ SPOOL_REG_PRINTSTARTTIME , map_dword } ,
{ SPOOL_REG_PRINTSTATUS , map_sz } ,
{ SPOOL_REG_PRIORITY , map_dword } ,
{ SPOOL_REG_SERVERNAME , map_sz } ,
{ SPOOL_REG_SHORTSERVERNAME , map_sz } ,
{ SPOOL_REG_UNCNAME , map_sz } ,
{ SPOOL_REG_URL , map_sz } ,
{ SPOOL_REG_VERSIONNUMBER , map_dword } ,
2002-11-18 22:59:58 +03:00
{ NULL , NULL }
} ;
int i ;
for ( i = 0 ; map [ i ] . valname ; i + + ) {
if ( StrCaseCmp ( map [ i ] . valname , value - > valuename ) = = 0 ) {
if ( ! map [ i ] . fn ( ctx , mods , value ) ) {
DEBUG ( 5 , ( " Add of value %s to modlist failed \n " , value - > valuename ) ) ;
} else {
DEBUG ( 7 , ( " Mapped value %s \n " , value - > valuename ) ) ;
}
2002-02-01 19:15:53 +03:00
}
}
2002-11-18 22:59:58 +03:00
}
2002-02-01 19:15:53 +03:00
2002-11-18 22:59:58 +03:00
WERROR get_remote_printer_publishing_data ( struct cli_state * cli ,
TALLOC_CTX * mem_ctx ,
ADS_MODLIST * mods ,
2003-01-03 11:28:12 +03:00
const char * printer )
2002-11-18 22:59:58 +03:00
{
WERROR result ;
char * printername , * servername ;
REGVAL_CTR dsdriver_ctr , dsspooler_ctr ;
2002-12-03 22:42:39 +03:00
BOOL got_dsdriver = False , got_dsspooler = False ;
2002-11-18 22:59:58 +03:00
uint32 needed , i ;
POLICY_HND pol ;
asprintf ( & servername , " \\ \\ %s " , cli - > desthost ) ;
asprintf ( & printername , " %s \\ %s " , servername , printer ) ;
if ( ! servername | | ! printername ) {
DEBUG ( 3 , ( " Insufficient memory \n " ) ) ;
return WERR_NOMEM ;
}
result = cli_spoolss_open_printer_ex ( cli , mem_ctx , printername ,
" " , MAXIMUM_ALLOWED_ACCESS ,
servername , cli - > user_name , & pol ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 3 , ( " Unable to open printer %s, error is %s. \n " ,
printername , dos_errstr ( result ) ) ) ;
return result ;
}
result = cli_spoolss_enumprinterdataex ( cli , mem_ctx , 0 , & needed ,
2002-12-03 22:42:39 +03:00
& pol , SPOOL_DSDRIVER_KEY , NULL ) ;
2002-11-18 22:59:58 +03:00
if ( W_ERROR_V ( result ) = = ERRmoredata )
result = cli_spoolss_enumprinterdataex ( cli , mem_ctx , needed ,
2002-12-03 22:42:39 +03:00
NULL , & pol ,
SPOOL_DSDRIVER_KEY ,
2002-11-18 22:59:58 +03:00
& dsdriver_ctr ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 3 , ( " Unable to do enumdataex on %s, error is %s. \n " ,
printername , dos_errstr ( result ) ) ) ;
2002-12-03 22:42:39 +03:00
} else {
2002-11-18 22:59:58 +03:00
2002-12-03 22:42:39 +03:00
/* Have the data we need now, so start building */
got_dsdriver = True ;
for ( i = 0 ; i < dsdriver_ctr . num_values ; i + + )
map_regval_to_ads ( mem_ctx , mods ,
dsdriver_ctr . values [ i ] ) ;
}
2002-11-18 22:59:58 +03:00
result = cli_spoolss_enumprinterdataex ( cli , mem_ctx , 0 , & needed ,
2002-12-03 22:42:39 +03:00
& pol , SPOOL_DSSPOOLER_KEY ,
NULL ) ;
2002-11-18 22:59:58 +03:00
if ( W_ERROR_V ( result ) = = ERRmoredata )
result = cli_spoolss_enumprinterdataex ( cli , mem_ctx , needed ,
2002-12-03 22:42:39 +03:00
NULL , & pol ,
SPOOL_DSSPOOLER_KEY ,
2002-11-18 22:59:58 +03:00
& dsspooler_ctr ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 3 , ( " Unable to do enumdataex on %s, error is %s. \n " ,
printername , dos_errstr ( result ) ) ) ;
2002-12-03 22:42:39 +03:00
} else {
got_dsspooler = True ;
for ( i = 0 ; i < dsspooler_ctr . num_values ; i + + )
map_regval_to_ads ( mem_ctx , mods ,
dsspooler_ctr . values [ i ] ) ;
2002-02-11 18:48:01 +03:00
}
2002-11-18 22:59:58 +03:00
2002-12-03 22:42:39 +03:00
ads_mod_str ( mem_ctx , mods , SPOOL_REG_PRINTERNAME , printer ) ;
2002-02-11 18:48:01 +03:00
2002-12-03 22:42:39 +03:00
if ( got_dsdriver ) regval_ctr_destroy ( & dsdriver_ctr ) ;
if ( got_dsspooler ) regval_ctr_destroy ( & dsspooler_ctr ) ;
2002-11-18 22:59:58 +03:00
cli_spoolss_close_printer ( cli , mem_ctx , & pol ) ;
2002-02-11 18:48:01 +03:00
2002-11-18 22:59:58 +03:00
return result ;
}
2002-02-01 19:15:53 +03:00
2002-11-18 22:59:58 +03:00
BOOL get_local_printer_publishing_data ( TALLOC_CTX * mem_ctx ,
ADS_MODLIST * mods ,
NT_PRINTER_DATA * data )
{
uint32 key , val ;
for ( key = 0 ; key < data - > num_keys ; key + + ) {
REGVAL_CTR ctr = data - > keys [ key ] . values ;
for ( val = 0 ; val < ctr . num_values ; val + + )
map_regval_to_ads ( mem_ctx , mods , ctr . values [ val ] ) ;
}
return True ;
2002-02-01 19:15:53 +03:00
}
# endif