From: Jeremy Allison Date: Thu, 27 Jan 2022 22:17:36 +0000 (-0800) Subject: s3: smbd: Add two new functions in a new file, smb2_posix.c: smb2_posix_cc_info(... X-Git-Tag: tevent-0.12.0~802 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b2b41c8682d0830786e3d69a9875af8b0c98175;p=thirdparty%2Fsamba.git s3: smbd: Add two new functions in a new file, smb2_posix.c: smb2_posix_cc_info(), store_smb2_posix_info() Not yet used. Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Tue Feb 1 17:25:45 UTC 2022 on sn-devel-184 --- diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index c802b05a78f..59a1bbd3e80 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -1331,4 +1331,15 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, files_struct **result, DATA_BLOB *new_cookie); +/* The following definitions come from smbd/smb2_posix.c */ +DATA_BLOB smb2_posix_cc_info(TALLOC_CTX *mem_ctx, + connection_struct *conn, + uint32_t reparse_tag, + const SMB_STRUCT_STAT *psbuf); +DATA_BLOB store_smb2_posix_info(TALLOC_CTX *mem_ctx, + connection_struct *conn, + const SMB_STRUCT_STAT *psbuf, + uint32_t reparse_tag, + uint32_t dos_attributes); + #endif /* _SMBD_PROTO_H_ */ diff --git a/source3/smbd/smb2_posix.c b/source3/smbd/smb2_posix.c new file mode 100644 index 00000000000..3d9e2a617e4 --- /dev/null +++ b/source3/smbd/smb2_posix.c @@ -0,0 +1,170 @@ +/* + Unix SMB/CIFS implementation. + SMB2 POSIX code. + Copyright (C) Jeremy Allison 2022 + + 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 . +*/ + +#include "includes.h" +#include "smbd/smbd.h" +#include "passdb/lookup_sid.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* + * SMB2 POSIX create context return details. + */ +DATA_BLOB smb2_posix_cc_info(TALLOC_CTX *mem_ctx, + connection_struct *conn, + uint32_t reparse_tag, + const SMB_STRUCT_STAT *psbuf) +{ + DATA_BLOB ret_blob = data_blob_null; + struct dom_sid sid_owner; + struct dom_sid sid_group; + size_t owner_sid_size = 0; + size_t group_sid_size = 0; + size_t b_size = 12; + + uid_to_sid(&sid_owner, psbuf->st_ex_uid); + owner_sid_size = ndr_size_dom_sid(&sid_owner, 0); + if (b_size + owner_sid_size < b_size) { + return data_blob_null; + } + b_size += owner_sid_size; + + gid_to_sid(&sid_group, psbuf->st_ex_gid); + group_sid_size = ndr_size_dom_sid(&sid_group, 0); + if (b_size + group_sid_size < b_size) { + return data_blob_null; + } + b_size += group_sid_size; + + ret_blob = data_blob_talloc(mem_ctx, + NULL, + b_size); + if (ret_blob.data == NULL) { + return data_blob_null; + } + + /* number of hard links */ + PUSH_LE_U32(ret_blob.data, 0, psbuf->st_ex_nlink); + + /* Reparse tag if FILE_FLAG_REPARSE is set, else zero. */ + PUSH_LE_U32(ret_blob.data, 4, reparse_tag); + + /* + * Remove type info from mode, leaving only the + * permissions and setuid/gid bits. + */ + PUSH_LE_U32(ret_blob.data, + 8, + unix_perms_to_wire(psbuf->st_ex_mode & ~S_IFMT)); + + /* Now add in the owner and group sids. */ + sid_linearize(ret_blob.data + 12, + b_size - 12, + &sid_owner); + sid_linearize(ret_blob.data + 12 + owner_sid_size, + b_size - owner_sid_size - 12, + &sid_group); + return ret_blob; +} + +/* + * SMB2 POSIX info level. + */ +DATA_BLOB store_smb2_posix_info(TALLOC_CTX *mem_ctx, + connection_struct *conn, + const SMB_STRUCT_STAT *psbuf, + uint32_t reparse_tag, + uint32_t dos_attributes) +{ + uint64_t file_id = SMB_VFS_FS_FILE_ID(conn, psbuf); + DATA_BLOB ret_blob = data_blob_null; + DATA_BLOB cc = smb2_posix_cc_info(mem_ctx, + conn, + reparse_tag, + psbuf); + if (cc.data == NULL) { + return data_blob_null; + } + + if (cc.length + 68 < 68) { + data_blob_free(&cc); + return data_blob_null; + } + + ret_blob = data_blob_talloc(mem_ctx, + NULL, + cc.length + 68); + if (ret_blob.data == NULL) { + data_blob_free(&cc); + return data_blob_null; + } + + /* Timestamps. */ + + /* Birth (creation) time. */ + put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, + (char *)ret_blob.data+0, + psbuf->st_ex_btime); + /* Access time. */ + put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, + (char *)ret_blob.data+8, + psbuf->st_ex_atime); + /* Last write time. */ + put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, + (char *)ret_blob.data+16, + psbuf->st_ex_mtime); + /* Change time. */ + put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, + (char *)ret_blob.data+24, + psbuf->st_ex_ctime); + + /* File size 64 Bit */ + SOFF_T(ret_blob.data,32, get_file_size_stat(psbuf)); + + /* Number of bytes used on disk - 64 Bit */ + SOFF_T(ret_blob.data,40,SMB_VFS_GET_ALLOC_SIZE(conn,NULL,psbuf)); + + /* DOS attributes */ + if (S_ISREG(psbuf->st_ex_mode)) { + PUSH_LE_U32(ret_blob.data, 48, dos_attributes); + } else if (S_ISDIR(psbuf->st_ex_mode)) { + PUSH_LE_U32(ret_blob.data, + 48, + dos_attributes|FILE_ATTRIBUTE_DIRECTORY); + } else { + /* + * All non-directory or regular files are reported + * as reparse points. Client may or may not be able + * to access these. + */ + PUSH_LE_U32(ret_blob.data, + 48, + FILE_ATTRIBUTE_REPARSE_POINT); + } + + /* Add the inode and dev (16 bytes). */ + PUSH_LE_U64(ret_blob.data, 52, file_id); + PUSH_LE_U64(ret_blob.data, 60, psbuf->st_ex_dev); + + /* + * Append a POSIX create context (variable bytes). + */ + memcpy(ret_blob.data + 68, cc.data, cc.length); + data_blob_free(&cc); + return ret_blob; +} diff --git a/source3/wscript_build b/source3/wscript_build index acfc0c56f03..ce6892eb08d 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -675,6 +675,7 @@ bld.SAMBA3_LIBRARY('smbd_base', smbd/smb2_getinfo.c smbd/smb2_setinfo.c smbd/smb2_break.c + smbd/smb2_posix.c smbd/smbXsrv_version.c smbd/smbXsrv_client.c smbd/smbXsrv_session.c