smbd: Remove references to get_Protocol()
[Samba.git] / source3 / param / service.c
blobb06a2fbc734fbb50c1ce447c1e787cd76c9bb1d1
1 /*
2 Unix SMB/CIFS implementation.
3 service (connection) opening and closing
4 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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/>.
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"
33 static int load_registry_service(const char *servicename)
35 if (!lp_registry_shares()) {
36 return -1;
39 if ((servicename == NULL) || (*servicename == '\0')) {
40 return -1;
43 if (strequal(servicename, GLOBAL_NAME)) {
44 return -2;
47 if (!process_registry_service(servicename)) {
48 return -1;
51 return lp_servicenumber(servicename);
54 void load_registry_shares(void)
56 DEBUG(8, ("load_registry_shares()\n"));
57 if (!lp_registry_shares()) {
58 return;
61 process_registry_shares();
63 return;
66 /****************************************************************************
67 Add a home service. Returns the new service number or -1 if fail.
68 ****************************************************************************/
70 int add_home_service(const char *service, const char *username, const char *homedir)
72 int iHomeService;
74 if (!service || !homedir || homedir[0] == '\0')
75 return -1;
77 if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
78 if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
79 return -1;
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.
91 const char *p = strchr(service,*lp_winbind_separator());
93 /* We only want the 'user' part of the string */
94 if (p) {
95 service = p + 1;
99 if (!lp_add_home(service, iHomeService, username, homedir)) {
100 return -1;
103 return lp_servicenumber(service);
108 * Find a service entry.
110 * @param service is modified (to canonical form??)
113 int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
115 const struct loadparm_substitution *lp_sub =
116 loadparm_s3_global_substitution();
117 int iService;
119 if (!service_in) {
120 return -1;
123 /* First make a copy. */
124 *p_service_out = talloc_strdup(ctx, service_in);
125 if (!*p_service_out) {
126 return -1;
129 all_string_sub(*p_service_out,"\\","/",0);
131 iService = lp_servicenumber(*p_service_out);
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.
139 if (iService < 0) {
140 iService = load_registry_service(*p_service_out);
143 /* now handle the special case of a home directory */
144 if (iService < 0) {
145 char *phome_dir = get_user_home_dir(ctx, *p_service_out);
147 if(!phome_dir) {
149 * Try mapping the servicename, it may
150 * be a Windows to unix mapped user name.
152 if(map_username(ctx, *p_service_out, p_service_out)) {
153 if (*p_service_out == NULL) {
154 /* Out of memory. */
155 return -1;
157 phome_dir = get_user_home_dir(
158 ctx, *p_service_out);
162 DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,
163 phome_dir?phome_dir:"(NULL)"));
165 if (!strequal(phome_dir, "/")) {
166 iService = add_home_service(*p_service_out,
167 *p_service_out, /* username */
168 phome_dir);
172 /* If we still don't have a service, attempt to add it as a printer. */
173 if (iService < 0) {
174 int iPrinterService;
176 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
177 iPrinterService = load_registry_service(PRINTERS_NAME);
179 if (iPrinterService >= 0) {
180 DEBUG(3,("checking whether %s is a valid printer name...\n",
181 *p_service_out));
182 if (printer_list_printername_exists(*p_service_out)) {
183 DEBUG(3,("%s is a valid printer name\n",
184 *p_service_out));
185 DEBUG(3,("adding %s as a printer service\n",
186 *p_service_out));
187 lp_add_printer(*p_service_out, iPrinterService);
188 iService = lp_servicenumber(*p_service_out);
189 if (iService < 0) {
190 DEBUG(0,("failed to add %s as a printer service!\n",
191 *p_service_out));
193 } else {
194 DEBUG(3,("%s is not a valid printer name\n",
195 *p_service_out));
200 /* Is it a usershare service ? */
201 if (iService < 0 && *lp_usershare_path(talloc_tos(), lp_sub)) {
202 /* Ensure the name is canonicalized. */
203 if (!strlower_m(*p_service_out)) {
204 goto fail;
206 iService = load_usershare_service(*p_service_out);
209 /* just possibly it's a default service? */
210 if (iService < 0) {
211 char *pdefservice = lp_defaultservice(talloc_tos(), lp_sub);
212 if (pdefservice &&
213 *pdefservice &&
214 !strequal(pdefservice, *p_service_out)
215 && !strstr_m(*p_service_out,"..")) {
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>.
222 char *defservice = talloc_strdup(ctx, pdefservice);
224 if (!defservice) {
225 goto fail;
228 /* Disallow anything except explicit share names. */
229 if (strequal(defservice,HOMES_NAME) ||
230 strequal(defservice, PRINTERS_NAME) ||
231 strequal(defservice, "IPC$")) {
232 TALLOC_FREE(defservice);
233 goto fail;
236 iService = find_service(ctx, defservice, p_service_out);
237 if (!*p_service_out) {
238 TALLOC_FREE(defservice);
239 iService = -1;
240 goto fail;
242 if (iService >= 0) {
243 all_string_sub(*p_service_out, "_","/",0);
244 iService = lp_add_service(*p_service_out, iService);
246 TALLOC_FREE(defservice);
250 if (iService >= 0) {
251 if (!VALID_SNUM(iService)) {
252 DEBUG(0,("Invalid snum %d for %s\n",iService,
253 *p_service_out));
254 iService = -1;
258 fail:
260 if (iService < 0) {
261 DEBUG(3,("find_service() failed to find service %s\n",
262 *p_service_out));
265 return (iService);
268 bool lp_allow_local_address(
269 int snum, const struct tsocket_address *local_address)
271 bool is_inet = tsocket_address_is_inet(local_address, "ip");
272 const char **server_addresses = lp_server_addresses(snum);
273 char *local = NULL;
274 ssize_t i;
276 if (!is_inet) {
277 return false;
280 if (server_addresses == NULL) {
281 return true;
284 local = tsocket_address_inet_addr_string(local_address, talloc_tos());
285 if (local == NULL) {
286 return false;
289 for (i=0; server_addresses[i] != NULL; i++) {
290 struct tsocket_address *server_addr = NULL;
291 char *server_addr_string = NULL;
292 bool equal;
293 int ret;
296 * Go through struct tsocket_address to normalize the
297 * string representation
300 ret = tsocket_address_inet_from_strings(
301 talloc_tos(),
302 "ip",
303 server_addresses[i],
305 &server_addr);
306 if (ret == -1) {
307 DBG_WARNING("tsocket_address_inet_from_strings "
308 "failed for %s: %s, ignoring\n",
309 server_addresses[i],
310 strerror(errno));
311 continue;
314 server_addr_string = tsocket_address_inet_addr_string(
315 server_addr, talloc_tos());
316 TALLOC_FREE(server_addr);
317 if (server_addr_string == NULL) {
318 DBG_ERR("tsocket_address_inet_addr_string failed "
319 "for %s, ignoring\n",
320 server_addresses[i]);
321 continue;
324 equal = strequal(local, server_addr_string);
325 TALLOC_FREE(server_addr_string);
327 if (equal) {
328 TALLOC_FREE(local);
329 return true;
333 TALLOC_FREE(local);
334 return false;