Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : service (connection) opening and closing
4 : Copyright (C) Andrew Tridgell 1992-1998
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "system/filesys.h"
22 : #include "../lib/tsocket/tsocket.h"
23 : #include "smbd/smbd.h"
24 : #include "smbd/globals.h"
25 : #include "../librpc/gen_ndr/netlogon.h"
26 : #include "../libcli/security/security.h"
27 : #include "printing/pcap.h"
28 : #include "printing/printer_list.h"
29 : #include "passdb/lookup_sid.h"
30 : #include "auth.h"
31 : #include "lib/param/loadparm.h"
32 :
33 20936 : static int load_registry_service(const char *servicename)
34 : {
35 20936 : if (!lp_registry_shares()) {
36 10326 : return -1;
37 : }
38 :
39 9818 : if ((servicename == NULL) || (*servicename == '\0')) {
40 0 : return -1;
41 : }
42 :
43 9818 : if (strequal(servicename, GLOBAL_NAME)) {
44 0 : return -2;
45 : }
46 :
47 9818 : if (!process_registry_service(servicename)) {
48 0 : return -1;
49 : }
50 :
51 9818 : return lp_servicenumber(servicename);
52 : }
53 :
54 216 : void load_registry_shares(void)
55 : {
56 216 : DEBUG(8, ("load_registry_shares()\n"));
57 216 : if (!lp_registry_shares()) {
58 57 : return;
59 : }
60 :
61 159 : process_registry_shares();
62 :
63 159 : return;
64 : }
65 :
66 : /****************************************************************************
67 : Add a home service. Returns the new service number or -1 if fail.
68 : ****************************************************************************/
69 :
70 30006 : int add_home_service(const char *service, const char *username, const char *homedir)
71 : {
72 782 : int iHomeService;
73 :
74 30006 : if (!service || !homedir || homedir[0] == '\0')
75 1421 : return -1;
76 :
77 28575 : if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
78 17457 : if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
79 16685 : return -1;
80 : }
81 : }
82 :
83 : /*
84 : * If this is a winbindd provided username, remove
85 : * the domain component before adding the service.
86 : * Log a warning if the "path=" parameter does not
87 : * include any macros.
88 : */
89 :
90 : {
91 11118 : const char *p = strchr(service,*lp_winbind_separator());
92 :
93 : /* We only want the 'user' part of the string */
94 11118 : if (p) {
95 0 : service = p + 1;
96 : }
97 : }
98 :
99 11118 : if (!lp_add_home(service, iHomeService, username, homedir)) {
100 0 : return -1;
101 : }
102 :
103 11118 : return lp_servicenumber(service);
104 :
105 : }
106 :
107 : /**
108 : * Find a service entry.
109 : *
110 : * @param service is modified (to canonical form??)
111 : **/
112 :
113 103874 : int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
114 : {
115 1639 : const struct loadparm_substitution *lp_sub =
116 103874 : loadparm_s3_global_substitution();
117 1639 : int iService;
118 :
119 103874 : if (!service_in) {
120 8 : return -1;
121 : }
122 :
123 : /* First make a copy. */
124 103866 : *p_service_out = talloc_strdup(ctx, service_in);
125 103866 : if (!*p_service_out) {
126 0 : return -1;
127 : }
128 :
129 103866 : all_string_sub(*p_service_out,"\\","/",0);
130 :
131 103866 : iService = lp_servicenumber(*p_service_out);
132 :
133 : /*
134 : * check for whether the service is a registry share before
135 : * handling home directories. This is to ensure that
136 : * that in the case service name is identical to a user's
137 : * home directory, the explicit service is preferred.
138 : */
139 103866 : if (iService < 0) {
140 2044 : iService = load_registry_service(*p_service_out);
141 : }
142 :
143 : /* now handle the special case of a home directory */
144 103866 : if (iService < 0) {
145 1435 : char *phome_dir = get_user_home_dir(ctx, *p_service_out);
146 :
147 1435 : if(!phome_dir) {
148 : /*
149 : * Try mapping the servicename, it may
150 : * be a Windows to unix mapped user name.
151 : */
152 1427 : if(map_username(ctx, *p_service_out, p_service_out)) {
153 0 : if (*p_service_out == NULL) {
154 : /* Out of memory. */
155 0 : return -1;
156 : }
157 0 : phome_dir = get_user_home_dir(
158 : ctx, *p_service_out);
159 : }
160 : }
161 :
162 1435 : DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,
163 : phome_dir?phome_dir:"(NULL)"));
164 :
165 1435 : if (!strequal(phome_dir, "/")) {
166 1431 : iService = add_home_service(*p_service_out,
167 : *p_service_out, /* username */
168 : phome_dir);
169 : }
170 : }
171 :
172 : /* If we still don't have a service, attempt to add it as a printer. */
173 103866 : if (iService < 0) {
174 10 : int iPrinterService;
175 :
176 1435 : if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
177 1435 : iPrinterService = load_registry_service(PRINTERS_NAME);
178 : }
179 1435 : if (iPrinterService >= 0) {
180 0 : DEBUG(3,("checking whether %s is a valid printer name...\n",
181 : *p_service_out));
182 0 : if (printer_list_printername_exists(*p_service_out)) {
183 0 : DEBUG(3,("%s is a valid printer name\n",
184 : *p_service_out));
185 0 : DEBUG(3,("adding %s as a printer service\n",
186 : *p_service_out));
187 0 : lp_add_printer(*p_service_out, iPrinterService);
188 0 : iService = lp_servicenumber(*p_service_out);
189 0 : if (iService < 0) {
190 0 : DEBUG(0,("failed to add %s as a printer service!\n",
191 : *p_service_out));
192 : }
193 : } else {
194 0 : DEBUG(3,("%s is not a valid printer name\n",
195 : *p_service_out));
196 : }
197 : }
198 : }
199 :
200 : /* Is it a usershare service ? */
201 103866 : if (iService < 0 && *lp_usershare_path(talloc_tos(), lp_sub)) {
202 : /* Ensure the name is canonicalized. */
203 1435 : if (!strlower_m(*p_service_out)) {
204 0 : goto fail;
205 : }
206 1435 : iService = load_usershare_service(*p_service_out);
207 : }
208 :
209 : /* just possibly it's a default service? */
210 103866 : if (iService < 0) {
211 1433 : char *pdefservice = lp_defaultservice(talloc_tos(), lp_sub);
212 1433 : if (pdefservice &&
213 1433 : *pdefservice &&
214 0 : !strequal(pdefservice, *p_service_out)
215 0 : && !strstr_m(*p_service_out,"..")) {
216 : /*
217 : * We need to do a local copy here as lp_defaultservice()
218 : * returns one of the rotating lp_string buffers that
219 : * could get overwritten by the recursive find_service() call
220 : * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
221 : */
222 0 : char *defservice = talloc_strdup(ctx, pdefservice);
223 :
224 0 : if (!defservice) {
225 0 : goto fail;
226 : }
227 :
228 : /* Disallow anything except explicit share names. */
229 0 : if (strequal(defservice,HOMES_NAME) ||
230 0 : strequal(defservice, PRINTERS_NAME) ||
231 0 : strequal(defservice, "IPC$")) {
232 0 : TALLOC_FREE(defservice);
233 0 : goto fail;
234 : }
235 :
236 0 : iService = find_service(ctx, defservice, p_service_out);
237 0 : if (!*p_service_out) {
238 0 : TALLOC_FREE(defservice);
239 0 : iService = -1;
240 0 : goto fail;
241 : }
242 0 : if (iService >= 0) {
243 0 : all_string_sub(*p_service_out, "_","/",0);
244 0 : iService = lp_add_service(*p_service_out, iService);
245 : }
246 0 : TALLOC_FREE(defservice);
247 : }
248 : }
249 :
250 103866 : if (iService >= 0) {
251 102433 : if (!VALID_SNUM(iService)) {
252 0 : DEBUG(0,("Invalid snum %d for %s\n",iService,
253 : *p_service_out));
254 0 : iService = -1;
255 : }
256 : }
257 :
258 103866 : fail:
259 :
260 103866 : if (iService < 0) {
261 1433 : DEBUG(3,("find_service() failed to find service %s\n",
262 : *p_service_out));
263 : }
264 :
265 102227 : return (iService);
266 : }
267 :
268 70653 : bool lp_allow_local_address(
269 : int snum, const struct tsocket_address *local_address)
270 : {
271 70653 : bool is_inet = tsocket_address_is_inet(local_address, "ip");
272 70653 : const char **server_addresses = lp_server_addresses(snum);
273 70653 : char *local = NULL;
274 765 : ssize_t i;
275 :
276 70653 : if (!is_inet) {
277 0 : return false;
278 : }
279 :
280 70653 : if (server_addresses == NULL) {
281 69727 : return true;
282 : }
283 :
284 161 : local = tsocket_address_inet_addr_string(local_address, talloc_tos());
285 161 : if (local == NULL) {
286 0 : return false;
287 : }
288 :
289 318 : for (i=0; server_addresses[i] != NULL; i++) {
290 161 : struct tsocket_address *server_addr = NULL;
291 161 : char *server_addr_string = NULL;
292 0 : bool equal;
293 0 : int ret;
294 :
295 : /*
296 : * Go through struct tsocket_address to normalize the
297 : * string representation
298 : */
299 :
300 161 : ret = tsocket_address_inet_from_strings(
301 : talloc_tos(),
302 : "ip",
303 : server_addresses[i],
304 : 0,
305 : &server_addr);
306 161 : if (ret == -1) {
307 0 : DBG_WARNING("tsocket_address_inet_from_strings "
308 : "failed for %s: %s, ignoring\n",
309 : server_addresses[i],
310 : strerror(errno));
311 0 : continue;
312 : }
313 :
314 161 : server_addr_string = tsocket_address_inet_addr_string(
315 : server_addr, talloc_tos());
316 161 : TALLOC_FREE(server_addr);
317 161 : if (server_addr_string == NULL) {
318 0 : DBG_ERR("tsocket_address_inet_addr_string failed "
319 : "for %s, ignoring\n",
320 : server_addresses[i]);
321 0 : continue;
322 : }
323 :
324 161 : equal = strequal(local, server_addr_string);
325 161 : TALLOC_FREE(server_addr_string);
326 :
327 161 : if (equal) {
328 4 : TALLOC_FREE(local);
329 4 : return true;
330 : }
331 : }
332 :
333 157 : TALLOC_FREE(local);
334 157 : return false;
335 : }
|