root/source4/smb_server/tcon.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smbsrv_get_my_addr
  2. smbsrv_get_peer_addr
  3. smbsrv_init_tcons
  4. smbsrv_smb_init_tcons
  5. smbsrv_smb2_init_tcons
  6. smbsrv_tcon_find
  7. smbsrv_smb_tcon_find
  8. smbsrv_smb2_tcon_find
  9. smbsrv_tcon_destructor
  10. smbsrv_tcon_new
  11. smbsrv_smb_tcon_new
  12. smbsrv_smb2_tcon_new

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    Manage smbsrv_tcon structures
   4    Copyright (C) Andrew Tridgell 1998
   5    Copyright (C) Alexander Bokovoy 2002
   6    Copyright (C) Stefan Metzmacher 2005-2006
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "../lib/util/dlinklist.h"
  24 #include "smb_server/smb_server.h"
  25 #include "smbd/service_stream.h"
  26 #include "ntvfs/ntvfs.h"
  27 
  28 struct socket_address *smbsrv_get_my_addr(void *p, TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  29 {
  30         struct smbsrv_connection *smb_conn = talloc_get_type(p,
  31                                              struct smbsrv_connection);
  32 
  33         return socket_get_my_addr(smb_conn->connection->socket, mem_ctx);
  34 }
  35 
  36 struct socket_address *smbsrv_get_peer_addr(void *p, TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  37 {
  38         struct smbsrv_connection *smb_conn = talloc_get_type(p,
  39                                              struct smbsrv_connection);
  40 
  41         return socket_get_peer_addr(smb_conn->connection->socket, mem_ctx);
  42 }
  43 
  44 /****************************************************************************
  45 init the tcon structures
  46 ****************************************************************************/
  47 static NTSTATUS smbsrv_init_tcons(struct smbsrv_tcons_context *tcons_ctx, TALLOC_CTX *mem_ctx, uint32_t limit)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49         /* 
  50          * the idr_* functions take 'int' as limit,
  51          * and only work with a max limit 0x00FFFFFF
  52          */
  53         limit &= 0x00FFFFFF;
  54 
  55         tcons_ctx->idtree_tid   = idr_init(mem_ctx);
  56         NT_STATUS_HAVE_NO_MEMORY(tcons_ctx->idtree_tid);
  57         tcons_ctx->idtree_limit = limit;
  58         tcons_ctx->list         = NULL;
  59 
  60         return NT_STATUS_OK;
  61 }
  62 
  63 NTSTATUS smbsrv_smb_init_tcons(struct smbsrv_connection *smb_conn)
     /* [<][>][^][v][top][bottom][index][help] */
  64 {
  65         return smbsrv_init_tcons(&smb_conn->smb_tcons, smb_conn, UINT16_MAX);
  66 }
  67 
  68 NTSTATUS smbsrv_smb2_init_tcons(struct smbsrv_session *smb_sess)
     /* [<][>][^][v][top][bottom][index][help] */
  69 {
  70         return smbsrv_init_tcons(&smb_sess->smb2_tcons, smb_sess, UINT32_MAX);
  71 }
  72 
  73 /****************************************************************************
  74 find a tcon given a tid for SMB
  75 ****************************************************************************/
  76 static struct smbsrv_tcon *smbsrv_tcon_find(struct smbsrv_tcons_context *tcons_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  77                                             uint32_t tid, struct timeval request_time)
  78 {
  79         void *p;
  80         struct smbsrv_tcon *tcon;
  81 
  82         if (tid == 0) return NULL;
  83 
  84         if (tid > tcons_ctx->idtree_limit) return NULL;
  85 
  86         p = idr_find(tcons_ctx->idtree_tid, tid);
  87         if (!p) return NULL;
  88 
  89         tcon = talloc_get_type(p, struct smbsrv_tcon);
  90         if (!tcon) return NULL;
  91 
  92         tcon->statistics.last_request_time = request_time;
  93 
  94         return tcon;
  95 }
  96 
  97 struct smbsrv_tcon *smbsrv_smb_tcon_find(struct smbsrv_connection *smb_conn,
     /* [<][>][^][v][top][bottom][index][help] */
  98                                          uint32_t tid, struct timeval request_time)
  99 {
 100         return smbsrv_tcon_find(&smb_conn->smb_tcons, tid, request_time);
 101 }
 102 
 103 struct smbsrv_tcon *smbsrv_smb2_tcon_find(struct smbsrv_session *smb_sess,
     /* [<][>][^][v][top][bottom][index][help] */
 104                                           uint32_t tid, struct timeval request_time)
 105 {
 106         if (!smb_sess) return NULL;
 107         return smbsrv_tcon_find(&smb_sess->smb2_tcons, tid, request_time);
 108 }
 109 
 110 /*
 111   destroy a connection structure
 112 */
 113 static int smbsrv_tcon_destructor(struct smbsrv_tcon *tcon)
     /* [<][>][^][v][top][bottom][index][help] */
 114 {
 115         struct smbsrv_tcons_context *tcons_ctx;
 116         struct socket_address *client_addr;
 117 
 118         client_addr = socket_get_peer_addr(tcon->smb_conn->connection->socket, tcon);
 119         DEBUG(3,("%s closed connection to service %s\n",
 120                  client_addr ? client_addr->addr : "(unknown)",
 121                  tcon->share_name));
 122 
 123         /* tell the ntvfs backend that we are disconnecting */
 124         if (tcon->ntvfs) {
 125                 ntvfs_disconnect(tcon->ntvfs);
 126                 tcon->ntvfs = NULL;
 127         }
 128 
 129         if (tcon->smb2.session) {
 130                 tcons_ctx = &tcon->smb2.session->smb2_tcons;
 131         } else {
 132                 tcons_ctx = &tcon->smb_conn->smb_tcons;
 133         }
 134 
 135         idr_remove(tcons_ctx->idtree_tid, tcon->tid);
 136         DLIST_REMOVE(tcons_ctx->list, tcon);
 137         return 0;
 138 }
 139 
 140 /*
 141   find first available connection slot
 142 */
 143 static struct smbsrv_tcon *smbsrv_tcon_new(struct smbsrv_connection *smb_conn,
     /* [<][>][^][v][top][bottom][index][help] */
 144                                            struct smbsrv_session *smb_sess,
 145                                            const char *share_name)
 146 {
 147         TALLOC_CTX *mem_ctx;
 148         struct smbsrv_tcons_context *tcons_ctx;
 149         uint32_t handle_uint_max;
 150         struct smbsrv_tcon *tcon;
 151         NTSTATUS status;
 152         int i;
 153 
 154         if (smb_sess) {
 155                 mem_ctx = smb_sess;
 156                 tcons_ctx = &smb_sess->smb2_tcons;
 157                 handle_uint_max = UINT32_MAX;
 158         } else {
 159                 mem_ctx = smb_conn;
 160                 tcons_ctx = &smb_conn->smb_tcons;
 161                 handle_uint_max = UINT16_MAX;
 162         }
 163 
 164         tcon = talloc_zero(mem_ctx, struct smbsrv_tcon);
 165         if (!tcon) return NULL;
 166         tcon->smb_conn          = smb_conn;
 167         tcon->smb2.session      = smb_sess;
 168         tcon->share_name        = talloc_strdup(tcon, share_name);
 169         if (!tcon->share_name) goto failed;
 170 
 171         /*
 172          * the use -1 here, because we don't want to give away the wildcard
 173          * fnum used in SMBflush
 174          */
 175         status = smbsrv_init_handles(tcon, handle_uint_max - 1);
 176         if (!NT_STATUS_IS_OK(status)) {
 177                 DEBUG(1,("ERROR! failed to init handles: %s\n", nt_errstr(status)));
 178                 goto failed;
 179         }
 180 
 181         i = idr_get_new_random(tcons_ctx->idtree_tid, tcon, tcons_ctx->idtree_limit);
 182         if (i == -1) {
 183                 DEBUG(1,("ERROR! Out of connection structures\n"));
 184                 goto failed;
 185         }
 186         tcon->tid = i;
 187 
 188         DLIST_ADD(tcons_ctx->list, tcon);
 189         talloc_set_destructor(tcon, smbsrv_tcon_destructor);
 190 
 191         /* now fill in some statistics */
 192         tcon->statistics.connect_time = timeval_current();
 193 
 194         return tcon;
 195 
 196 failed:
 197         talloc_free(tcon);
 198         return NULL;
 199 }
 200 
 201 struct smbsrv_tcon *smbsrv_smb_tcon_new(struct smbsrv_connection *smb_conn, const char *share_name)
     /* [<][>][^][v][top][bottom][index][help] */
 202 {
 203         return smbsrv_tcon_new(smb_conn, NULL, share_name);
 204 }
 205 
 206 struct smbsrv_tcon *smbsrv_smb2_tcon_new(struct smbsrv_session *smb_sess, const char *share_name)
     /* [<][>][^][v][top][bottom][index][help] */
 207 {
 208         return smbsrv_tcon_new(smb_sess->smb_conn, smb_sess, share_name);
 209 }

/* [<][>][^][v][top][bottom][index][help] */