s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[nivanova/samba-autobuild/.git] / source3 / smbd / conn.c
index 16a0ee053e90807974d35fabc4c2965f60513356..a3f66b36be7f5b50e614354edcf3aca544c9e57a 100644 (file)
@@ -53,10 +53,9 @@ int conn_num_open(struct smbd_server_connection *sconn)
  Check if a snum is in use.
 ****************************************************************************/
 
-bool conn_snum_used(int snum)
+bool conn_snum_used(struct smbd_server_connection *sconn,
+                   int snum)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
-
        if (sconn->using_smb2) {
                /* SMB2 */
                struct smbd_smb2_session *sess;
@@ -134,8 +133,8 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
 
        if (sconn->using_smb2) {
                /* SMB2 */
-               if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
-                   !(conn->params = TALLOC_P(conn, struct share_params))) {
+               if (!(conn=talloc_zero(NULL, connection_struct)) ||
+                   !(conn->params = talloc(conn, struct share_params))) {
                        DEBUG(0,("TALLOC_ZERO() failed!\n"));
                        TALLOC_FREE(conn);
                        return NULL;
@@ -189,8 +188,8 @@ find_again:
                return NULL;
        }
 
-       if (!(conn=TALLOC_ZERO_P(NULL, connection_struct)) ||
-           !(conn->params = TALLOC_P(conn, struct share_params))) {
+       if (!(conn=talloc_zero(NULL, connection_struct)) ||
+           !(conn->params = talloc(conn, struct share_params))) {
                DEBUG(0,("TALLOC_ZERO() failed!\n"));
                TALLOC_FREE(conn);
                return NULL;
@@ -212,142 +211,52 @@ find_again:
 }
 
 /****************************************************************************
- Close all conn structures.
- Return true if any were closed.
-****************************************************************************/
-
-bool conn_close_all(struct smbd_server_connection *sconn)
-{
-       bool ret = false;
-       if (sconn->using_smb2) {
-               /* SMB2 */
-               struct smbd_smb2_session *sess;
-               for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
-                       struct smbd_smb2_tcon *tcon, *tc_next;
-
-                       for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
-                               tc_next = tcon->next;
-                               TALLOC_FREE(tcon);
-                               ret = true;
-                       }
-               }
-       } else {
-               /* SMB1 */
-               connection_struct *conn, *next;
-
-               for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
-                       next=conn->next;
-                       set_current_service(conn, 0, True);
-                       close_cnum(conn, conn->vuid);
-                       ret = true;
-               }
-       }
-       return ret;
-}
-
-/****************************************************************************
- Update last used timestamps.
-****************************************************************************/
-
-static void conn_lastused_update(struct smbd_server_connection *sconn,time_t t)
-{
-       if (sconn->using_smb2) {
-               /* SMB2 */
-               struct smbd_smb2_session *sess;
-               for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
-                       struct smbd_smb2_tcon *ptcon;
-
-                       for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
-                               connection_struct *conn = ptcon->compat_conn;
-                               /* Update if connection wasn't idle. */
-                               if (conn && conn->lastused != conn->lastused_count) {
-                                       conn->lastused = t;
-                                       conn->lastused_count = t;
-                               }
-                       }
-               }
-       } else {
-               /* SMB1 */
-               connection_struct *conn;
-               for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
-                       /* Update if connection wasn't idle. */
-                       if (conn->lastused != conn->lastused_count) {
-                               conn->lastused = t;
-                               conn->lastused_count = t;
-                       }
-               }
-       }
-}
-
-/****************************************************************************
- Idle inactive connections.
+ Clear a vuid out of the connection's vuid cache
 ****************************************************************************/
 
-bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
+static void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
 {
-       int deadtime = lp_deadtime()*60;
-
-       conn_lastused_update(sconn, t);
-
-       if (deadtime <= 0) {
-               deadtime = DEFAULT_SMBD_TIMEOUT;
-       }
-
-       if (sconn->using_smb2) {
-               /* SMB2 */
-               struct smbd_smb2_session *sess;
-               for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
-                       struct smbd_smb2_tcon *ptcon;
-
-                       for (ptcon = sess->tcons.list; ptcon; ptcon = ptcon->next) {
-                               time_t age;
-                               connection_struct *conn = ptcon->compat_conn;
-
-                               if (conn == NULL) {
-                                       continue;
-                               }
-
-                               age = t - conn->lastused;
-                               /* close dirptrs on connections that are idle */
-                               if (age > DPTR_IDLE_TIMEOUT) {
-                                       dptr_idlecnum(conn);
-                               }
-
-                               if (conn->num_files_open > 0 || age < deadtime) {
-                                       return false;
-                               }
-                       }
-               }
-       } else {
-               /* SMB1 */
-               connection_struct *conn;
-               for (conn=sconn->smb1.tcons.Connections;conn;conn=conn->next) {
-                       time_t age = t - conn->lastused;
-
-                       /* close dirptrs on connections that are idle */
-                       if (age > DPTR_IDLE_TIMEOUT) {
-                               dptr_idlecnum(conn);
-                       }
+       int i;
 
-                       if (conn->num_files_open > 0 || age < deadtime) {
-                               return false;
+       for (i=0; i<VUID_CACHE_SIZE; i++) {
+               struct vuid_cache_entry *ent;
+
+               ent = &conn->vuid_cache.array[i];
+
+               if (ent->vuid == vuid) {
+                       ent->vuid = UID_FIELD_INVALID;
+                       /*
+                        * We need to keep conn->session_info around
+                        * if it's equal to ent->session_info as a SMBulogoff
+                        * is often followed by a SMBtdis (with an invalid
+                        * vuid). The debug code (or regular code in
+                        * vfs_full_audit) wants to refer to the
+                        * conn->session_info pointer to print debug
+                        * statements. Theoretically this is a bug,
+                        * as once the vuid is gone the session_info
+                        * on the conn struct isn't valid any more,
+                        * but there's enough code that assumes
+                        * conn->session_info is never null that
+                        * it's easier to hold onto the old pointer
+                        * until we get a new sessionsetupX.
+                        * As everything is hung off the
+                        * conn pointer as a talloc context we're not
+                        * leaking memory here. See bug #6315. JRA.
+                        */
+                       if (conn->session_info == ent->session_info) {
+                               ent->session_info = NULL;
+                       } else {
+                               TALLOC_FREE(ent->session_info);
                        }
+                       ent->read_only = False;
                }
        }
-
-       /*
-        * Check all pipes for any open handles. We cannot
-        * idle with a handle open.
-        */
-       if (check_open_pipes()) {
-               return false;
-       }
-
-       return true;
 }
 
 /****************************************************************************
  Clear a vuid out of the validity cache, and as the 'owner' of a connection.
+
+ Called from invalidate_vuid()
 ****************************************************************************/
 
 void conn_clear_vuid_caches(struct smbd_server_connection *sconn,uint16_t vuid)
@@ -451,64 +360,3 @@ void conn_free(connection_struct *conn)
 
        conn_free_internal(conn);
 }
-
-/****************************************************************************
- Receive a smbcontrol message to forcibly unmount a share.
- The message contains just a share name and all instances of that
- share are unmounted.
- The special sharename '*' forces unmount of all shares.
-****************************************************************************/
-
-void msg_force_tdis(struct messaging_context *msg,
-                   void *private_data,
-                   uint32_t msg_type,
-                   struct server_id server_id,
-                   DATA_BLOB *data)
-{
-       struct smbd_server_connection *sconn;
-       connection_struct *conn, *next;
-       fstring sharename;
-
-       sconn = msg_ctx_to_sconn(msg);
-       if (sconn == NULL) {
-               DEBUG(1, ("could not find sconn\n"));
-               return;
-       }
-
-       fstrcpy(sharename, (const char *)data->data);
-
-       if (strcmp(sharename, "*") == 0) {
-               DEBUG(1,("Forcing close of all shares\n"));
-               conn_close_all(sconn);
-               return;
-       }
-
-       if (sconn->using_smb2) {
-               /* SMB2 */
-               struct smbd_smb2_session *sess;
-               for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
-                       struct smbd_smb2_tcon *tcon, *tc_next;
-
-                       for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
-                               tc_next = tcon->next;
-                               if (tcon->compat_conn &&
-                                               strequal(lp_servicename(SNUM(tcon->compat_conn)),
-                                                               sharename)) {
-                                       DEBUG(1,("Forcing close of share %s cnum=%d\n",
-                                               sharename, tcon->compat_conn->cnum));
-                                       TALLOC_FREE(tcon);
-                               }
-                       }
-               }
-       } else {
-               /* SMB1 */
-               for (conn=sconn->smb1.tcons.Connections;conn;conn=next) {
-                       next=conn->next;
-                       if (strequal(lp_servicename(SNUM(conn)), sharename)) {
-                               DEBUG(1,("Forcing close of share %s cnum=%d\n",
-                                       sharename, conn->cnum));
-                               close_cnum(conn, (uint16)-1);
-                       }
-               }
-       }
-}