s3: smbd: Add two new functions in a new file, smb2_posix.c: smb2_posix_cc_info(...
authorJeremy Allison <jra@samba.org>
Thu, 27 Jan 2022 22:17:36 +0000 (14:17 -0800)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 1 Feb 2022 17:25:45 +0000 (17:25 +0000)
Not yet used.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Tue Feb  1 17:25:45 UTC 2022 on sn-devel-184

source3/smbd/proto.h
source3/smbd/smb2_posix.c [new file with mode: 0644]
source3/wscript_build

index c802b05a78fa67736d83f82141ad1001a85c3623..59a1bbd3e80bcc9a857affe934b01a7fc8237869 100644 (file)
@@ -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 (file)
index 0000000..3d9e2a6
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+*/
+
+#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;
+}
index acfc0c56f037037f5b3b4233a765a060b1d0c562..ce6892eb08d2b426db238c3b387fad2b292c7e32 100644 (file)
@@ -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