Skip to content

Commit

Permalink
s3: smbd: Add two new functions in a new file, smb2_posix.c: smb2_pos…
Browse files Browse the repository at this point in the history
…ix_cc_info(), store_smb2_posix_info()

Not yet used.

Signed-off-by: Jeremy Allison <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>

Autobuild-User(master): Andreas Schneider <[email protected]>
Autobuild-Date(master): Tue Feb  1 17:25:45 UTC 2022 on sn-devel-184
  • Loading branch information
jrasamba authored and cryptomilk committed Feb 1, 2022
1 parent 85c6711 commit 2b2b41c
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 0 deletions.
11 changes: 11 additions & 0 deletions source3/smbd/proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
170 changes: 170 additions & 0 deletions source3/smbd/smb2_posix.c
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions source3/wscript_build
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 2b2b41c

Please sign in to comment.