/src/samba/source3/smbd/server_reload.c
Line | Count | Source |
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 | | bool snum_is_shared_printer(int snum) |
43 | 0 | { |
44 | 0 | return (lp_browseable(snum) && lp_snum_ok(snum) && lp_printable(snum)); |
45 | 0 | } |
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 | | void delete_and_reload_printers(void) |
54 | 0 | { |
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 | 0 | TALLOC_CTX *frame = NULL; |
62 | 0 | const struct loadparm_substitution *lp_sub = |
63 | 0 | loadparm_s3_global_substitution(); |
64 | |
|
65 | 0 | if (!lp_load_printers()) { |
66 | 0 | DBG_DEBUG("skipping printer reload: disabled\n"); |
67 | 0 | return; |
68 | 0 | } |
69 | | |
70 | 0 | frame = talloc_stackframe(); |
71 | 0 | ok = pcap_cache_loaded(&pcap_last_update); |
72 | 0 | if (!ok) { |
73 | 0 | DEBUG(1, ("pcap cache not loaded\n")); |
74 | 0 | talloc_free(frame); |
75 | 0 | return; |
76 | 0 | } |
77 | | |
78 | 0 | if (reload_last_pcap_time == pcap_last_update) { |
79 | 0 | DEBUG(5, ("skipping printer reload, already up to date.\n")); |
80 | 0 | talloc_free(frame); |
81 | 0 | return; |
82 | 0 | } |
83 | 0 | reload_last_pcap_time = pcap_last_update; |
84 | | |
85 | | /* Get pcap printers updated */ |
86 | 0 | load_printers(); |
87 | |
|
88 | 0 | n_services = lp_numservices(); |
89 | 0 | pnum = lp_servicenumber(PRINTERS_NAME); |
90 | |
|
91 | 0 | 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 | 0 | for (snum = 0; snum < n_services; snum++) { |
98 | | /* avoid removing PRINTERS_NAME */ |
99 | 0 | if (snum == pnum) { |
100 | 0 | continue; |
101 | 0 | } |
102 | | |
103 | | /* skip no-printer services */ |
104 | 0 | if (!snum_is_shared_printer(snum)) { |
105 | 0 | continue; |
106 | 0 | } |
107 | | |
108 | 0 | pname = lp_printername(frame, lp_sub, snum); |
109 | | |
110 | | /* check printer, but avoid removing non-autoloaded printers */ |
111 | 0 | if (lp_autoloaded(snum) && |
112 | 0 | !printer_list_printername_exists(pname)) { |
113 | 0 | lp_killservice(snum); |
114 | 0 | } |
115 | 0 | } |
116 | | |
117 | | /* Make sure deleted printers are gone */ |
118 | 0 | load_printers(); |
119 | |
|
120 | 0 | talloc_free(frame); |
121 | 0 | } |
122 | | |
123 | | /**************************************************************************** |
124 | | Reload the services file. |
125 | | **************************************************************************/ |
126 | | |
127 | | bool reload_services(struct smbd_server_connection *sconn, |
128 | | bool (*snumused) (struct smbd_server_connection *, int), |
129 | | bool test) |
130 | 0 | { |
131 | 0 | const struct loadparm_substitution *lp_sub = |
132 | 0 | loadparm_s3_global_substitution(); |
133 | 0 | struct smbXsrv_connection *xconn = NULL; |
134 | 0 | bool ret; |
135 | |
|
136 | 0 | if (lp_loaded()) { |
137 | 0 | char *fname = lp_next_configfile(talloc_tos(), lp_sub); |
138 | 0 | if (file_exist(fname) && |
139 | 0 | !strcsequal(fname, get_dyn_CONFIGFILE())) { |
140 | 0 | set_dyn_CONFIGFILE(fname); |
141 | 0 | test = False; |
142 | 0 | } |
143 | 0 | TALLOC_FREE(fname); |
144 | 0 | } |
145 | |
|
146 | 0 | reopen_logs(); |
147 | |
|
148 | 0 | if (test && !lp_file_list_changed()) |
149 | 0 | return(True); |
150 | | |
151 | 0 | lp_killunused(sconn, snumused); |
152 | |
|
153 | 0 | ret = lp_load_with_shares(get_dyn_CONFIGFILE()); |
154 | | |
155 | | /* perhaps the config filename is now set */ |
156 | 0 | if (!test) { |
157 | 0 | reload_services(sconn, snumused, true); |
158 | 0 | } |
159 | |
|
160 | 0 | reopen_logs(); |
161 | |
|
162 | 0 | load_interfaces(); |
163 | |
|
164 | 0 | if (sconn != NULL && sconn->client != NULL) { |
165 | 0 | xconn = sconn->client->connections; |
166 | 0 | } |
167 | 0 | for (;xconn != NULL; xconn = xconn->next) { |
168 | 0 | set_socket_options(xconn->transport.sock, "SO_KEEPALIVE"); |
169 | 0 | set_socket_options(xconn->transport.sock, lp_socket_options()); |
170 | 0 | } |
171 | |
|
172 | 0 | mangle_reset_cache(); |
173 | 0 | flush_dfree_cache(); |
174 | |
|
175 | 0 | return(ret); |
176 | 0 | } |