lib: remove unused function nttime_from_string()
[bbaumbach/samba-autobuild/.git] / source3 / libsmb / clirap.c
index 6685fbd1d8b8c5a3e306c5bbcf1abea8e7c0af07..e80dfc92a77b0bd2dd6c614e6f05d2f24dda8e1e 100644 (file)
@@ -29,6 +29,7 @@
 #include "libsmb/clirap.h"
 #include "trans2.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "cli_smb2_fnum.h"
 
 #define PIPE_LANMAN   "\\PIPE\\LANMAN"
 
@@ -67,14 +68,14 @@ bool cli_api(struct cli_state *cli,
         * talloc
         */
 
-       *rparam = (char *)memdup(my_rparam, num_my_rparam);
+       *rparam = (char *)smb_memdup(my_rparam, num_my_rparam);
        if (*rparam == NULL) {
                goto fail;
        }
        *rprcnt = num_my_rparam;
        TALLOC_FREE(my_rparam);
 
-       *rdata = (char *)memdup(my_rdata, num_my_rdata);
+       *rdata = (char *)smb_memdup(my_rdata, num_my_rdata);
        if (*rdata == NULL) {
                goto fail;
        }
@@ -117,13 +118,17 @@ bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
        SSVAL(p,0,1);
        p += 2;
        strlcpy(p,user,sizeof(param)-PTR_DIFF(p,param));
-       strupper_m(p);
+       if (!strupper_m(p)) {
+               return false;
+       }
        p += 21;
        p++;
        p += 15;
        p++;
        strlcpy(p, workstation,sizeof(param)-PTR_DIFF(p,param));
-       strupper_m(p);
+       if (!strupper_m(p)) {
+               return false;
+       }
        p += 16;
        SSVAL(p, 0, CLI_BUFFER_SIZE);
        p += 2;
@@ -161,7 +166,7 @@ bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
  Call a NetShareEnum - try and browse available connections on a host.
 ****************************************************************************/
 
-int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state)
+int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32_t, const char *, void *), void *state)
 {
        char *rparam = NULL;
        char *rdata = NULL;
@@ -268,8 +273,8 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
  the comment and a state pointer.
 ****************************************************************************/
 
-bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
-                      void (*fn)(const char *, uint32, const char *, void *),
+bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype,
+                      void (*fn)(const char *, uint32_t, const char *, void *),
                       void *state)
 {
        char *rparam = NULL;
@@ -280,7 +285,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
        char param[1024];
        int uLevel = 1;
        size_t len;
-       uint32 func = RAP_NetServerEnum2;
+       uint32_t func = RAP_NetServerEnum2;
        char *last_entry = NULL;
        int total_cnt = 0;
        int return_cnt = 0;
@@ -323,7 +328,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
                                sizeof(param) - PTR_DIFF(p,param) - 1,
                                STR_TERMINATE|STR_UPPER);
 
-               if (len == (size_t)-1) {
+               if (len == 0) {
                        SAFE_FREE(last_entry);
                        return false;
                }
@@ -335,7 +340,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
                                        sizeof(param) - PTR_DIFF(p,param) - 1,
                                        STR_TERMINATE);
 
