ctdb/docs: Include ceph rados namespace support in man page
[samba.git] / source3 / smbd / smb1_process.c
index c8957ef6b92a2edb567c765c0fa04291e66c51b2..9b5a1bb16023bd08592c5bf8112061402f766ef2 100644 (file)
@@ -23,6 +23,7 @@
 #include "system/filesys.h"
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
+#include "source3/smbd/smbXsrv_session.h"
 #include "smbd/smbXsrv_open.h"
 #include "librpc/gen_ndr/netlogon.h"
 #include "../lib/async_req/async_sock.h"
@@ -47,6 +48,7 @@
 #include "libcli/smb/smbXcli_base.h"
 #include "lib/util/time_basic.h"
 #include "source3/lib/substitute.h"
+#include "lib/util/util_process.h"
 
 /* Internal message queue for deferred opens. */
 struct pending_message_list {
@@ -55,7 +57,6 @@ struct pending_message_list {
        struct smbd_server_connection *sconn;
        struct smbXsrv_connection *xconn;
        struct tevent_timer *te;
-       struct smb_perfcount_data pcd;
        uint32_t seqnum;
        bool encrypted;
        bool processed;
@@ -207,10 +208,11 @@ void smbd_unlock_socket(struct smbXsrv_connection *xconn)
  Send an smb to a fd.
 ****************************************************************************/
 
-bool smb1_srv_send(struct smbXsrv_connection *xconn, char *buffer,
-                  bool do_signing, uint32_t seqnum,
-                  bool do_encrypt,
-                  struct smb_perfcount_data *pcd)
+bool smb1_srv_send(struct smbXsrv_connection *xconn,
+                  char *buffer,
+                  bool do_signing,
+                  uint32_t seqnum,
+                  bool do_encrypt)
 {
        size_t len = 0;
        ssize_t ret;
@@ -267,11 +269,8 @@ bool smb1_srv_send(struct smbXsrv_connection *xconn, char *buffer,
                goto out;
        }
 
-       SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
        srv_free_enc_buffer(xconn, buf_out);
 out:
-       SMB_PERFCOUNT_END(pcd);
-
        smbd_unlock_socket(xconn);
        return (ret > 0);
 }
@@ -562,7 +561,6 @@ static bool push_queued_message(struct smb_request *req,
        msg->seqnum = req->seqnum;
        msg->encrypted = req->encrypted;
        msg->processed = false;
-       SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
 
        if (open_rec) {
                msg->open_rec = talloc_move(msg, &open_rec);
@@ -986,7 +984,7 @@ static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
                sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
        } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
                /*
-                * echo can be unsigned. Sesssion setup except final
+                * echo can be unsigned. Session setup except final
                 * session setup response too
                 */
                sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
@@ -1013,6 +1011,44 @@ static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
        return;
 }
 
+static void set_current_case_sensitive(connection_struct *conn, uint16_t flags)
+{
+       int snum;
+       enum remote_arch_types ra_type;
+
+       SMB_ASSERT(conn != NULL);
+       SMB_ASSERT(!conn_using_smb2(conn->sconn));
+
+       snum = SNUM(conn);
+
+       /*
+        * Obey the client case sensitivity requests - only for clients that
+        * support it. */
+       switch (lp_case_sensitive(snum)) {
+       case Auto:
+               /*
+                * We need this ugliness due to DOS/Win9x clients that lie
+                * about case insensitivity. */
+               ra_type = get_remote_arch();
+               if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
+                       /*
+                        * Client can't support per-packet case sensitive
+                        * pathnames. */
+                       conn->case_sensitive = false;
+               } else {
+                       conn->case_sensitive =
+                                       !(flags & FLAG_CASELESS_PATHNAMES);
+               }
+       break;
+       case True:
+               conn->case_sensitive = true;
+               break;
+       default:
+               conn->case_sensitive = false;
+               break;
+       }
+}
+
 /****************************************************************************
  Prepare everything for calling the actual request function, and potentially
  call the request function via the "new" interface.
@@ -1257,9 +1293,11 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 ****************************************************************************/
 
 void construct_reply(struct smbXsrv_connection *xconn,
-                    char *inbuf, int size, size_t unread_bytes,
-                    uint32_t seqnum, bool encrypted,
-                    struct smb_perfcount_data *deferred_pcd)
+                    char *inbuf,
+                    int size,
+                    size_t unread_bytes,
+                    uint32_t seqnum,
+                    bool encrypted)
 {
        struct smbd_server_connection *sconn = xconn->client->sconn;
        struct smb_request *req;
@@ -1268,22 +1306,13 @@ void construct_reply(struct smbXsrv_connection *xconn,
                smb_panic("could not allocate smb_request");
        }
 
-       if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
+       if (!init_smb1_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
                              encrypted, seqnum)) {
                exit_server_cleanly("Invalid SMB request");
        }
 
        req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
 
