Add two flags to allow for handling of Extended Signatures (Session Key Protection...
[samba.git] / source3 / smbd / process.c
index a437a9813b464d12b5a7b8de266d364d54ebca42..dd26a27ec391eae7ecff4fa57bcfd81c7184242c 100644 (file)
@@ -41,8 +41,6 @@
 #include "lib/id_cache.h"
 #include "serverid.h"
 
-extern bool global_machine_password_needs_changing;
-
 /* Internal message queue for deferred opens. */
 struct pending_message_list {
        struct pending_message_list *next, *prev;
@@ -718,15 +716,14 @@ void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
  schedule it for immediate processing.
 ****************************************************************************/
 
-void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
+bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
                                        uint64_t mid)
 {
        struct pending_message_list *pml;
        int i = 0;
 
        if (sconn->using_smb2) {
-               schedule_deferred_open_message_smb2(sconn, mid);
-               return;
+               return schedule_deferred_open_message_smb2(sconn, mid);
        }
 
        for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
@@ -768,13 +765,15 @@ void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
                        TALLOC_FREE(pml->te);
                        pml->te = te;
                        DLIST_PROMOTE(sconn->deferred_open_queue, pml);
-                       return;
+                       return true;
                }
        }
 
        DEBUG(10,("schedule_deferred_open_message_smb: failed to "
                "find message mid %llu\n",
                (unsigned long long)mid ));
+
+       return false;
 }
 
 /****************************************************************************
@@ -2463,12 +2462,21 @@ static void smbd_server_echo_handler(struct event_context *ev,
 }
 
 #ifdef CLUSTER_SUPPORT
+
+struct smbd_release_ip_state {
+       struct smbd_server_connection *sconn;
+       char addr[INET6_ADDRSTRLEN];
+};
+
 /****************************************************************************
 received when we should release a specific IP
 ****************************************************************************/
 static void release_ip(const char *ip, void *priv)
 {
-       const char *addr = (const char *)priv;
+       struct smbd_release_ip_state *state =
+               talloc_get_type_abort(priv,
+               struct smbd_release_ip_state);
+       const char *addr = state->addr;
        const char *p = addr;
 
        if (strncmp("::ffff:", addr, 7) == 0) {
@@ -2479,17 +2487,53 @@ static void release_ip(const char *ip, void *priv)
                   "our address is %s\n", ip, p));
 
        if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
-               /* we can't afford to do a clean exit - that involves
-                  database writes, which would potentially mean we
-                  are still running after the failover has finished -
-                  we have to get rid of this process ID straight
-                  away */
                DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
                        ip));
-               /* note we must exit with non-zero status so the unclean handler gets
-                  called in the parent, so that the brl database is tickled */
-               _exit(1);
+               /*
+                * With SMB2 we should do a clean disconnect,
+                * the previous_session_id in the session setup
+                * will cleanup the old session, tcons and opens.
+                *
+                * A clean disconnect is needed in order to support
+                * durable handles.
+                *
+                * Note: typically this is never triggered
+                *       as we got a TCP RST (triggered by ctdb event scripts)
+                *       before we get CTDB_SRVID_RELEASE_IP.
+                *
+                * We used to call _exit(1) here, but as this was mostly never
+                * triggered and has implication on our process model,
+                * we can just use smbd_server_connection_terminate()
+                * (also for SMB1).
+                */
+               smbd_server_connection_terminate(state->sconn,
+                                                "CTDB_SRVID_RELEASE_IP");
+               return;
+       }
+}
+
+static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
+                                 struct sockaddr_storage *srv,
+                                 struct sockaddr_storage *clnt)
+{
+       struct smbd_release_ip_state *state;
+       struct ctdbd_connection *cconn;
+
+       cconn = messaging_ctdbd_connection();
+       if (cconn == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       state = talloc_zero(sconn, struct smbd_release_ip_state);
+       if (state == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       state->sconn = sconn;
+       if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
+               return NT_STATUS_NO_MEMORY;
        }
+
+       return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
 }
 
 static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
@@ -2580,9 +2624,6 @@ static bool housekeeping_fn(const struct timeval *now, void *private_data)
        /* check if we need to reload services */
        check_reload(sconn, time_mono(NULL));
 
-       /* Change machine password if neccessary. */
-       attempt_machine_password_change();
-
         /*
         * Force a log file check.
         */
@@ -3071,33 +3112,6 @@ fail:
        return false;
 }
 
-#if CLUSTER_SUPPORT
-
-static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
-                                 struct sockaddr_storage *srv,
-                                 struct sockaddr_storage *clnt)
-{
-       struct ctdbd_connection *cconn;
-       char tmp_addr[INET6_ADDRSTRLEN];
-       char *addr;
-
-       cconn = messaging_ctdbd_connection();
-       if (cconn == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr)) == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       addr = talloc_strdup(cconn, tmp_addr);
-       if (addr == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
-}
-
-#endif
-
 static bool uid_in_use(const struct user_struct *user, uid_t uid)
 {
        while (user) {
@@ -3211,6 +3225,11 @@ NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
+
+               status = smb2srv_open_table_init(conn);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        } else {
                status = smb1srv_session_table_init(conn);
                if (!NT_STATUS_IS_OK(status)) {
@@ -3221,6 +3240,11 @@ NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
+
+               status = smb1srv_open_table_init(conn);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        }
 
        return NT_STATUS_OK;
@@ -3450,16 +3474,17 @@ void smbd_process(struct tevent_context *ev_ctx,
                exit_server("Could not open account policy tdb.\n");
        }
 
-       if (*lp_rootdir()) {
-               if (chroot(lp_rootdir()) != 0) {
-                       DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
+       if (*lp_rootdir(talloc_tos())) {
+               if (chroot(lp_rootdir(talloc_tos())) != 0) {
+                       DEBUG(0,("Failed to change root to %s\n",
+                                lp_rootdir(talloc_tos())));
                        exit_server("Failed to chroot()");
                }
                if (chdir("/") == -1) {
-                       DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
+                       DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir(talloc_tos())));
                        exit_server("Failed to chroot()");
                }
-               DEBUG(0,("Changed root to %s\n", lp_rootdir()));
+               DEBUG(0,("Changed root to %s\n", lp_rootdir(talloc_tos())));
        }
 
        if (!srv_init_signing(sconn)) {