]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
smb: use easy handle/connection meta hash to keep structs
authorStefan Eissing <stefan@eissing.org>
Wed, 30 Apr 2025 12:00:35 +0000 (14:00 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 6 May 2025 07:10:07 +0000 (09:10 +0200)
Keep easy/connection related protoocl structs in the meta hash instead
of the unions at request and connectdata.

Closes #17238

lib/request.h
lib/smb.c
lib/smb.h
lib/urldata.h

index d74079314821175151a68054eba181a92a924614..cdb2371335bb0ed4809c995002fe8bd211332ea0 100644 (file)
@@ -106,7 +106,6 @@ struct SingleRequest {
     struct IMAP *imap;
     struct ldapreqinfo *ldap;
     struct RTSP *rtsp;
-    struct smb_request *smb;
     struct SMTP *smtp;
     struct SSHPROTO *ssh;
     struct TELNET *telnet;
index b25edf8ae3d9f671282e3b201d6beb93d316f94b..133e250c0ee8ecbe26e5fb38f9ad9b609461cfbc 100644 (file)
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -29,6 +29,7 @@
 
 #include "smb.h"
 #include "urldata.h"
+#include "url.h"
 #include "sendf.h"
 #include "multiif.h"
 #include "cfilters.h"
 #include "curl_memory.h"
 #include "memdebug.h"
 
+
+/* meta key for storing protocol meta at easy handle */
+#define CURL_META_SMB_EASY   "meta:proto:smb:easy"
+/* meta key for storing protocol meta at connection */
+#define CURL_META_SMB_CONN   "meta:proto:smb:conn"
+
+enum smb_conn_state {
+  SMB_NOT_CONNECTED = 0,
+  SMB_CONNECTING,
+  SMB_NEGOTIATE,
+  SMB_SETUP,
+  SMB_CONNECTED
+};
+
+/* SMB connection data, kept at connection */
+struct smb_conn {
+  enum smb_conn_state state;
+  char *user;
+  char *domain;
+  char *share;
+  unsigned char challenge[8];
+  unsigned int session_key;
+  unsigned short uid;
+  char *recv_buf;
+  char *send_buf;
+  size_t upload_size;
+  size_t send_size;
+  size_t sent;
+  size_t got;
+};
+
+/* SMB request state */
+enum smb_req_state {
+  SMB_REQUESTING,
+  SMB_TREE_CONNECT,
+  SMB_OPEN,
+  SMB_DOWNLOAD,
+  SMB_UPLOAD,
+  SMB_CLOSE,
+  SMB_TREE_DISCONNECT,
+  SMB_DONE
+};
+
+/* SMB request data, kept at easy handle */
+struct smb_request {
+  enum smb_req_state state;
+  char *path;
+  unsigned short tid; /* Even if we connect to the same tree as another */
+  unsigned short fid; /* request, the tid will be different */
+  CURLcode result;
+};
+
 /*
  * Definitions for SMB protocol data structures
  */
@@ -245,12 +298,11 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done);
 static CURLcode smb_connection_state(struct Curl_easy *data, bool *done);
 static CURLcode smb_do(struct Curl_easy *data, bool *done);
 static CURLcode smb_request_state(struct Curl_easy *data, bool *done);
-static CURLcode smb_disconnect(struct Curl_easy *data,
-                               struct connectdata *conn, bool dead);
 static int smb_getsock(struct Curl_easy *data, struct connectdata *conn,
                        curl_socket_t *socks);
 static CURLcode smb_parse_url_path(struct Curl_easy *data,
-                                   struct connectdata *conn);
+                                   struct smb_conn *smbc,
+                                   struct smb_request *req);
 
 /*
  * SMB handler interface
@@ -268,7 +320,7 @@ const struct Curl_handler Curl_handler_smb = {
   smb_getsock,                          /* doing_getsock */
   ZERO_NULL,                            /* domore_getsock */
   ZERO_NULL,                            /* perform_getsock */