-                       if (len == (size_t)-1) {
+                       if (len == 0) {
                                SAFE_FREE(last_entry);
                                return false;
                        }
@@ -578,7 +583,7 @@ struct cli_qpathinfo1_state {
 static void cli_qpathinfo1_done(struct tevent_req *subreq);
 
 struct tevent_req *cli_qpathinfo1_send(TALLOC_CTX *mem_ctx,
-                                      struct event_context *ev,
+                                      struct tevent_context *ev,
                                       struct cli_state *cli,
                                       const char *fname)
 {
@@ -622,7 +627,7 @@ NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req,
                             time_t *access_time,
                             time_t *write_time,
                             off_t *size,
-                            uint16 *mode)
+                            uint16_t *mode)
 {
        struct cli_qpathinfo1_state *state = tevent_req_data(
                req, struct cli_qpathinfo1_state);
@@ -664,10 +669,10 @@ NTSTATUS cli_qpathinfo1(struct cli_state *cli,
                        time_t *access_time,
                        time_t *write_time,
                        off_t *size,
-                       uint16 *mode)
+                       uint16_t *mode)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-       struct event_context *ev;
+       struct tevent_context *ev;
        struct tevent_req *req;
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
@@ -678,7 +683,7 @@ NTSTATUS cli_qpathinfo1(struct cli_state *cli,
                status = NT_STATUS_INVALID_PARAMETER;
                goto fail;
        }
-       ev = event_context_init(frame);
+       ev = samba_tevent_context_init(frame);
        if (ev == NULL) {
                goto fail;
        }
@@ -705,7 +710,7 @@ NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname,
                               time_t access_time,
                               time_t write_time,
                               time_t change_time,
-                              uint16 mode)
+                              uint16_t mode)
 {
        unsigned int data_len = 0;
        char data[40];
@@ -728,8 +733,17 @@ NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname,
         put_long_date(p, change_time);
         p += 8;
 
-        /* Add attributes */
-        SIVAL(p, 0, mode);
+       if (mode == (uint16_t)-1 || mode == FILE_ATTRIBUTE_NORMAL) {
+               /* No change. */
+               mode = 0;
+       } else if (mode == 0) {
+               /* Clear all existing attributes. */
+               mode = FILE_ATTRIBUTE_NORMAL;
+       }
+
+       /* Add attributes */
+       SIVAL(p, 0, mode);
+
         p += 4;
 
         /* Add padding */
@@ -738,6 +752,19 @@ NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname,
 
         data_len = PTR_DIFF(p, data);
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               DATA_BLOB in_data = data_blob_const(data, data_len);
+               /*
+                * Split out SMB2 here as we need to select
+                * the correct info type and level.
+                */
+               return cli_smb2_setpathinfo(cli,
+                               fname,
+                               1, /* SMB2_SETINFO_FILE */
+                               SMB_FILE_BASIC_INFORMATION - 1000,
+                               &in_data);
+       }
+
        return cli_setpathinfo(cli, SMB_FILE_BASIC_INFORMATION, fname,
                               (uint8_t *)data, data_len);
 }
