Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : Main SMB server routines 4 : Copyright (C) Andrew Tridgell 1992-1998 5 : Copyright (C) Martin Pool 2002 6 : Copyright (C) Jelmer Vernooij 2002-2003 7 : Copyright (C) Volker Lendecke 1993-2007 8 : Copyright (C) Jeremy Allison 1993-2007 9 : 10 : This program is free software; you can redistribute it and/or modify 11 : it under the terms of the GNU General Public License as published by 12 : the Free Software Foundation; either version 3 of the License, or 13 : (at your option) any later version. 14 : 15 : This program is distributed in the hope that it will be useful, 16 : but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : GNU General Public License for more details. 19 : 20 : You should have received a copy of the GNU General Public License 21 : along with this program. If not, see <http://www.gnu.org/licenses/>. 22 : */ 23 : 24 : #include "includes.h" 25 : #include "smbd/smbd.h" 26 : #include "smbd/globals.h" 27 : #include "nt_printing.h" 28 : #include "printing/pcap.h" 29 : #include "printing/printer_list.h" 30 : #include "printing/load.h" 31 : #include "auth.h" 32 : #include "messages.h" 33 : #include "lib/param/loadparm.h" 34 : 35 : /* 36 : * The persistent pcap cache is populated by the background print process. Per 37 : * client smbds should only reload their printer share inventories if this 38 : * information has changed. Use reload_last_pcap_time to detect this. 39 : */ 40 : static time_t reload_last_pcap_time = 0; 41 : 42 19183 : bool snum_is_shared_printer(int snum) 43 : { 44 19183 : return (lp_browseable(snum) && lp_snum_ok(snum) && lp_printable(snum)); 45 : } 46 : 47 : /** 48 : * @brief Purge stale printer shares and reload from pre-populated pcap cache. 49 : * 50 : * This function should normally only be called as a callback on a successful 51 : * pcap_cache_reload(), or on client enumeration. 52 : */ 53 1388 : void delete_and_reload_printers(void) 54 : { 55 0 : int n_services; 56 0 : int pnum; 57 0 : int snum; 58 0 : const char *pname; 59 0 : bool ok; 60 0 : time_t pcap_last_update; 61 1388 : TALLOC_CTX *frame = NULL; 62 0 : const struct loadparm_substitution *lp_sub = 63 1388 : loadparm_s3_global_substitution(); 64 : 65 1388 : if (!lp_load_printers()) { 66 0 : DBG_DEBUG("skipping printer reload: disabled\n"); 67 1261 : return; 68 : } 69 : 70 1388 : frame = talloc_stackframe(); 71 1388 : ok = pcap_cache_loaded(&pcap_last_update); 72 1388 : if (!ok) { 73 119 : DEBUG(1, ("pcap cache not loaded\n")); 74 119 : talloc_free(frame); 75 119 : return; 76 : } 77 : 78 1269 : if (reload_last_pcap_time == pcap_last_update) { 79 1142 : DEBUG(5, ("skipping printer reload, already up to date.\n")); 80 1142 : talloc_free(frame); 81 1142 : return; 82 : } 83 127 : reload_last_pcap_time = pcap_last_update; 84 : 85 : /* Get pcap printers updated */ 86 127 : load_printers(); 87 : 88 127 : n_services = lp_numservices(); 89 127 : pnum = lp_servicenumber(PRINTERS_NAME); 90 : 91 127 : DEBUG(10, ("reloading printer services from pcap cache\n")); 92 : 93 : /* 94 : * Add default config for printers added to smb.conf file and remove 95 : * stale printers 96 : */ 97 7260 : for (snum = 0; snum < n_services; snum++) { 98 : /* avoid removing PRINTERS_NAME */ 99 7133 : if (snum == pnum) { 100 0 : continue; 101 : } 102 : 103 : /* skip no-printer services */ 104 7133 : if (!snum_is_shared_printer(snum)) { 105 6577 : continue; 106 : } 107 : 108 556 : pname = lp_printername(frame, lp_sub, snum); 109 : 110 : /* check printer, but avoid removing non-autoloaded printers */ 111 556 : if (lp_autoloaded(snum) && 112 0 : !printer_list_printername_exists(pname)) { 113 0 : lp_killservice(snum); 114 : } 115 : } 116 : 117 : /* Make sure deleted printers are gone */ 118 127 : load_printers(); 119 : 120 127 : talloc_free(frame); 121 : } 122 : 123 : /**************************************************************************** 124 : Reload the services file. 125 : **************************************************************************/ 126 : 127 151760 : bool reload_services(struct smbd_server_connection *sconn, 128 : bool (*snumused) (struct smbd_server_connection *, int), 129 : bool test) 130 : { 131 3821 : const struct loadparm_substitution *lp_sub = 132 151760 : loadparm_s3_global_substitution(); 133 151760 : struct smbXsrv_connection *xconn = NULL; 134 3821 : bool ret; 135 : 136 151760 : if (lp_loaded()) { 137 151760 : char *fname = lp_next_configfile(talloc_tos(), lp_sub); 138 151760 : if (file_exist(fname) && 139 0 : !strcsequal(fname, get_dyn_CONFIGFILE())) { 140 0 : set_dyn_CONFIGFILE(fname); 141 0 : test = False; 142 : } 143 151760 : TALLOC_FREE(fname); 144 : } 145 : 146 151760 : reopen_logs(); 147 : 148 151760 : if (test && !lp_file_list_changed()) 149 146731 : return(True); 150 : 151 1208 : lp_killunused(sconn, snumused); 152 : 153 1208 : ret = lp_load_with_shares(get_dyn_CONFIGFILE()); 154 : 155 : /* perhaps the config filename is now set */ 156 1208 : if (!test) { 157 807 : reload_services(sconn, snumused, true); 158 : } 159 : 160 1208 : reopen_logs(); 161 : 162 1208 : load_interfaces(); 163 : 164 1208 : if (sconn != NULL && sconn->client != NULL) { 165 1088 : xconn = sconn->client->connections; 166 : } 167 2302 : for (;xconn != NULL; xconn = xconn->next) { 168 1094 : set_socket_options(xconn->transport.sock, "SO_KEEPALIVE"); 169 1094 : set_socket_options(xconn->transport.sock, lp_socket_options()); 170 : } 171 : 172 1208 : mangle_reset_cache(); 173 1208 : flush_dfree_cache(); 174 : 175 1208 : return(ret); 176 : }