-  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* disconnect */
   ZERO_NULL,                            /* write_resp */
   ZERO_NULL,                            /* write_resp_hd */
   ZERO_NULL,                            /* connection_check */
@@ -297,7 +349,7 @@ const struct Curl_handler Curl_handler_smbs = {
   smb_getsock,                          /* doing_getsock */
   ZERO_NULL,                            /* domore_getsock */
   ZERO_NULL,                            /* perform_getsock */
-  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* disconnect */
   ZERO_NULL,                            /* write_resp */
   ZERO_NULL,                            /* write_resp_hd */
   ZERO_NULL,                            /* connection_check */
@@ -341,30 +393,9 @@ static curl_off_t smb_swap64(curl_off_t x)
 #  define smb_swap64(x) (x)
 #endif
 
-/* SMB request state */
-enum smb_req_state {
-  SMB_REQUESTING,
-  SMB_TREE_CONNECT,
-  SMB_OPEN,
-  SMB_DOWNLOAD,
-  SMB_UPLOAD,
-  SMB_CLOSE,
-  SMB_TREE_DISCONNECT,
-  SMB_DONE
-};
-
-/* SMB request data */
-struct smb_request {
-  enum smb_req_state state;
-  char *path;
-  unsigned short tid; /* Even if we connect to the same tree as another */
-  unsigned short fid; /* request, the tid will be different */
-  CURLcode result;
-};
-
-static void conn_state(struct Curl_easy *data, enum smb_conn_state newstate)
+static void conn_state(struct Curl_easy *data, struct smb_conn *smbc,
+                       enum smb_conn_state newstate)
 {
-  struct smb_conn *smbc = &data->conn->proto.smbc;
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
   /* For debug purposes */
   static const char * const names[] = {
@@ -380,34 +411,59 @@ static void conn_state(struct Curl_easy *data, enum smb_conn_state newstate)
     infof(data, "SMB conn %p state change from %s to %s",
           (void *)smbc, names[smbc->state], names[newstate]);
 #endif
-
+  (void)data;
   smbc->state = newstate;
 }
 
 static void request_state(struct Curl_easy *data,
                           enum smb_req_state newstate)
 {
-  struct smb_request *req = data->req.p.smb;
+  struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
+  if(req) {
 #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
-  /* For debug purposes */
-  static const char * const names[] = {
-    "SMB_REQUESTING",
-    "SMB_TREE_CONNECT",
-    "SMB_OPEN",
-    "SMB_DOWNLOAD",
-    "SMB_UPLOAD",
-    "SMB_CLOSE",
-    "SMB_TREE_DISCONNECT",
-    "SMB_DONE",
-    /* LAST */
-  };
-
-  if(req->state != newstate)
-    infof(data, "SMB request %p state change from %s to %s",
-          (void *)req, names[req->state], names[newstate]);
+    /* For debug purposes */
+    static const char * const names[] = {
+      "SMB_REQUESTING",
+      "SMB_TREE_CONNECT",
+      "SMB_OPEN",
+      "SMB_DOWNLOAD",
+      "SMB_UPLOAD",
+      "SMB_CLOSE",
+      "SMB_TREE_DISCONNECT",
+      "SMB_DONE",
+      /* LAST */
+    };
+
+    if(req->state != newstate)
+      infof(data, "SMB request %p state change from %s to %s",
+            (void *)req, names[req->state], names[newstate]);
 #endif
 
-  req->state = newstate;
+    req->state = newstate;
+  }
+}
+
+static void smb_easy_dtor(void *key, size_t klen, void *entry)
+{
+  struct smb_request *req = entry;
+  (void)key;
+  (void)klen;
+  /* `req->path` points to somewhere in `struct smb_conn` which is
+   * kept at the connection meta. If the connection is destroyed first,
+   * req->path points to free'd memory. */
+  free(req);
+}
+
+static void smb_conn_dtor(void *key, size_t klen, void *entry)
+{
+  struct smb_conn *smbc = entry;
+  (void)key;
+  (void)klen;
+  Curl_safefree(smbc->share);
+  Curl_safefree(smbc->domain);
+  Curl_safefree(smbc->recv_buf);
+  Curl_safefree(smbc->send_buf);
+  free(smbc);
 }
 
 /* this should setup things in the connection, not in the easy
@@ -415,24 +471,34 @@ static void request_state(struct Curl_easy *data,
 static CURLcode smb_setup_connection(struct Curl_easy *data,
                                      struct connectdata *conn)
 {
+  struct smb_conn *smbc;
   struct smb_request *req;
 
+  /* Initialize the connection state */
+  smbc = calloc(1, sizeof(*smbc));
+  if(!smbc ||
+     Curl_conn_meta_set(conn, CURL_META_SMB_CONN, smbc, smb_conn_dtor))
+    return CURLE_OUT_OF_MEMORY;
+
   /* Initialize the request state */
-  data->req.p.smb = req = calloc(1, sizeof(struct smb_request));
-  if(!req)
+  req = calloc(1, sizeof(*req));
+  if(!req ||
+     Curl_meta_set(data, CURL_META_SMB_EASY, req, smb_easy_dtor))
     return CURLE_OUT_OF_MEMORY;
 
   /* Parse the URL path */
-  return smb_parse_url_path(data, conn);
+  return smb_parse_url_path(data, smbc, req);
 }
 
 static CURLcode smb_connect(struct Curl_easy *data, bool *done)
 {
   struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
   char *slash;
 
   (void) done;
+  if(!smbc)
+    return CURLE_FAILED_INIT;
 
   /* Check we have a username and password to authenticate with */
   if(!data->state.aptr.user)
@@ -472,10 +538,10 @@ static CURLcode smb_connect(struct Curl_easy *data, bool *done)
   return CURLE_OK;
 }
 
-static CURLcode smb_recv_message(struct Curl_easy *data, void **msg)
+static CURLcode smb_recv_message(struct Curl_easy *data,
+                                 struct smb_conn *smbc,
+                                 void **msg)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
   char *buf = smbc->recv_buf;
   ssize_t bytes_read;
   size_t nbt_size;
@@ -520,19 +586,16 @@ static CURLcode smb_recv_message(struct Curl_easy *data, void **msg)
   return CURLE_OK;
 }
 