@@ -754,7 +781,7 @@ struct cli_qpathinfo2_state {
 static void cli_qpathinfo2_done(struct tevent_req *subreq);
 
 struct tevent_req *cli_qpathinfo2_send(TALLOC_CTX *mem_ctx,
-                                      struct event_context *ev,
+                                      struct tevent_context *ev,
                                       struct cli_state *cli,
                                       const char *fname)
 {
@@ -798,7 +825,7 @@ NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req,
                             struct timespec *access_time,
                             struct timespec *write_time,
                             struct timespec *change_time,
-                            off_t *size, uint16 *mode,
+                            off_t *size, uint16_t *mode,
                             SMB_INO_T *ino)
 {
        struct cli_qpathinfo2_state *state = tevent_req_data(
@@ -838,14 +865,28 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname,
                        struct timespec *access_time,
                        struct timespec *write_time,
                        struct timespec *change_time,
-                       off_t *size, uint16 *mode,
+                       off_t *size, uint16_t *mode,
                        SMB_INO_T *ino)
 {
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct event_context *ev;
+       TALLOC_CTX *frame = NULL;
+       struct tevent_context *ev;
        struct tevent_req *req;
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_smb2_qpathinfo2(cli,
+                                       fname,
+                                       create_time,
+                                       access_time,
+                                       write_time,
+                                       change_time,
+                                       size,
+                                       mode,
+                                       ino);
+       }
+
+       frame = talloc_stackframe();
+
        if (smbXcli_conn_has_async_calls(cli->conn)) {
                /*
                 * Can't use sync call while an async call is in flight
@@ -853,7 +894,7 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname,
                status = NT_STATUS_INVALID_PARAMETER;
                goto fail;
        }
-       ev = event_context_init(frame);
+       ev = samba_tevent_context_init(frame);
        if (ev == NULL) {
                goto fail;
        }
@@ -875,11 +916,6 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname,
  Get the stream info
 ****************************************************************************/
 
-static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *data,
-                              size_t data_len,
-                              unsigned int *pnum_streams,
-                              struct stream_struct **pstreams);
-
 struct cli_qpathinfo_streams_state {
        uint32_t num_data;
        uint8_t *data;
@@ -952,11 +988,21 @@ NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
                               unsigned int *pnum_streams,
                               struct stream_struct **pstreams)
 {
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct event_context *ev;
+       TALLOC_CTX *frame = NULL;
+       struct tevent_context *ev;
        struct tevent_req *req;
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_smb2_qpathinfo_streams(cli,
+                                       fname,
+                                       mem_ctx,
+                                       pnum_streams,
+                                       pstreams);
+       }
+
+       frame = talloc_stackframe();
+
        if (smbXcli_conn_has_async_calls(cli->conn)) {
                /*
                 * Can't use sync call while an async call is in flight
@@ -964,7 +1010,7 @@ NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
                status = NT_STATUS_INVALID_PARAMETER;
                goto fail;
        }
-       ev = event_context_init(frame);
+       ev = samba_tevent_context_init(frame);
        if (ev == NULL) {
                goto fail;
        }
@@ -982,7 +1028,7 @@ NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
        return status;
 }
 
-static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata,
+bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata,
                               size_t data_len,
                               unsigned int *pnum_streams,
                               struct stream_struct **pstreams)
@@ -1115,7 +1161,7 @@ NTSTATUS cli_qfilename(struct cli_state *cli, uint16_t fnum,
 ****************************************************************************/
 
 NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum,
-                            uint16 *mode, off_t *size,
+                            uint16_t *mode, off_t *size,
                             struct timespec *create_time,
                             struct timespec *access_time,
                             struct timespec *write_time,
@@ -1126,6 +1172,18 @@ NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum,
        uint32_t num_rdata;
        NTSTATUS status;
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_smb2_qfileinfo_basic(cli,
+                                               fnum,
+                                               mode,
+                                               size,
+                                               create_time,
+                                               access_time,
+                                               write_time,
+                                               change_time,
+                                               ino);
+       }
+
        /* if its a win95 server then fail this - win95 totally screws it
           up */
        if (cli->win95) {
@@ -1179,7 +1237,7 @@ struct cli_qpathinfo_basic_state {
 static void cli_qpathinfo_basic_done(struct tevent_req *subreq);
 
 struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx,
-                                           struct event_context *ev,
+                                           struct tevent_context *ev,
                                            struct cli_state *cli,
                                            const char *fname)
 {
@@ -1220,7 +1278,7 @@ static void cli_qpathinfo_basic_done(struct tevent_req *subreq)
 }
 
 NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
-                                 SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+                                 SMB_STRUCT_STAT *sbuf, uint32_t *attributes)
 {
        struct cli_qpathinfo_basic_state *state = tevent_req_data(
                req, struct cli_qpathinfo_basic_state);
@@ -1230,6 +1288,7 @@ NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
                return status;
        }
 
+       sbuf->st_ex_btime = interpret_long_date((char *)state->data);
        sbuf->st_ex_atime = interpret_long_date((char *)state->data+8);
        sbuf->st_ex_mtime = interpret_long_date((char *)state->data+16);
        sbuf->st_ex_ctime = interpret_long_date((char *)state->data+24);
@@ -1238,13 +1297,22 @@ NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
 }
 
 NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
-                            SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+                            SMB_STRUCT_STAT *sbuf, uint32_t *attributes)
 {
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct event_context *ev;
+       TALLOC_CTX *frame = NULL;
+       struct tevent_context *ev;
        struct tevent_req *req;
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_smb2_qpathinfo_basic(cli,
+                                               name,
+                                               sbuf,
+                                               attributes);
+       }
+
+       frame = talloc_stackframe();
+
        if (smbXcli_conn_has_async_calls(cli->conn)) {
                /*
                 * Can't use sync call while an async call is in flight
@@ -1252,7 +1320,7 @@ NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
                status = NT_STATUS_INVALID_PARAMETER;
                goto fail;
        }
-       ev = event_context_init(frame);
+       ev = samba_tevent_context_init(frame);
        if (ev == NULL) {
                goto fail;
        }
@@ -1282,6 +1350,12 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin
        size_t converted_size = 0;
        NTSTATUS status;
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_smb2_qpathinfo_alt_name(cli,
+                                               fname,
+                                               alt_name);
+       }
+
        status = cli_qpathinfo(talloc_tos(), cli, fname,
                               SMB_QUERY_FILE_ALT_NAME_INFO,
                               4, CLI_BUFFER_SIZE, &rdata, &num_rdata);
@@ -1312,3 +1386,112 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin
 
        return NT_STATUS_OK;
 }
+
+/****************************************************************************
+ Send a qpathinfo SMB_QUERY_FILE_STADNDARD_INFO call.
+****************************************************************************/
+
+NTSTATUS cli_qpathinfo_standard(struct cli_state *cli, const char *fname,
+                               uint64_t *allocated, uint64_t *size,
+                               uint32_t *nlinks,
+                               bool *is_del_pending, bool *is_dir)
+{
+       uint8_t *rdata;
+       uint32_t num_rdata;
+       NTSTATUS status;
+
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       status = cli_qpathinfo(talloc_tos(), cli, fname,
+                              SMB_QUERY_FILE_STANDARD_INFO,
+                              24, CLI_BUFFER_SIZE, &rdata, &num_rdata);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (allocated) {
+               *allocated = BVAL(rdata, 0);
+       }
+
+       if (size) {
+               *size = BVAL(rdata, 8);
+       }
+
+       if (nlinks) {
+               *nlinks = IVAL(rdata, 16);
+       }
+
+       if (is_del_pending) {
+               *is_del_pending = CVAL(rdata, 20);
+       }
+
+       if (is_dir) {
+               *is_dir = CVAL(rdata, 20);
+       }
+
+       TALLOC_FREE(rdata);
+
+       return NT_STATUS_OK;
+}
+
+
+/* like cli_qpathinfo2 but do not use SMB_QUERY_FILE_ALL_INFO with smb1 */
+NTSTATUS cli_qpathinfo3(struct cli_state *cli, const char *fname,
+                       struct timespec *create_time,
+                       struct timespec *access_time,
+                       struct timespec *write_time,
+                       struct timespec *change_time,
+                       off_t *size, uint16_t *mode,
+                       SMB_INO_T *ino)
+{
+       NTSTATUS status = NT_STATUS_OK;
+       SMB_STRUCT_STAT st = { 0 };
+       uint32_t attr;
+       uint64_t pos;
+
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return cli_qpathinfo2(cli, fname,
+                                     create_time, access_time, write_time, change_time,
+                                     size, mode, ino);
+       }
+
+       if (create_time || access_time || write_time || change_time || mode) {
+               status = cli_qpathinfo_basic(cli, fname, &st, &attr);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       if (size) {
+               status = cli_qpathinfo_standard(cli, fname,
+                                               NULL, &pos, NULL, NULL, NULL);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               *size = pos;
+       }
+
+       if (create_time) {
+               *create_time = st.st_ex_btime;
+       }
+       if (access_time) {
+               *access_time = st.st_ex_atime;
+       }
+       if (write_time) {
+               *write_time = st.st_ex_mtime;
+       }
+       if (change_time) {
+               *change_time = st.st_ex_ctime;
+       }
+       if (mode) {
+               *mode = attr;
+       }
+       if (ino) {
+               *ino = 0;
+       }
+
+       return NT_STATUS_OK;
+}