LCOV - code coverage report
Current view: top level - source3/param - service.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 58 98 59.2 %
Date: 2021-09-23 10:06:22 Functions: 4 4 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       18474 : static int load_registry_service(const char *servicename)
      34             : {
      35       18474 :         if (!lp_registry_shares()) {
      36        9702 :                 return -1;
      37             :         }
      38             : 
      39        8232 :         if ((servicename == NULL) || (*servicename == '\0')) {
      40           0 :                 return -1;
      41             :         }
      42             : 
      43        8232 :         if (strequal(servicename, GLOBAL_NAME)) {
      44           0 :                 return -2;
      45             :         }
      46             : 
      47        8232 :         if (!process_registry_service(servicename)) {
      48           0 :                 return -1;
      49             :         }
      50             : 
      51        8232 :         return lp_servicenumber(servicename);
      52             : }
      53             : 
      54         196 : void load_registry_shares(void)
      55             : {
      56         196 :         DEBUG(8, ("load_registry_shares()\n"));
      57         196 :         if (!lp_registry_shares()) {
      58          57 :                 return;
      59             :         }
      60             : 
      61         139 :         process_registry_shares();
      62             : 
      63         139 :         return;
      64             : }
      65             : 
      66             : /****************************************************************************
      67             :  Add a home service. Returns the new service number or -1 if fail.
      68             : ****************************************************************************/
      69             : 
      70       26030 : int add_home_service(const char *service, const char *username, const char *homedir)
      71             : {
      72             :         int iHomeService;
      73             : 
      74       26030 :         if (!service || !homedir || homedir[0] == '\0')
      75        1371 :                 return -1;
      76             : 
      77       24649 :         if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
      78       15682 :                 if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
      79       15162 :                         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        8967 :                 const char *p = strchr(service,*lp_winbind_separator());
      92             : 
      93             :                 /* We only want the 'user' part of the string */
      94        8967 :                 if (p) {
      95           0 :                         service = p + 1;
      96             :                 }
      97             :         }
      98             : 
      99        8967 :         if (!lp_add_home(service, iHomeService, username, homedir)) {
     100           0 :                 return -1;
     101             :         }
     102             : 
     103        8967 :         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       87542 : int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
     114             : {
     115       79083 :         const struct loadparm_substitution *lp_sub =
     116        8459 :                 loadparm_s3_global_substitution();
     117             :         int iService;
     118             : 
     119       87542 :         if (!service_in) {
     120           6 :                 return -1;
     121             :         }
     122             : 
     123             :         /* First make a copy. */
     124       87536 :         *p_service_out = talloc_strdup(ctx, service_in);
     125       87536 :         if (!*p_service_out) {
     126           0 :                 return -1;
     127             :         }
     128             : 
     129       87536 :         all_string_sub(*p_service_out,"\\","/",0);
     130             : 
     131       87536 :         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       87536 :         if (iService < 0) {
     140        1407 :                 iService = load_registry_service(*p_service_out);
     141             :         }
     142             : 
     143             :         /* now handle the special case of a home directory */
     144       87536 :         if (iService < 0) {
     145        1385 :                 char *phome_dir = get_user_home_dir(ctx, *p_service_out);
     146             : 
     147        1385 :                 if(!phome_dir) {
     148             :                         /*
     149             :                          * Try mapping the servicename, it may
     150             :                          * be a Windows to unix mapped user name.
     151             :                          */
     152        1377 :                         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        1385 :                 DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,
     163             :                         phome_dir?phome_dir:"(NULL)"));
     164             : 
     165        1385 :                 if (!strequal(phome_dir, "/")) {
     166        1381 :                         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       87536 :         if (iService < 0) {
     174             :                 int iPrinterService;
     175             : 
     176        1385 :                 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
     177        1385 :                         iPrinterService = load_registry_service(PRINTERS_NAME);
     178             :                 }
     179        1385 :                 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       87536 :         if (iService < 0 && *lp_usershare_path(talloc_tos(), lp_sub)) {
     202             :                 /* Ensure the name is canonicalized. */
     203        1385 :                 if (!strlower_m(*p_service_out)) {
     204           0 :                         goto fail;
     205             :                 }
     206        1385 :                 iService = load_usershare_service(*p_service_out);
     207             :         }
     208             : 
     209             :         /* just possibly it's a default service? */
     210       87536 :         if (iService < 0) {
     211        1383 :                 char *pdefservice = lp_defaultservice(talloc_tos(), lp_sub);
     212        2291 :                 if (pdefservice &&
     213        1383 :                                 *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       87536 :         if (iService >= 0) {
     251       86153 :                 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      165438 :   fail:
     259             : 
     260       87536 :         if (iService < 0) {
     261        1383 :                 DEBUG(3,("find_service() failed to find service %s\n",
     262             :                         *p_service_out));
     263             :         }
     264             : 
     265       86361 :         return (iService);
     266             : }

Generated by: LCOV version 1.13