-static void smb_pop_message(struct connectdata *conn)
+static void smb_pop_message(struct smb_conn *smbc)
 {
-  struct smb_conn *smbc = &conn->proto.smbc;
-
   smbc->got = 0;
 }
 
-static void smb_format_message(struct Curl_easy *data, struct smb_header *h,
+static void smb_format_message(struct smb_conn *smbc,
+                               struct smb_request *req,
+                               struct smb_header *h,
                                unsigned char cmd, size_t len)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
-  struct smb_request *req = data->req.p.smb;
   unsigned int pid;
 
   memset(h, 0, sizeof(*h));
@@ -549,11 +612,9 @@ static void smb_format_message(struct Curl_easy *data, struct smb_header *h,
   h->pid = smb_swap16((unsigned short) pid);
 }
 
-static CURLcode smb_send(struct Curl_easy *data, size_t len,
-                         size_t upload_size)
+static CURLcode smb_send(struct Curl_easy *data, struct smb_conn *smbc,
+                         size_t len, size_t upload_size)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
   size_t bytes_written;
   CURLcode result;
 
@@ -571,10 +632,8 @@ static CURLcode smb_send(struct Curl_easy *data, size_t len,
   return CURLE_OK;
 }
 
-static CURLcode smb_flush(struct Curl_easy *data)
+static CURLcode smb_flush(struct Curl_easy *data, struct smb_conn *smbc)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
   size_t bytes_written;
   size_t len = smbc->send_size - smbc->sent;
   CURLcode result;
@@ -595,39 +654,46 @@ static CURLcode smb_flush(struct Curl_easy *data)
   return CURLE_OK;
 }
 
