Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/conn.c

    r596 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   Manage connections_struct structures
    44   Copyright (C) Andrew Tridgell 1998
    55   Copyright (C) Alexander Bokovoy 2002
    6    
     6   Copyright (C) Jeremy Allison 2010
     7
    78   This program is free software; you can redistribute it and/or modify
    89   it under the terms of the GNU General Public License as published by
    910   the Free Software Foundation; either version 3 of the License, or
    1011   (at your option) any later version.
    11    
     12
    1213   This program is distributed in the hope that it will be useful,
    1314   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1415   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1516   GNU General Public License for more details.
    16    
     17
    1718   You should have received a copy of the GNU General Public License
    1819   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2021
    2122#include "includes.h"
     23#include "smbd/smbd.h"
    2224#include "smbd/globals.h"
     25#include "rpc_server/rpc_ncacn_np.h"
    2326
    2427/* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The
     
    2629 * the "max connections" limit, looong before that.
    2730 */
     31
    2832#define BITMAP_BLOCK_SZ 128
    2933
    3034/****************************************************************************
    31 init the conn structures
    32 ****************************************************************************/
     35 Init the conn structures.
     36****************************************************************************/
     37
    3338void conn_init(struct smbd_server_connection *sconn)
    3439{
    3540        sconn->smb1.tcons.Connections = NULL;
    36         sconn->smb1.tcons.num_open = 0;
    37         sconn->smb1.tcons.bmap = bitmap_allocate(BITMAP_BLOCK_SZ);
    38 }
    39 
    40 /****************************************************************************
    41 return the number of open connections
    42 ****************************************************************************/
     41        sconn->smb1.tcons.bmap = bitmap_talloc(sconn, BITMAP_BLOCK_SZ);
     42}
     43
     44/****************************************************************************
     45 Return the number of open connections.
     46****************************************************************************/
     47
    4348int conn_num_open(struct smbd_server_connection *sconn)
    4449{
    45         return sconn->smb1.tcons.num_open;
    46 }
    47 
    48 
    49 /****************************************************************************
    50 check if a snum is in use
    51 ****************************************************************************/
     50        return sconn->num_tcons_open;
     51}
     52
     53/****************************************************************************
     54 Check if a snum is in use.
     55****************************************************************************/
     56
    5257bool conn_snum_used(int snum)
    5358{
    5459        struct smbd_server_connection *sconn = smbd_server_conn;
    55         connection_struct *conn;
    56         for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
    57                 if (conn->params->service == snum) {
    58                         return(True);
    59                 }
    60         }
    61         return(False);
     60
     61        if (sconn->using_smb2) {
     62                /* SMB2 */
     63                struct smbd_smb2_session *sess;
     64                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     65                        struct smbd_smb2_tcon *ptcon;
     66
     67                        for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
     68                                if (ptcon->compat_conn &&
     69                                                ptcon->compat_conn->params &&
     70                                                (ptcon->compat_conn->params->service = snum)) {
     71                                        return true;
     72                                }
     73                        }
     74                }
     75        } else {
     76                /* SMB1 */
     77                connection_struct *conn;
     78                for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
     79                        if (conn->params->service == snum) {
     80                                return true;
     81                        }
     82                }
     83        }
     84        return false;
    6285}
    6386
     
    6891connection_struct *conn_find(struct smbd_server_connection *sconn,unsigned cnum)
    6992{
    70         int count=0;
    71         connection_struct *conn;
    72 
    73         for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) {
    74                 if (conn->cnum == cnum) {
    75                         if (count > 10) {
    76                                 DLIST_PROMOTE(sconn->smb1.tcons.Connections,
    77                                               conn);
    78                         }
    79                         return conn;
     93        if (sconn->using_smb2) {
     94                /* SMB2 */
     95                struct smbd_smb2_session *sess;
     96                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     97                        struct smbd_smb2_tcon *ptcon;
     98
     99                        for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
     100                                if (ptcon->compat_conn &&
     101                                                ptcon->compat_conn->cnum == cnum) {
     102                                        return ptcon->compat_conn;
     103                                }
     104                        }
     105                }
     106        } else {
     107                /* SMB1 */
     108                int count=0;
     109                connection_struct *conn;
     110                for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next,count++) {
     111                        if (conn->cnum == cnum) {
     112                                if (count > 10) {
     113                                        DLIST_PROMOTE(sconn->smb1.tcons.Connections,
     114                                                conn);
     115                                }
     116                                return conn;
     117                        }
    80118                }
    81119        }
     
    85123
    86124/****************************************************************************
    87   find first available connection slot, starting from a random position.
    88 The randomisation stops problems with the server dieing and clients
    89 thinking the server is still available.
    90 ****************************************************************************/
     125 Find first available connection slot, starting from a random position.
     126 The randomisation stops problems with the server dieing and clients
     127 thinking the server is still available.
     128****************************************************************************/
     129
    91130connection_struct *conn_new(struct smbd_server_connection *sconn)
    92131{
     
    95134        int find_offset = 1;
    96135
    97         if (sconn->allow_smb2) {
     136        if (sconn->using_smb2) {
     137                /* SMB2 */
    98138                if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
    99139                    !(conn->params = TALLOC_P(conn, struct share_params))) {
     
    106146        }
    107147
     148        /* SMB1 */
    108149find_again:
    109150        i = bitmap_find(sconn->smb1.tcons.bmap, find_offset);
    110        
     151
    111152        if (i == -1) {
    112153                /* Expand the connections bitmap. */
     
    125166                        oldsz, newsz));
    126167
    127                 nbmap = bitmap_allocate(newsz);
     168                nbmap = bitmap_talloc(sconn, newsz);
    128169                if (!nbmap) {
    129170                        DEBUG(0,("ERROR! malloc fail.\n"));
     
    132173
    133174                bitmap_copy(nbmap, sconn->smb1.tcons.bmap);
    134                 bitmap_free(sconn->smb1.tcons.bmap);
     175                TALLOC_FREE(sconn->smb1.tcons.bmap);
    135176
    136177                sconn->smb1.tcons.bmap = nbmap;
     
    162203        bitmap_set(sconn->smb1.tcons.bmap, i);
    163204
    164         sconn->smb1.tcons.num_open++;
     205        sconn->num_tcons_open++;
    165206
    166207        string_set(&conn->connectpath,"");
    167208        string_set(&conn->origpath,"");
    168        
     209
    169210        DLIST_ADD(sconn->smb1.tcons.Connections, conn);
    170211
     
    174215/****************************************************************************
    175216 Close all conn structures.
    176 return true if any were closed
    177 ****************************************************************************/
     217 Return true if any were closed.
     218****************************************************************************/
     219
    178220bool conn_close_all(struct smbd_server_connection *sconn)
    179221{
    180         connection_struct *conn, *next;
    181222        bool ret = false;
    182         for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
    183                 next=conn->next;
    184                 set_current_service(conn, 0, True);
    185                 close_cnum(conn, conn->vuid);
    186                 ret = true;
     223        if (sconn->using_smb2) {
     224                /* SMB2 */
     225                struct smbd_smb2_session *sess;
     226                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     227                        struct smbd_smb2_tcon *tcon, *tc_next;
     228
     229                        for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
     230                                tc_next = tcon->next;
     231                                TALLOC_FREE(tcon);
     232                                ret = true;
     233                        }
     234                }
     235        } else {
     236                /* SMB1 */
     237                connection_struct *conn, *next;
     238
     239                for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
     240                        next=conn->next;
     241                        set_current_service(conn, 0, True);
     242                        close_cnum(conn, conn->vuid);
     243                        ret = true;
     244                }
    187245        }
    188246        return ret;
     
    190248
    191249/****************************************************************************
     250 Update last used timestamps.
     251****************************************************************************/
     252
     253static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
     254{
     255        if (sconn->using_smb2) {
     256                /* SMB2 */
     257                struct smbd_smb2_session *sess;
     258                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     259                        struct smbd_smb2_tcon *ptcon;
     260
     261                        for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
     262                                connection_struct *conn = ptcon->compat_conn;
     263                                /* Update if connection wasn't idle. */
     264                                if (conn && conn->lastused != conn->lastused_count) {
     265                                        conn->lastused = t;
     266                                        conn->lastused_count = t;
     267                                }
     268                        }
     269                }
     270        } else {
     271                /* SMB1 */
     272                connection_struct *conn;
     273                for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
     274                        /* Update if connection wasn't idle. */
     275                        if (conn->lastused != conn->lastused_count) {
     276                                conn->lastused = t;
     277                                conn->lastused_count = t;
     278                        }
     279                }
     280        }
     281}
     282
     283/****************************************************************************
    192284 Idle inactive connections.
    193285****************************************************************************/
    194286
    195 bool conn_idle_all(struct smbd_server_connection *sconn,time_t t)
     287bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
    196288{
    197289        int deadtime = lp_deadtime()*60;
    198         pipes_struct *plist = NULL;
    199         connection_struct *conn;
    200         bool ret = true;
    201 
    202         if (deadtime <= 0)
     290
     291        conn_lastused_update(sconn, t);
     292
     293        if (deadtime <= 0) {
    203294                deadtime = DEFAULT_SMBD_TIMEOUT;
    204 
    205         for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
    206 
    207                 time_t age = t - conn->lastused;
    208 
    209                 /* Update if connection wasn't idle. */
    210                 if (conn->lastused != conn->lastused_count) {
    211                         conn->lastused = t;
    212                         conn->lastused_count = t;
    213                         age = 0;
    214                 }
    215 
    216                 /* close dirptrs on connections that are idle */
    217                 if (age > DPTR_IDLE_TIMEOUT) {
    218                         dptr_idlecnum(conn);
    219                 }
    220 
    221                 if (conn->num_files_open > 0 || age < deadtime) {
    222                         ret = false;
     295        }
     296
     297        if (sconn->using_smb2) {
     298                /* SMB2 */
     299                struct smbd_smb2_session *sess;
     300                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     301                        struct smbd_smb2_tcon *ptcon;
     302
     303                        for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
     304                                time_t age;
     305                                connection_struct *conn = ptcon->compat_conn;
     306
     307                                if (conn == NULL) {
     308                                        continue;
     309                                }
     310
     311                                age = t - conn->lastused;
     312                                /* close dirptrs on connections that are idle */
     313                                if (age > DPTR_IDLE_TIMEOUT) {
     314                                        dptr_idlecnum(conn);
     315                                }
     316
     317                                if (conn->num_files_open > 0 || age < deadtime) {
     318                                        return false;
     319                                }
     320                        }
     321                }
     322        } else {
     323                /* SMB1 */
     324                connection_struct *conn;
     325                for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
     326                        time_t age = t - conn->lastused;
     327
     328                        /* close dirptrs on connections that are idle */
     329                        if (age > DPTR_IDLE_TIMEOUT) {
     330                                dptr_idlecnum(conn);
     331                        }
     332
     333                        if (conn->num_files_open > 0 || age < deadtime) {
     334                                return false;
     335                        }
    223336                }
    224337        }
     
    228341         * idle with a handle open.
    229342         */
    230 
    231         for (plist = get_first_internal_pipe(); plist;
    232              plist = get_next_internal_pipe(plist)) {
    233                 if (num_pipe_handles(plist->pipe_handles) != 0) {
    234                         ret = false;
    235                         break;
    236                 }
    237         }
    238        
    239         return ret;
     343        if (check_open_pipes()) {
     344                return false;
     345        }
     346
     347        return true;
    240348}
    241349
     
    248356        connection_struct *conn;
    249357
    250         for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
    251                 if (conn->vuid == vuid) {
    252                         conn->vuid = UID_FIELD_INVALID;
    253                 }
    254                 conn_clear_vuid_cache(conn, vuid);
     358        if (sconn->using_smb2) {
     359                /* SMB2 */
     360                struct smbd_smb2_session *sess;
     361                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     362                        struct smbd_smb2_tcon *ptcon;
     363
     364                        for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
     365                                if (ptcon->compat_conn) {
     366                                        if (ptcon->compat_conn->vuid == vuid) {
     367                                                ptcon->compat_conn->vuid = UID_FIELD_INVALID;
     368                                        }
     369                                        conn_clear_vuid_cache(ptcon->compat_conn, vuid);
     370                                }
     371                        }
     372                }
     373        } else {
     374                /* SMB1 */
     375                for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
     376                        if (conn->vuid == vuid) {
     377                                conn->vuid = UID_FIELD_INVALID;
     378                        }
     379                        conn_clear_vuid_cache(conn, vuid);
     380                }
    255381        }
    256382}
     
    286412        free_namearray(conn->veto_oplock_list);
    287413        free_namearray(conn->aio_write_behind_list);
    288        
     414
    289415        string_free(&conn->connectpath);
    290416        string_free(&conn->origpath);
     
    305431        }
    306432
    307         if (conn->sconn->allow_smb2) {
     433        if (conn->sconn->using_smb2) {
     434                /* SMB2 */
    308435                conn_free_internal(conn);
    309436                return;
    310437        }
    311438
     439        /* SMB1 */
    312440        DLIST_REMOVE(conn->sconn->smb1.tcons.Connections, conn);
    313441
    314         bitmap_clear(conn->sconn->smb1.tcons.bmap, conn->cnum);
    315 
    316         SMB_ASSERT(conn->sconn->smb1.tcons.num_open > 0);
    317         conn->sconn->smb1.tcons.num_open--;
     442        if (conn->sconn->smb1.tcons.bmap != NULL) {
     443                /*
     444                 * Can be NULL for fake connections created by
     445                 * create_conn_struct()
     446                 */
     447                bitmap_clear(conn->sconn->smb1.tcons.bmap, conn->cnum);
     448        }
     449
     450        SMB_ASSERT(conn->sconn->num_tcons_open > 0);
     451        conn->sconn->num_tcons_open--;
    318452
    319453        conn_free_internal(conn);
    320454}
    321  
    322 /****************************************************************************
    323 receive a smbcontrol message to forcibly unmount a share
    324 the message contains just a share name and all instances of that
    325 share are unmounted
    326 the special sharename '*' forces unmount of all shares
    327 ****************************************************************************/
     455
     456/****************************************************************************
     457 Receive a smbcontrol message to forcibly unmount a share.
     458 The message contains just a share name and all instances of that
     459 share are unmounted.
     460 The special sharename '*' forces unmount of all shares.
     461****************************************************************************/
     462
    328463void msg_force_tdis(struct messaging_context *msg,
    329464                    void *private_data,
     
    332467                    DATA_BLOB *data)
    333468{
    334         struct smbd_server_connection *sconn = smbd_server_conn;
     469        struct smbd_server_connection *sconn;
    335470        connection_struct *conn, *next;
    336471        fstring sharename;
     472
     473        sconn = msg_ctx_to_sconn(msg);
     474        if (sconn == NULL) {
     475                DEBUG(1, ("could not find sconn\n"));
     476                return;
     477        }
    337478
    338479        fstrcpy(sharename, (const char *)data->data);
     
    344485        }
    345486
    346         for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
    347                 next=conn->next;
    348                 if (strequal(lp_servicename(SNUM(conn)), sharename)) {
    349                         DEBUG(1,("Forcing close of share %s cnum=%d\n",
    350                                  sharename, conn->cnum));
    351                         close_cnum(conn, (uint16)-1);
    352                 }
    353         }
    354 }
     487        if (sconn->using_smb2) {
     488                /* SMB2 */
     489                struct smbd_smb2_session *sess;
     490                for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
     491                        struct smbd_smb2_tcon *tcon, *tc_next;
     492
     493                        for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
     494                                tc_next = tcon->next;
     495                                if (tcon->compat_conn &&
     496                                                strequal(lp_servicename(SNUM(tcon->compat_conn)),
     497                                                                sharename)) {
     498                                        DEBUG(1,("Forcing close of share %s cnum=%d\n",
     499                                                sharename, tcon->compat_conn->cnum));
     500                                        TALLOC_FREE(tcon);
     501                                }
     502                        }
     503                }
     504        } else {
     505                /* SMB1 */
     506                for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
     507                        next=conn->next;
     508                        if (strequal(lp_servicename(SNUM(conn)), sharename)) {
     509                                DEBUG(1,("Forcing close of share %s cnum=%d\n",
     510                                        sharename, conn->cnum));
     511                                close_cnum(conn, (uint16)-1);
     512                        }
     513                }
     514        }
     515}
Note: See TracChangeset for help on using the changeset viewer.