-       /* we popped this message off the queue - keep original perf data */
-       if (deferred_pcd)
-               req->pcd = *deferred_pcd;
-       else {
-               SMB_PERFCOUNT_START(&req->pcd);
-               SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
-               SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
-       }
-
        req->conn = switch_message(req->cmd, req);
 
        if (req->outbuf == NULL) {
@@ -1300,9 +1329,10 @@ void construct_reply(struct smbXsrv_connection *xconn,
 }
 
 static void construct_reply_chain(struct smbXsrv_connection *xconn,
-                                 char *inbuf, int size, uint32_t seqnum,
-                                 bool encrypted,
-                                 struct smb_perfcount_data *deferred_pcd)
+                                 char *inbuf,
+                                 int size,
+                                 uint32_t seqnum,
+                                 bool encrypted)
 {
        struct smb_request **reqs = NULL;
        struct smb_request *req;
@@ -1315,8 +1345,7 @@ static void construct_reply_chain(struct smbXsrv_connection *xconn,
                char errbuf[smb_size];
                error_packet(errbuf, 0, 0, NT_STATUS_INVALID_PARAMETER,
                             __LINE__, __FILE__);
-               if (!smb1_srv_send(xconn, errbuf, true, seqnum, encrypted,
-                                 NULL)) {
+               if (!smb1_srv_send(xconn, errbuf, true, seqnum, encrypted)) {
                        exit_server_cleanly("construct_reply_chain: "
                                            "smb1_srv_send failed.");
                }
@@ -1438,10 +1467,11 @@ void smb_request_done(struct smb_request *req)
 
 shipit:
        if (!smb1_srv_send(first_req->xconn,
-                         (char *)first_req->outbuf,
-                         true, first_req->seqnum+1,
-                         IS_CONN_ENCRYPTED(req->conn)||first_req->encrypted,
-                         &first_req->pcd)) {
+                          (char *)first_req->outbuf,
+                          true,
+                          first_req->seqnum + 1,
+                          IS_CONN_ENCRYPTED(req->conn) ||
+                                  first_req->encrypted)) {
                exit_server_cleanly("construct_reply_chain: smb1_srv_send "
                                    "failed.");
        }
@@ -1453,9 +1483,11 @@ error:
        {
                char errbuf[smb_size];
                error_packet(errbuf, 0, 0, status, __LINE__, __FILE__);
-               if (!smb1_srv_send(req->xconn, errbuf, true,
-                                 req->seqnum+1, req->encrypted,
-                                 NULL)) {
+               if (!smb1_srv_send(req->xconn,
+                                  errbuf,
+                                  true,
+                                  req->seqnum + 1,
+                                  req->encrypted)) {
                        exit_server_cleanly("construct_reply_chain: "
                                            "smb1_srv_send failed.");
                }
@@ -1469,9 +1501,11 @@ error:
 ****************************************************************************/
 
 void process_smb1(struct smbXsrv_connection *xconn,
-                 uint8_t *inbuf, size_t nread, size_t unread_bytes,
-                 uint32_t seqnum, bool encrypted,
-                 struct smb_perfcount_data *deferred_pcd)
+                 uint8_t *inbuf,
+                 size_t nread,
+                 size_t unread_bytes,
+                 uint32_t seqnum,
+                 bool encrypted)
 {
        struct smbd_server_connection *sconn = xconn->client->sconn;
 
@@ -1497,11 +1531,18 @@ void process_smb1(struct smbXsrv_connection *xconn,
        show_msg((char *)inbuf);
 
        if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
-               construct_reply_chain(xconn, (char *)inbuf, nread,
-                                     seqnum, encrypted, deferred_pcd);
+               construct_reply_chain(xconn,
+                                     (char *)inbuf,
+                                     nread,
+                                     seqnum,
+                                     encrypted);
        } else {
-               construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
-                               seqnum, encrypted, deferred_pcd);
+               construct_reply(xconn,
+                               (char *)inbuf,
+                               nread,
+                               unread_bytes,
+                               seqnum,
+                               encrypted);
        }
 
        sconn->trans_num++;
@@ -1909,7 +1950,7 @@ static bool smb1_parse_chain_cb(uint8_t cmd,
                return false;
        }
 
-       ok = init_smb_request(req, state->sconn, state->xconn, state->buf, 0,
+       ok = init_smb1_request(req, state->sconn, state->xconn, state->buf, 0,
                              state->encrypted, state->seqnum);
        if (!ok) {
                return false;
@@ -2036,8 +2077,7 @@ void smbd_smb1_server_connection_read_handler(struct smbXsrv_connection *xconn,
        }
 
 process:
-       process_smb(xconn, inbuf, inbuf_len, unread_bytes,
-                   seqnum, encrypted, NULL);
+       process_smb(xconn, inbuf, inbuf_len, unread_bytes, seqnum, encrypted);
 }
 
 static void smbd_server_echo_handler(struct tevent_context *ev,
@@ -2079,7 +2119,7 @@ bool keepalive_fn(const struct timeval *now, void *private_data)
        struct smbXsrv_connection *xconn = NULL;
        bool ret;
 
-       if (sconn->using_smb2) {
+       if (conn_using_smb2(sconn)) {
                /* Don't do keepalives on an SMB2 connection. */
                return false;
        }
@@ -2351,15 +2391,14 @@ static bool smbd_echo_reply(struct smbd_echo_state *state,
                return false;
        }
 
-       if (!init_smb_request(&req, state->sconn, state->xconn, inbuf, 0, false,
+       if (!init_smb1_request(&req, state->sconn, state->xconn, inbuf, 0, false,
                              seqnum)) {
                return false;
        }
        req.inbuf = inbuf;
 
        DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
-                  smb_messages[req.cmd].name
-                  ? smb_messages[req.cmd].name : "unknown"));
+                  smb_fn_name(req.cmd)));
 
        if (req.cmd != SMBecho) {
                return false;
@@ -2374,9 +2413,9 @@ static bool smbd_echo_reply(struct smbd_echo_state *state,
                return false;
        }
 
-       if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
+       if (!create_smb1_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
                           1, req.buflen)) {
-               DEBUG(10, ("create_outbuf failed\n"));
+               DEBUG(10, ("create_smb1_outbuf failed\n"));
                return false;
        }
        req.outbuf = (uint8_t *)outbuf;
@@ -2387,10 +2426,7 @@ static bool smbd_echo_reply(struct smbd_echo_state *state,
                memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
        }
 
-       ok = smb1_srv_send(req.xconn,
-                         (char *)outbuf,
-                         true, seqnum+1,
-                         false, &req.pcd);
+       ok = smb1_srv_send(req.xconn, (char *)outbuf, true, seqnum + 1, false);
        TALLOC_FREE(outbuf);
        if (!ok) {
                exit(1);
@@ -2602,13 +2638,13 @@ bool fork_echo_handler(struct smbXsrv_connection *xconn)
 
                status = smbd_reinit_after_fork(xconn->client->msg_ctx,
                                                xconn->client->raw_ev_ctx,
-                                               true,
-                                               "smbd-echo");
+                                               true);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(1, ("reinit_after_fork failed: %s\n",
                                  nt_errstr(status)));
                        exit(1);
                }
+               process_set_title("smbd-echo", "echo handler");
                initialize_password_db(true, xconn->client->raw_ev_ctx);
                smbd_echo_loop(xconn, listener_pipe[1]);
                exit(0);