-static CURLcode smb_send_message(struct Curl_easy *data, unsigned char cmd,
+static CURLcode smb_send_message(struct Curl_easy *data,
+                                 struct smb_conn *smbc,
+                                 struct smb_request *req,
+                                 unsigned char cmd,
                                  const void *msg, size_t msg_len)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
-
-  smb_format_message(data, (struct smb_header *)smbc->send_buf,
+  smb_format_message(smbc, req, (struct smb_header *)smbc->send_buf,
                      cmd, msg_len);
   DEBUGASSERT((sizeof(struct smb_header) + msg_len) <= MAX_MESSAGE_SIZE);
   memcpy(smbc->send_buf + sizeof(struct smb_header), msg, msg_len);
 
-  return smb_send(data, sizeof(struct smb_header) + msg_len, 0);
+  return smb_send(data, smbc, sizeof(struct smb_header) + msg_len, 0);
 }
 
-static CURLcode smb_send_negotiate(struct Curl_easy *data)
+static CURLcode smb_send_negotiate(struct Curl_easy *data,
+                                   struct smb_conn *smbc,
+                                   struct smb_request *req)
 {
   const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
 
-  return smb_send_message(data, SMB_COM_NEGOTIATE, msg, 15);
+  return smb_send_message(data, smbc, req, SMB_COM_NEGOTIATE, msg, 15);
 }
 
 static CURLcode smb_send_setup(struct Curl_easy *data)
 {
   struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
+  struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
   struct smb_setup msg;
   char *p = msg.bytes;
   unsigned char lm_hash[21];
   unsigned char lm[24];
   unsigned char nt_hash[21];
   unsigned char nt[24];
+  size_t byte_count;
+
+  if(!smbc || !req)
+    return CURLE_FAILED_INIT;
 
-  const size_t byte_count = sizeof(lm) + sizeof(nt) +
+  byte_count = sizeof(lm) + sizeof(nt) +
     strlen(smbc->user) + strlen(smbc->domain) +
     strlen(CURL_OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */
   if(byte_count > sizeof(msg.bytes))
@@ -662,19 +728,20 @@ static CURLcode smb_send_setup(struct Curl_easy *data)
   DEBUGASSERT(byte_count == (size_t)(p - msg.bytes));
   msg.byte_count = smb_swap16((unsigned short)byte_count);
 
-  return smb_send_message(data, SMB_COM_SETUP_ANDX, &msg,
+  return smb_send_message(data, smbc, req, SMB_COM_SETUP_ANDX, &msg,
                           sizeof(msg) - sizeof(msg.bytes) + byte_count);
 }
 
-static CURLcode smb_send_tree_connect(struct Curl_easy *data)
+static CURLcode smb_send_tree_connect(struct Curl_easy *data,
+                                      struct smb_conn *smbc,
+                                      struct smb_request *req)
 {
   struct smb_tree_connect msg;
   struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
   char *p = msg.bytes;
-
   const size_t byte_count = strlen(conn->host.name) + strlen(smbc->share) +
     strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
+
   if(byte_count > sizeof(msg.bytes))
     return CURLE_FILESIZE_EXCEEDED;
 
@@ -692,13 +759,14 @@ static CURLcode smb_send_tree_connect(struct Curl_easy *data)
   DEBUGASSERT(byte_count == (size_t)(p - msg.bytes));
   msg.byte_count = smb_swap16((unsigned short)byte_count);
 
-  return smb_send_message(data, SMB_COM_TREE_CONNECT_ANDX, &msg,
+  return smb_send_message(data, smbc, req, SMB_COM_TREE_CONNECT_ANDX, &msg,
                           sizeof(msg) - sizeof(msg.bytes) + byte_count);
 }
 
-static CURLcode smb_send_open(struct Curl_easy *data)
+static CURLcode smb_send_open(struct Curl_easy *data,
+                              struct smb_conn *smbc,
+                              struct smb_request *req)
 {
-  struct smb_request *req = data->req.p.smb;
   struct smb_nt_create msg;
   const size_t byte_count = strlen(req->path) + 1;
 
@@ -721,34 +789,37 @@ static CURLcode smb_send_open(struct Curl_easy *data)
   msg.byte_count = smb_swap16((unsigned short) byte_count);
   strcpy(msg.bytes, req->path);
 
-  return smb_send_message(data, SMB_COM_NT_CREATE_ANDX, &msg,
+  return smb_send_message(data, smbc, req, SMB_COM_NT_CREATE_ANDX, &msg,
                           sizeof(msg) - sizeof(msg.bytes) + byte_count);
 }
 
-static CURLcode smb_send_close(struct Curl_easy *data)
+static CURLcode smb_send_close(struct Curl_easy *data,
+                               struct smb_conn *smbc,
+                               struct smb_request *req)
 {
-  struct smb_request *req = data->req.p.smb;
   struct smb_close msg;
 
   memset(&msg, 0, sizeof(msg));
   msg.word_count = SMB_WC_CLOSE;
   msg.fid = smb_swap16(req->fid);
 
-  return smb_send_message(data, SMB_COM_CLOSE, &msg, sizeof(msg));
+  return smb_send_message(data, smbc, req, SMB_COM_CLOSE, &msg, sizeof(msg));
 }
 
-static CURLcode smb_send_tree_disconnect(struct Curl_easy *data)
+static CURLcode smb_send_tree_disconnect(struct Curl_easy *data,
+                                         struct smb_conn *smbc,
+                                         struct smb_request *req)
 {
   struct smb_tree_disconnect msg;
-
   memset(&msg, 0, sizeof(msg));
-
-  return smb_send_message(data, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
+  return smb_send_message(data, smbc, req, SMB_COM_TREE_DISCONNECT,
+                          &msg, sizeof(msg));
 }
 
-static CURLcode smb_send_read(struct Curl_easy *data)
+static CURLcode smb_send_read(struct Curl_easy *data,
+                              struct smb_conn *smbc,
+                              struct smb_request *req)
 {
-  struct smb_request *req = data->req.p.smb;
   curl_off_t offset = data->req.offset;
   struct smb_read msg;
 
@@ -761,15 +832,15 @@ static CURLcode smb_send_read(struct Curl_easy *data)
   msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
   msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
 
-  return smb_send_message(data, SMB_COM_READ_ANDX, &msg, sizeof(msg));
+  return smb_send_message(data, smbc, req, SMB_COM_READ_ANDX,
+                          &msg, sizeof(msg));
 }
 
-static CURLcode smb_send_write(struct Curl_easy *data)
+static CURLcode smb_send_write(struct Curl_easy *data,
+                               struct smb_conn *smbc,
+                               struct smb_request *req)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
   struct smb_write *msg;
-  struct smb_request *req = data->req.p.smb;
   curl_off_t offset = data->req.offset;
   curl_off_t upload_size = data->req.size - data->req.bytecount;
 
@@ -787,16 +858,15 @@ static CURLcode smb_send_write(struct Curl_easy *data)
   msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
   msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
 
-  smb_format_message(data, &msg->h, SMB_COM_WRITE_ANDX,
+  smb_format_message(smbc, req, &msg->h, SMB_COM_WRITE_ANDX,
                      sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
 
-  return smb_send(data, sizeof(*msg), (size_t) upload_size);
+  return smb_send(data, smbc, sizeof(*msg), (size_t) upload_size);
 }
 
-static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
+static CURLcode smb_send_and_recv(struct Curl_easy *data,
+                                  struct smb_conn *smbc, void **msg)
 {
-  struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
   CURLcode result;
   *msg = NULL; /* if it returns early */
 
@@ -819,7 +889,7 @@ static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
 
   /* Check if there is data to send */
   if(smbc->send_size) {
-    result = smb_flush(data);
+    result = smb_flush(data, smbc);
     if(result)
       return result;
   }
@@ -828,18 +898,22 @@ static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg)
   if(smbc->send_size || smbc->upload_size)
     return CURLE_AGAIN;
 
-  return smb_recv_message(data, msg);
+  return smb_recv_message(data, smbc, msg);
 }
 
 static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
 {
   struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
+  struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
   struct smb_negotiate_response *nrsp;
   struct smb_header *h;
   CURLcode result;
   void *msg = NULL;
 
+  if(!smbc || !req)
+    return CURLE_FAILED_INIT;
+
   if(smbc->state == SMB_CONNECTING) {
 #ifdef USE_SSL
     if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) {
@@ -852,17 +926,17 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
     }
 #endif
 
-    result = smb_send_negotiate(data);
+    result = smb_send_negotiate(data, smbc, req);
     if(result) {
       connclose(conn, "SMB: failed to send negotiate message");
       return result;
     }
 
-    conn_state(data, SMB_NEGOTIATE);
+    conn_state(data, smbc, SMB_NEGOTIATE);
   }
 
   /* Send the previous message and check for a response */
-  result = smb_send_and_recv(data, &msg);
+  result = smb_send_and_recv(data, smbc, &msg);
   if(result && result != CURLE_AGAIN) {
     connclose(conn, "SMB: failed to communicate");
     return result;
@@ -897,7 +971,7 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
       connclose(conn, "SMB: failed to send setup message");
       return result;
     }
-    conn_state(data, SMB_SETUP);
+    conn_state(data, smbc, SMB_SETUP);
     break;
 
   case SMB_SETUP:
@@ -906,16 +980,16 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done)
       return CURLE_LOGIN_DENIED;
     }
     smbc->uid = smb_swap16(h->uid);
-    conn_state(data, SMB_CONNECTED);
+    conn_state(data, smbc, SMB_CONNECTED);
     *done = TRUE;
     break;
 
   default:
-    smb_pop_message(conn);
+    smb_pop_message(smbc);
     return CURLE_OK; /* ignore */
   }
 
-  smb_pop_message(conn);
+  smb_pop_message(smbc);
 
   return CURLE_OK;
 }
@@ -945,9 +1019,9 @@ static void get_posix_time(time_t *out, curl_off_t timestamp)
 static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
 {
   struct connectdata *conn = data->conn;
-  struct smb_request *req = data->req.p.smb;
+  struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
+  struct smb_request *req = Curl_meta_get(data, CURL_META_SMB_EASY);
   struct smb_header *h;
-  struct smb_conn *smbc = &conn->proto.smbc;
   enum smb_req_state next_state = SMB_DONE;
   unsigned short len;
   unsigned short off;
@@ -955,6 +1029,9 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
   void *msg = NULL;
   const struct smb_nt_create_response *smb_m;
 
+  if(!smbc || !req)
+    return CURLE_FAILED_INIT;
+
   if(data->state.upload && (data->state.infilesize < 0)) {
     failf(data, "SMB upload needs to know the size up front");
     return CURLE_SEND_ERROR;
@@ -962,7 +1039,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
 
   /* Start the request */
   if(req->state == SMB_REQUESTING) {
-    result = smb_send_tree_connect(data);
+    result = smb_send_tree_connect(data, smbc, req);
     if(result) {
       connclose(conn, "SMB: failed to send tree connect message");
       return result;
@@ -972,7 +1049,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
   }
 
   /* Send the previous message and check for a response */
-  result = smb_send_and_recv(data, &msg);
+  result = smb_send_and_recv(data, smbc, &msg);
   if(result && result != CURLE_AGAIN) {
     connclose(conn, "SMB: failed to communicate");
     return result;
@@ -1082,31 +1159,31 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
     break;
 
   default:
-    smb_pop_message(conn);
+    smb_pop_message(smbc);
     return CURLE_OK; /* ignore */
   }
 
-  smb_pop_message(conn);
+  smb_pop_message(smbc);
 
   switch(next_state) {
   case SMB_OPEN:
-    result = smb_send_open(data);
+    result = smb_send_open(data, smbc, req);
     break;
 
   case SMB_DOWNLOAD:
-    result = smb_send_read(data);
+    result = smb_send_read(data, smbc, req);
     break;
 
   case SMB_UPLOAD:
-    result = smb_send_write(data);
+    result = smb_send_write(data, smbc, req);
     break;
 
   case SMB_CLOSE:
-    result = smb_send_close(data);
+    result = smb_send_close(data, smbc, req);
     break;
 
   case SMB_TREE_DISCONNECT:
-    result = smb_send_tree_disconnect(data);
+    result = smb_send_tree_disconnect(data, smbc, req);
     break;
 
   case SMB_DONE:
@@ -1128,19 +1205,6 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
   return CURLE_OK;
 }
 
-static CURLcode smb_disconnect(struct Curl_easy *data,
-                               struct connectdata *conn, bool dead)
-{
-  struct smb_conn *smbc = &conn->proto.smbc;
-  (void) dead;
-  (void) data;
-  Curl_safefree(smbc->share);
-  Curl_safefree(smbc->domain);
-  Curl_safefree(smbc->recv_buf);
-  Curl_safefree(smbc->send_buf);
-  return CURLE_OK;
-}
-
 static int smb_getsock(struct Curl_easy *data,
                        struct connectdata *conn, curl_socket_t *socks)
 {
@@ -1152,26 +1216,26 @@ static int smb_getsock(struct Curl_easy *data,
 static CURLcode smb_do(struct Curl_easy *data, bool *done)
 {
   struct connectdata *conn = data->conn;
-  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_conn *smbc = Curl_conn_meta_get(conn, CURL_META_SMB_CONN);
 
   *done = FALSE;
-  if(smbc->share) {
+  if(!smbc)
+    return CURLE_FAILED_INIT;
+  if(smbc->share)
     return CURLE_OK;
-  }
   return CURLE_URL_MALFORMAT;
 }
 
 static CURLcode smb_parse_url_path(struct Curl_easy *data,
-                                   struct connectdata *conn)
+                                   struct smb_conn *smbc,
+                                   struct smb_request *req)
 {
-  struct smb_request *req = data->req.p.smb;
-  struct smb_conn *smbc = &conn->proto.smbc;
   char *path;
   char *slash;
+  CURLcode result;
 
   /* URL decode the path */
-  CURLcode result = Curl_urldecode(data->state.up.path, 0, &path, NULL,
-                                   REJECT_CTRL);
+  result = Curl_urldecode(data->state.up.path, 0, &path, NULL, REJECT_CTRL);
   if(result)
     return result;
 
index 9ea2a8cc31c8bc47137a9744adf4aa75761c8875..eb4df6550a3edee765a27d5a0cbb6dc6222ae8f2 100644 (file)
--- a/lib/smb.h
+++ b/lib/smb.h
  *
  ***************************************************************************/
 
-enum smb_conn_state {
-  SMB_NOT_CONNECTED = 0,
-  SMB_CONNECTING,
-  SMB_NEGOTIATE,
-  SMB_SETUP,
-  SMB_CONNECTED
-};
-
-struct smb_conn {
-  enum smb_conn_state state;
-  char *user;
-  char *domain;
-  char *share;
-  unsigned char challenge[8];
-  unsigned int session_key;
-  unsigned short uid;
-  char *recv_buf;
-  char *send_buf;
-  size_t upload_size;
-  size_t send_size;
-  size_t sent;
-  size_t got;
-};
-
 #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
     (SIZEOF_CURL_OFF_T > 4)
 
index 29979c0327817a3c263492282f218905e84ad96f..2b6100d173b30cc710e406800f4e32392e780973 100644 (file)
@@ -875,9 +875,6 @@ struct connectdata {
 #ifndef CURL_DISABLE_RTSP
     struct rtsp_conn rtspc;
 #endif
-#ifndef CURL_DISABLE_SMB
-    struct smb_conn smbc;
-#endif
 #ifdef USE_LIBRTMP
     void *rtmp;
 #endif