2010-05-27 09:18:58 +04:00
/*
Unix SMB / CIFS implementation .
Main SMB server routines
Copyright ( C ) Andrew Tridgell 1992 - 1998
Copyright ( C ) Martin Pool 2002
Copyright ( C ) Jelmer Vernooij 2002 - 2003
Copyright ( C ) Volker Lendecke 1993 - 2007
Copyright ( C ) Jeremy Allison 1993 - 2007
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"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2010-05-27 09:18:58 +04:00
# include "smbd/globals.h"
2010-07-31 02:47:20 +04:00
# include "nt_printing.h"
2010-12-19 21:52:08 +03:00
# include "printing/pcap.h"
2011-02-22 21:24:31 +03:00
# include "printing/load.h"
2011-03-24 15:46:20 +03:00
# include "auth.h"
2011-03-24 17:31:06 +03:00
# include "messages.h"
2011-06-29 09:33:54 +04:00
# include "lib/param/loadparm.h"
2010-05-27 09:18:58 +04:00
2012-02-10 17:00:05 +04:00
static bool snum_is_shared_printer ( int snum )
{
2014-02-02 17:48:41 +04:00
return ( lp_browseable ( snum ) & & lp_snum_ok ( snum ) & & lp_printable ( snum ) ) ;
2012-02-10 17:00:05 +04:00
}
2011-09-05 16:35:55 +04:00
/**
* @ brief Purge stale printers and reload from pre - populated pcap cache .
*
* This function should normally only be called as a callback on a successful
* pcap_cache_reload ( ) or after a MSG_PRINTER_CAP message is received .
*
* This function can cause DELETION of printers and drivers from our registry ,
* so calling it on a failed pcap reload may REMOVE permanently all printers
* and drivers .
*
* @ param [ in ] ev The event context .
*
* @ param [ in ] msg_ctx The messaging context .
*/
void delete_and_reload_printers ( struct tevent_context * ev ,
struct messaging_context * msg_ctx )
2010-05-27 09:18:58 +04:00
{
2011-07-18 07:06:47 +04:00
struct auth_session_info * session_info = NULL ;
2010-04-27 01:34:24 +04:00
struct spoolss_PrinterInfo2 * pinfo2 = NULL ;
2012-02-07 14:41:54 +04:00
int n_services ;
int pnum ;
2010-05-27 09:18:58 +04:00
int snum ;
const char * pname ;
2012-02-07 14:41:54 +04:00
const char * sname ;
2010-04-27 01:34:24 +04:00
NTSTATUS status ;
2010-05-27 09:18:58 +04:00
2012-02-07 14:41:54 +04:00
/* Get pcap printers updated */
load_printers ( ev , msg_ctx ) ;
n_services = lp_numservices ( ) ;
pnum = lp_servicenumber ( PRINTERS_NAME ) ;
2010-12-19 21:52:08 +03:00
DEBUG ( 10 , ( " reloading printer services from pcap cache \n " ) ) ;
2010-05-27 09:18:58 +04:00
2011-02-21 12:25:52 +03:00
status = make_session_info_system ( talloc_tos ( ) , & session_info ) ;
2010-04-27 01:34:24 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-08-10 15:45:55 +04:00
DEBUG ( 3 , ( " reload_printers: "
2011-02-21 12:25:52 +03:00
" Could not create system session_info \n " ) ) ;
2010-04-27 01:34:24 +04:00
/* can't remove stale printers before we
* are fully initilized */
2012-02-07 14:41:54 +04:00
return ;
2010-04-27 01:34:24 +04:00
}
2012-02-07 14:41:54 +04:00
/*
* Add default config for printers added to smb . conf file and remove
* stale printers
*/
for ( snum = 0 ; snum < n_services ; snum + + ) {
/* avoid removing PRINTERS_NAME */
if ( snum = = pnum ) {
continue ;
}
/* skip no-printer services */
2012-02-10 17:00:05 +04:00
if ( ! snum_is_shared_printer ( snum ) ) {
2010-05-27 09:18:58 +04:00
continue ;
2012-02-07 14:41:54 +04:00
}
2010-05-27 09:18:58 +04:00
2012-02-07 14:41:54 +04:00
sname = lp_const_servicename ( snum ) ;
2012-07-18 09:37:23 +04:00
pname = lp_printername ( session_info , snum ) ;
2012-02-07 14:41:54 +04:00
/* check printer, but avoid removing non-autoloaded printers */
2012-08-28 16:17:22 +04:00
if ( lp_autoloaded ( snum ) & & ! pcap_printername_ok ( pname ) ) {
2010-05-27 09:18:58 +04:00
DEBUG ( 3 , ( " removing stale printer %s \n " , pname ) ) ;
2011-02-21 12:25:52 +03:00
if ( is_printer_published ( session_info , session_info ,
2010-08-08 17:02:29 +04:00
msg_ctx ,
2012-07-18 09:37:23 +04:00
NULL ,
lp_servicename ( session_info ,
snum ) ,
2013-05-29 12:43:33 +04:00
& pinfo2 ) ) {
2011-02-21 12:25:52 +03:00
nt_printer_publish ( session_info ,
session_info ,
2010-08-08 17:02:29 +04:00
msg_ctx ,
2010-08-08 16:35:50 +04:00
pinfo2 ,
2010-04-27 01:34:24 +04:00
DSPRINT_UNPUBLISH ) ;
TALLOC_FREE ( pinfo2 ) ;
}
2011-02-21 12:25:52 +03:00
nt_printer_remove ( session_info , session_info , msg_ctx ,
2010-08-08 17:02:29 +04:00
pname ) ;
2010-05-27 09:18:58 +04:00
lp_killservice ( snum ) ;
2012-02-07 14:41:54 +04:00
} else {
DEBUG ( 8 , ( " Adding default registry entry for printer "
" [%s], if it doesn't exist. \n " , sname ) ) ;
nt_printer_add ( session_info , session_info , msg_ctx ,
sname ) ;
2010-05-27 09:18:58 +04:00
}
}
2012-02-07 14:41:54 +04:00
/* Make sure deleted printers are gone */
2010-12-19 21:52:08 +03:00
load_printers ( ev , msg_ctx ) ;
2010-04-27 01:34:24 +04:00
2011-02-21 12:25:52 +03:00
TALLOC_FREE ( session_info ) ;
2010-05-27 09:18:58 +04:00
}
/****************************************************************************
Reload the services file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-12-14 16:25:20 +04:00
bool reload_services ( struct smbd_server_connection * sconn ,
bool ( * snumused ) ( struct smbd_server_connection * , int ) ,
2010-08-15 18:13:00 +04:00
bool test )
2010-05-27 09:18:58 +04:00
{
2014-05-22 01:23:34 +04:00
struct smbXsrv_connection * xconn = NULL ;
2010-05-27 09:18:58 +04:00
bool ret ;
2014-05-22 01:23:34 +04:00
if ( sconn ! = NULL ) {
xconn = sconn - > conn ;
}
2010-05-27 09:18:58 +04:00
if ( lp_loaded ( ) ) {
2014-01-15 08:29:57 +04:00
char * fname = lp_next_configfile ( talloc_tos ( ) ) ;
2010-05-27 09:18:58 +04:00
if ( file_exist ( fname ) & &
! strcsequal ( fname , get_dyn_CONFIGFILE ( ) ) ) {
set_dyn_CONFIGFILE ( fname ) ;
test = False ;
}
2012-06-01 02:06:58 +04:00
TALLOC_FREE ( fname ) ;
2010-05-27 09:18:58 +04:00
}
reopen_logs ( ) ;
if ( test & & ! lp_file_list_changed ( ) )
return ( True ) ;
2011-12-14 16:25:20 +04:00
lp_killunused ( sconn , snumused ) ;
2010-05-27 09:18:58 +04:00
2012-05-04 20:00:15 +04:00
ret = lp_load ( get_dyn_CONFIGFILE ( ) ,
false , /* global only */
false , /* save defaults */
true , /* add_ipc */
true ) ; /* initialize globals */
2010-05-27 09:18:58 +04:00
/* perhaps the config filename is now set */
2011-12-14 16:25:20 +04:00
if ( ! test ) {
reload_services ( sconn , snumused , true ) ;
}
2010-05-27 09:18:58 +04:00
reopen_logs ( ) ;
load_interfaces ( ) ;
2014-05-22 01:23:34 +04:00
if ( xconn ! = NULL ) {
set_socket_options ( xconn - > transport . sock , " SO_KEEPALIVE " ) ;
set_socket_options ( xconn - > transport . sock , lp_socket_options ( ) ) ;
2010-05-27 09:18:58 +04:00
}
mangle_reset_cache ( ) ;
reset_stat_cache ( ) ;
/* this forces service parameters to be flushed */
set_current_service ( NULL , 0 , True ) ;
return ( ret ) ;
}