LCOV - code coverage report
Current view: top level - source3/param - service.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 86 134 64.2 %
Date: 2024-04-21 15:09:00 Functions: 5 5 100.0 %

          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             : }

Generated by: LCOV version 1.14