LCOV - code coverage report
Current view: top level - source3/libsmb - libsmb_cache.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 84 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB client library implementation (server cache)
       4             :    Copyright (C) Andrew Tridgell 1998
       5             :    Copyright (C) Richard Sharpe 2000
       6             :    Copyright (C) John Terpstra 2000
       7             :    Copyright (C) Tom Jansen (Ninja ISD) 2002
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "libsmb/libsmb.h"
      25             : #include "libsmbclient.h"
      26             : #include "libsmb_internal.h"
      27             : 
      28             : /*
      29             :  * Structure we use if internal caching mechanism is used
      30             :  * nothing fancy here.
      31             :  */
      32             : struct smbc_server_cache {
      33             :         char *server_name;
      34             :         char *share_name;
      35             :         char *workgroup;
      36             :         char *username;
      37             :         SMBCSRV *server;
      38             : 
      39             :         struct smbc_server_cache *next, *prev;
      40             : };
      41             : 
      42             : 
      43             : 
      44             : /*
      45             :  * Add a new connection to the server cache.
      46             :  * This function is only used if the external cache is not enabled
      47             :  */
      48             : int
      49           0 : SMBC_add_cached_server(SMBCCTX * context,
      50             :                        SMBCSRV * newsrv,
      51             :                        const char * server,
      52             :                        const char * share,
      53             :                        const char * workgroup,
      54             :                        const char * username)
      55             : {
      56           0 :         struct smbc_server_cache * srvcache = NULL;
      57             : 
      58           0 :         if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) {
      59           0 :                 errno = ENOMEM;
      60           0 :                 DEBUG(3, ("Not enough space for server cache allocation\n"));
      61           0 :                 return 1;
      62             :         }
      63             : 
      64           0 :         ZERO_STRUCTP(srvcache);
      65             : 
      66           0 :         srvcache->server = newsrv;
      67             : 
      68           0 :         srvcache->server_name = SMB_STRDUP(server);
      69           0 :         if (!srvcache->server_name) {
      70           0 :                 errno = ENOMEM;
      71           0 :                 goto failed;
      72             :         }
      73             : 
      74           0 :         srvcache->share_name = SMB_STRDUP(share);
      75           0 :         if (!srvcache->share_name) {
      76           0 :                 errno = ENOMEM;
      77           0 :                 goto failed;
      78             :         }
      79             : 
      80           0 :         srvcache->workgroup = SMB_STRDUP(workgroup);
      81           0 :         if (!srvcache->workgroup) {
      82           0 :                 errno = ENOMEM;
      83           0 :                 goto failed;
      84             :         }
      85             : 
      86           0 :         srvcache->username = SMB_STRDUP(username);
      87           0 :         if (!srvcache->username) {
      88           0 :                 errno = ENOMEM;
      89           0 :                 goto failed;
      90             :         }
      91             : 
      92           0 :         DLIST_ADD(context->internal->server_cache, srvcache);
      93           0 :         return 0;
      94             : 
      95           0 : failed:
      96           0 :         SAFE_FREE(srvcache->server_name);
      97           0 :         SAFE_FREE(srvcache->share_name);
      98           0 :         SAFE_FREE(srvcache->workgroup);
      99           0 :         SAFE_FREE(srvcache->username);
     100           0 :         SAFE_FREE(srvcache);
     101             : 
     102           0 :         return 1;
     103             : }
     104             : 
     105             : 
     106             : 
     107             : /*
     108             :  * Search the server cache for a server
     109             :  * returns server handle on success, NULL on error (not found)
     110             :  * This function is only used if the external cache is not enabled
     111             :  */
     112             : SMBCSRV *
     113           0 : SMBC_get_cached_server(SMBCCTX * context,
     114             :                        const char * server,
     115             :                        const char * share,
     116             :                        const char * workgroup,
     117             :                        const char * user)
     118             : {
     119           0 :         struct smbc_server_cache * srv = NULL;
     120             : 
     121             :         /* Search the cache lines */
     122           0 :         for (srv = context->internal->server_cache; srv; srv = srv->next) {
     123             : 
     124           0 :                 if (strcmp(server,srv->server_name)  == 0 &&
     125           0 :                     strcmp(workgroup,srv->workgroup) == 0 &&
     126           0 :                     strcmp(user, srv->username)  == 0) {
     127             : 
     128             :                         /* If the share name matches, we're cool */
     129           0 :                         if (strcmp(share, srv->share_name) == 0) {
     130           0 :                                 return srv->server;
     131             :                         }
     132             : 
     133             :                         /*
     134             :                          * We only return an empty share name or the attribute
     135             :                          * server on an exact match (which would have been
     136             :                          * caught above).
     137             :                          */
     138           0 :                         if (*share == '\0' || strcmp(share, "*IPC$") == 0)
     139           0 :                                 continue;
     140             : 
     141             :                         /*
     142             :                          * Never return an empty share name or the attribute
     143             :                          * server if it wasn't what was requested.
     144             :                          */
     145           0 :                         if (*srv->share_name == '\0' ||
     146           0 :                             strcmp(srv->share_name, "*IPC$") == 0)
     147           0 :                                 continue;
     148             : 
     149             :                         /*
     150             :                          * If we're only allowing one share per server, then
     151             :                          * a connection to the server (other than the
     152             :                          * attribute server connection) is cool.
     153             :                          */
     154           0 :                         if (smbc_getOptionOneSharePerServer(context)) {
     155             :                                 NTSTATUS status;
     156             :                                 /*
     157             :                                  * The currently connected share name
     158             :                                  * doesn't match the requested share, so
     159             :                                  * disconnect from the current share.
     160             :                                  */
     161           0 :                                 status = cli_tdis(srv->server->cli);
     162           0 :                                 if (!NT_STATUS_IS_OK(status)) {
     163             :                                         /* Sigh. Couldn't disconnect. */
     164           0 :                                         cli_shutdown(srv->server->cli);
     165           0 :                                         srv->server->cli = NULL;
     166           0 :                                         smbc_getFunctionRemoveCachedServer(context)(context, srv->server);
     167           0 :                                         continue;
     168             :                                 }
     169             : 
     170             :                                 /*
     171             :                                  * Save the new share name.  We've
     172             :                                  * disconnected from the old share, and are
     173             :                                  * about to connect to the new one.
     174             :                                  */
     175           0 :                                 SAFE_FREE(srv->share_name);
     176           0 :                                 srv->share_name = SMB_STRDUP(share);
     177           0 :                                 if (!srv->share_name) {
     178             :                                         /* Out of memory. */
     179           0 :                                         cli_shutdown(srv->server->cli);
     180           0 :                                         srv->server->cli = NULL;
     181           0 :                                         smbc_getFunctionRemoveCachedServer(context)(context, srv->server);
     182           0 :                                         continue;
     183             :                                 }
     184             : 
     185           0 :                                 return srv->server;
     186             :                         }
     187             :                 }
     188             :         }
     189             : 
     190           0 :         return NULL;
     191             : }
     192             : 
     193             : 
     194             : /*
     195             :  * Search the server cache for a server and remove it
     196             :  * returns 0 on success
     197             :  * This function is only used if the external cache is not enabled
     198             :  */
     199             : int
     200           0 : SMBC_remove_cached_server(SMBCCTX * context,
     201             :                           SMBCSRV * server)
     202             : {
     203           0 :         struct smbc_server_cache * srv = NULL;
     204             : 
     205           0 :         for (srv = context->internal->server_cache; srv; srv = srv->next) {
     206           0 :                 if (server == srv->server) {
     207             : 
     208             :                         /* remove this sucker */
     209           0 :                         DLIST_REMOVE(context->internal->server_cache, srv);
     210           0 :                         SAFE_FREE(srv->server_name);
     211           0 :                         SAFE_FREE(srv->share_name);
     212           0 :                         SAFE_FREE(srv->workgroup);
     213           0 :                         SAFE_FREE(srv->username);
     214           0 :                         SAFE_FREE(srv);
     215           0 :                         return 0;
     216             :                 }
     217             :         }
     218             :         /* server not found */
     219           0 :         return 1;
     220             : }
     221             : 
     222             : 
     223             : /*
     224             :  * Try to remove all the servers in cache
     225             :  * returns 1 on failure and 0 if all servers could be removed.
     226             :  */
     227             : int
     228           0 : SMBC_purge_cached_servers(SMBCCTX * context)
     229             : {
     230             :         struct smbc_server_cache * srv;
     231             :         struct smbc_server_cache * next;
     232           0 :         int could_not_purge_all = 0;
     233             : 
     234           0 :         for (srv = context->internal->server_cache,
     235           0 :                      next = (srv ? srv->next :NULL);
     236           0 :              srv;
     237           0 :              srv = next,
     238           0 :                      next = (srv ? srv->next : NULL)) {
     239             : 
     240           0 :                 if (SMBC_remove_unused_server(context, srv->server)) {
     241             :                         /* could not be removed */
     242           0 :                         could_not_purge_all = 1;
     243             :                 }
     244             :         }
     245           0 :         return could_not_purge_all;
     246             : }

Generated by: LCOV version 1.13