The branch, master has been updated via 9c316623e5f libsmb: Extend cli_mknod to create NFS reparse points via af5756df6c5 libsmb: Remove reparse_symlink.c via e5d724ca883 libsmb: Use reparse_data_buffer_marshall() in py_reparse_put() via 1f21be8286b libsmb: Use reparse_data_buffer_marshall() in cli_symlink_send() via d19a28fdb4d libsmb: Factor out cli_create_reparse_point() from cli_symlink() via 41274da949e libsmb: Use reparse_data_buffer_marshall() in py_reparse_symlink_put() via ddc1f56cf1a libsmb: Add reparse_data_buffer_marshall() via 815ff26db28 smbclient: Add mkfifo command via 88258e17738 libsmb: Add sync cli_mknod() for smbclient3's use from e58805fe7f7 s3:tests: Check if test_smbclient_kerberos.sh was successful
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 9c316623e5f3cde9dc88cef5992843d233e139c0 Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 21 16:56:55 2023 -0700 libsmb: Extend cli_mknod to create NFS reparse points Tested smbclient mkfifo manually against W2k22, the Windows NFS server reports this as FIFO. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Mon Sep 25 18:08:01 UTC 2023 on atb-devel-224 commit af5756df6c51537e4adf36ca524d4ca671a191ee Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 21 07:40:43 2023 -0700 libsmb: Remove reparse_symlink.c Makes reparse_buffer_marshall static to reparse.c Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit e5d724ca88338798dcc22062585473a20506f1fc Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 21 07:33:15 2023 -0700 libsmb: Use reparse_data_buffer_marshall() in py_reparse_put() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 1f21be8286ba8459604a603490b2d9d60188765c Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 21 07:23:41 2023 -0700 libsmb: Use reparse_data_buffer_marshall() in cli_symlink_send() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit d19a28fdb4d05f8ac001d1a00415feb72df56c10 Author: Volker Lendecke <v...@samba.org> Date: Wed Sep 20 16:54:40 2023 -0700 libsmb: Factor out cli_create_reparse_point() from cli_symlink() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 41274da949ee07464d7a95a386d2f084ec8e796a Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 21 06:45:49 2023 -0700 libsmb: Use reparse_data_buffer_marshall() in py_reparse_symlink_put() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ddc1f56cf1a6e7b9f2e07b72fbe842c3de3122a4 Author: Volker Lendecke <v...@samba.org> Date: Thu Sep 21 04:27:34 2023 -0700 libsmb: Add reparse_data_buffer_marshall() Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 815ff26db28d755683af4c61005ad2de44e1b409 Author: Volker Lendecke <v...@samba.org> Date: Wed Jul 5 09:25:14 2023 +0200 smbclient: Add mkfifo command Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 88258e17738d742634d12150e1c951cceb458ff5 Author: Volker Lendecke <v...@samba.org> Date: Wed Jul 5 09:06:58 2023 +0200 libsmb: Add sync cli_mknod() for smbclient3's use Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: libcli/smb/py_reparse_symlink.c | 62 +++++++----- libcli/smb/reparse.c | 218 ++++++++++++++++++++++++++++++++++++++++ libcli/smb/reparse.h | 4 + libcli/smb/reparse_symlink.c | 167 ------------------------------ libcli/smb/reparse_symlink.h | 47 --------- libcli/smb/wscript | 1 - source3/client/client.c | 59 +++++++++++ source3/libsmb/clifile.c | 91 ++++++++++++++++- source3/libsmb/clisymlink.c | 203 +++++++++++++++++++++++++------------ source3/libsmb/proto.h | 9 ++ source3/libsmb/pylibsmb.c | 1 - 11 files changed, 554 insertions(+), 308 deletions(-) delete mode 100644 libcli/smb/reparse_symlink.c delete mode 100644 libcli/smb/reparse_symlink.h Changeset truncated at 500 lines: diff --git a/libcli/smb/py_reparse_symlink.c b/libcli/smb/py_reparse_symlink.c index 7aecc4fd38a..93e5cf8f049 100644 --- a/libcli/smb/py_reparse_symlink.c +++ b/libcli/smb/py_reparse_symlink.c @@ -22,7 +22,7 @@ #include "python/py3compat.h" #include "libcli/util/pyerrors.h" #include "reparse.h" -#include "reparse_symlink.h" +#include "lib/util/iov_buf.h" #include "smb_constants.h" static PyObject *py_reparse_put(PyObject *module, PyObject *args) @@ -31,10 +31,10 @@ static PyObject *py_reparse_put(PyObject *module, PyObject *args) Py_ssize_t reparse_len; unsigned long long tag = 0; unsigned reserved = 0; - struct iovec iov; uint8_t *buf = NULL; ssize_t buflen; PyObject *result = NULL; + struct reparse_data_buffer reparse_buf = {}; bool ok; ok = PyArg_ParseTuple( @@ -47,11 +47,13 @@ static PyObject *py_reparse_put(PyObject *module, PyObject *args) if (!ok) { return NULL; } - iov = (struct iovec) { - .iov_base = reparse, .iov_len = reparse_len, - }; - buflen = reparse_buffer_marshall(tag, reserved, &iov, 1, NULL, 0); + reparse_buf.tag = tag; + reparse_buf.parsed.raw.data = (uint8_t *)reparse; + reparse_buf.parsed.raw.length = reparse_len; + reparse_buf.parsed.raw.reserved = reserved; + + buflen = reparse_data_buffer_marshall(&reparse_buf, NULL, 0); if (buflen == -1) { errno = EINVAL; PyErr_SetFromErrno(PyExc_RuntimeError); @@ -62,7 +64,7 @@ static PyObject *py_reparse_put(PyObject *module, PyObject *args) PyErr_NoMemory(); return NULL; } - reparse_buffer_marshall(tag, reserved, &iov, 1, buf, buflen); + reparse_data_buffer_marshall(&reparse_buf, buf, buflen); result = PyBytes_FromStringAndSize((char *)buf, buflen); TALLOC_FREE(buf); @@ -71,35 +73,47 @@ static PyObject *py_reparse_put(PyObject *module, PyObject *args) static PyObject *py_reparse_symlink_put(PyObject *module, PyObject *args) { - char *substitute = NULL; - char *printname = NULL; int unparsed = 0; int flags = 0; - uint8_t *buf = NULL; - size_t buflen; + struct reparse_data_buffer reparse = { + .tag = IO_REPARSE_TAG_SYMLINK, + }; + struct symlink_reparse_struct *lnk = &reparse.parsed.lnk; + uint8_t stackbuf[1024]; + uint8_t *buf = stackbuf; + ssize_t buflen = sizeof(stackbuf); PyObject *result = NULL; bool ok; - ok = PyArg_ParseTuple( - args, - "ssii:symlink_put", - &substitute, - &printname, - &unparsed, - &flags); + ok = PyArg_ParseTuple(args, + "ssii:symlink_put", + &lnk->substitute_name, + &lnk->print_name, + &unparsed, + &flags); if (!ok) { return NULL; } + lnk->unparsed_path_length = unparsed; + lnk->flags = flags; - ok = symlink_reparse_buffer_marshall( - substitute, printname, unparsed, flags, NULL, &buf, &buflen); - if (!ok) { + buflen = reparse_data_buffer_marshall(&reparse, buf, buflen); + + if ((buflen > 0) && ((size_t)buflen > sizeof(stackbuf))) { + buf = malloc(buflen); + buflen = reparse_data_buffer_marshall(&reparse, buf, buflen); + } + + if (buflen == -1) { PyErr_NoMemory(); - return false; + } else { + result = PyBytes_FromStringAndSize((char *)buf, buflen); + } + + if (buf != stackbuf) { + free(buf); } - result = PyBytes_FromStringAndSize((char *)buf, buflen); - TALLOC_FREE(buf); return result; } diff --git a/libcli/smb/reparse.c b/libcli/smb/reparse.c index 1c4ad444bfc..1a6feff17e1 100644 --- a/libcli/smb/reparse.c +++ b/libcli/smb/reparse.c @@ -17,10 +17,12 @@ #include "replace.h" #include "libcli/smb/reparse.h" +#include "lib/util/iov_buf.h" #include "libcli/smb/smb_constants.h" #include "libcli/util/error.h" #include "lib/util/debug.h" #include "lib/util/bytearray.h" +#include "lib/util/talloc_stack.h" #include "lib/util/charset/charset.h" #include "smb_util.h" @@ -346,3 +348,219 @@ char *reparse_data_buffer_str(TALLOC_CTX *mem_ctx, } return s; } + +static ssize_t reparse_buffer_marshall(uint32_t reparse_tag, + uint16_t reserved, + const struct iovec *iov, + int iovlen, + uint8_t *buf, + size_t buflen) +{ + ssize_t reparse_data_length = iov_buflen(iov, iovlen); + size_t needed; + + if (reparse_data_length == -1) { + return -1; + } + if (reparse_data_length > UINT16_MAX) { + return -1; + } + + needed = reparse_data_length + 8; + if (needed < reparse_data_length) { + return -1; + } + + if (buflen >= needed) { + PUSH_LE_U32(buf, 0, reparse_tag); + PUSH_LE_U16(buf, 4, reparse_data_length); + PUSH_LE_U16(buf, 6, reserved); + iov_buf(iov, iovlen, buf + 8, buflen - 8); + } + + return needed; +} + +static ssize_t +reparse_data_buffer_marshall_syml(const struct symlink_reparse_struct *src, + uint8_t *buf, + size_t buflen) +{ + uint8_t sbuf[12]; + struct iovec iov[3]; + uint8_t *subst_utf16 = NULL; + uint8_t *print_utf16 = NULL; + size_t subst_len = 0; + size_t print_len = 0; + ssize_t ret = -1; + bool ok; + + if (src->substitute_name == NULL) { + return -1; + } + if (src->print_name == NULL) { + return -1; + } + + iov[0] = (struct iovec){ + .iov_base = sbuf, + .iov_len = sizeof(sbuf), + }; + + ok = convert_string_talloc(talloc_tos(), + CH_UNIX, + CH_UTF16, + src->substitute_name, + strlen(src->substitute_name), + &subst_utf16, + &subst_len); + if (!ok) { + goto fail; + } + if (subst_len > UINT16_MAX) { + goto fail; + } + iov[1] = (struct iovec){ + .iov_base = subst_utf16, + .iov_len = subst_len, + }; + + ok = convert_string_talloc(talloc_tos(), + CH_UNIX, + CH_UTF16, + src->print_name, + strlen(src->print_name), + &print_utf16, + &print_len); + if (!ok) { + goto fail; + } + if (print_len > UINT16_MAX) { + goto fail; + } + iov[2] = (struct iovec){ + .iov_base = print_utf16, + .iov_len = print_len, + }; + + PUSH_LE_U16(sbuf, 0, 0); /* SubstituteNameOffset */ + PUSH_LE_U16(sbuf, 2, subst_len); /* SubstituteNameLength */ + PUSH_LE_U16(sbuf, 4, subst_len); /* PrintNameOffset */ + PUSH_LE_U16(sbuf, 6, print_len); /* PrintNameLength */ + PUSH_LE_U32(sbuf, 8, src->flags); /* Flags */ + + ret = reparse_buffer_marshall(IO_REPARSE_TAG_SYMLINK, + src->unparsed_path_length, + iov, + ARRAY_SIZE(iov), + buf, + buflen); + +fail: + TALLOC_FREE(subst_utf16); + TALLOC_FREE(print_utf16); + return ret; +} + +static ssize_t +reparse_data_buffer_marshall_nfs(const struct nfs_reparse_data_buffer *src, + uint8_t *buf, + size_t buflen) +{ + uint8_t typebuf[8]; + uint8_t devbuf[8]; + struct iovec iov[2] = {}; + size_t iovlen; + uint8_t *lnk_utf16 = NULL; + size_t lnk_len = 0; + ssize_t ret; + + PUSH_LE_U64(typebuf, 0, src->type); + iov[0] = (struct iovec){ + .iov_base = typebuf, + .iov_len = sizeof(typebuf), + }; + iovlen = 1; + + switch (src->type) { + case NFS_SPECFILE_LNK: { + bool ok = convert_string_talloc(talloc_tos(), + CH_UNIX, + CH_UTF16, + src->data.lnk_target, + strlen(src->data.lnk_target), + &lnk_utf16, + &lnk_len); + if (!ok) { + return -1; + } + iov[1] = (struct iovec){ + .iov_base = lnk_utf16, + .iov_len = lnk_len, + }; + iovlen = 2; + break; + } + case NFS_SPECFILE_CHR: + FALL_THROUGH; + case NFS_SPECFILE_BLK: + PUSH_LE_U32(devbuf, 0, src->data.dev.major); + PUSH_LE_U32(devbuf, 4, src->data.dev.minor); + iov[1] = (struct iovec){ + .iov_base = devbuf, + .iov_len = sizeof(devbuf), + }; + iovlen = 2; + break; + default: + break; + /* Nothing to do for NFS_SPECFILE_FIFO and _SOCK */ + } + + ret = reparse_buffer_marshall(IO_REPARSE_TAG_NFS, + 0, + iov, + iovlen, + buf, + buflen); + TALLOC_FREE(lnk_utf16); + return ret; +} + +ssize_t reparse_data_buffer_marshall(const struct reparse_data_buffer *src, + uint8_t *buf, + size_t buflen) +{ + ssize_t ret = -1; + + switch (src->tag) { + case IO_REPARSE_TAG_SYMLINK: + + ret = reparse_data_buffer_marshall_syml(&src->parsed.lnk, + buf, + buflen); + break; + + case IO_REPARSE_TAG_NFS: + + ret = reparse_data_buffer_marshall_nfs(&src->parsed.nfs, + buf, + buflen); + break; + + default: { + struct iovec iov = { + .iov_base = src->parsed.raw.data, + .iov_len = src->parsed.raw.length, + }; + ret = reparse_buffer_marshall(src->tag, + src->parsed.raw.reserved, + &iov, + 1, + buf, + buflen); + } + } + + return ret; +} diff --git a/libcli/smb/reparse.h b/libcli/smb/reparse.h index aeeaf116eba..1e593272a66 100644 --- a/libcli/smb/reparse.h +++ b/libcli/smb/reparse.h @@ -70,4 +70,8 @@ NTSTATUS reparse_data_buffer_parse(TALLOC_CTX *mem_ctx, char *reparse_data_buffer_str(TALLOC_CTX *mem_ctx, const struct reparse_data_buffer *dst); +ssize_t reparse_data_buffer_marshall(const struct reparse_data_buffer *src, + uint8_t *buf, + size_t buflen); + #endif diff --git a/libcli/smb/reparse_symlink.c b/libcli/smb/reparse_symlink.c deleted file mode 100644 index b99cca261d7..00000000000 --- a/libcli/smb/reparse_symlink.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * Implementation of - * http://msdn.microsoft.com/en-us/library/cc232006%28v=PROT.13%29.aspx - * - * Copyright (C) Volker Lendecke 2011 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "replace.h" -#include "reparse_symlink.h" -#include "lib/util/charset/charset.h" -#include "lib/util/bytearray.h" -#include "libcli/smb/smb_constants.h" -#include "libcli/smb/smb_util.h" -#include "lib/util/debug.h" - -ssize_t reparse_buffer_marshall( - uint32_t reparse_tag, - uint16_t reserved, - const struct iovec *iov, - int iovlen, - uint8_t *buf, - size_t buflen) -{ - ssize_t reparse_data_length = iov_buflen(iov, iovlen); - size_t needed; - - if (reparse_data_length == -1) { - return -1; - } - if (reparse_data_length > UINT16_MAX) { - return -1; - } - - needed = reparse_data_length + 8; - if (needed < reparse_data_length) { - return -1; - } - - if (buflen >= needed) { - PUSH_LE_U32(buf, 0, reparse_tag); - PUSH_LE_U16(buf, 4, reparse_data_length); - PUSH_LE_U16(buf, 6, reserved); - iov_buf(iov, iovlen, buf+8, buflen-8); - } - - return needed; -} - -bool symlink_reparse_buffer_marshall( - const char *substitute, - const char *printname, - uint16_t unparsed_path_length, - uint32_t flags, - TALLOC_CTX *mem_ctx, - uint8_t **pdst, - size_t *pdstlen) -{ - uint8_t sbuf[12]; - struct iovec iov[3]; - uint8_t *dst = NULL; - ssize_t dst_len; - uint8_t *subst_utf16 = NULL; - uint8_t *print_utf16 = NULL; - size_t subst_len = 0; - size_t print_len = 0; - bool ret = false; - bool ok; - - if (substitute == NULL) { - return false; - } - if (printname == NULL) { - printname = substitute; - } - - iov[0] = (struct iovec) { .iov_base = sbuf, .iov_len = sizeof(sbuf), }; - - ok = convert_string_talloc( - mem_ctx, - CH_UNIX, - CH_UTF16, - substitute, - strlen(substitute), - &subst_utf16, - &subst_len); - if (!ok) { - goto fail; - } - if (subst_len > UINT16_MAX) { - goto fail; - } - iov[1] = (struct iovec) { - .iov_base = subst_utf16, .iov_len = subst_len, - }; - - ok = convert_string_talloc( - mem_ctx, - CH_UNIX, - CH_UTF16, - printname, - strlen(printname), - &print_utf16, - &print_len); - if (!ok) { - goto fail; - } - if (print_len > UINT16_MAX) { - goto fail; - } - iov[2] = (struct iovec) { - .iov_base = print_utf16, .iov_len = print_len, - }; -- Samba Shared Repository