summaryrefslogtreecommitdiff
path: root/source3/modules
diff options
context:
space:
mode:
Diffstat (limited to 'source3/modules')
-rw-r--r--source3/modules/nfs4_acls.c84
-rw-r--r--source3/modules/onefs.h13
-rw-r--r--source3/modules/onefs_acl.c238
-rw-r--r--source3/modules/onefs_streams.c128
-rw-r--r--source3/modules/onefs_system.c2
-rw-r--r--source3/modules/vfs_aixacl2.c2
-rw-r--r--source3/modules/vfs_cap.c5
-rw-r--r--source3/modules/vfs_catia.c4
-rw-r--r--source3/modules/vfs_default.c15
-rw-r--r--source3/modules/vfs_full_audit.c6
-rw-r--r--source3/modules/vfs_onefs.c35
-rw-r--r--source3/modules/vfs_recycle.c10
-rw-r--r--source3/modules/vfs_shadow_copy2.c4
13 files changed, 368 insertions, 178 deletions
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index f411176590..556dad6b5e 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -698,9 +698,10 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
bool result;
SMB_STRUCT_STAT sbuf;
- bool need_chown = False;
+ bool set_acl_as_root = false;
uid_t newUID = (uid_t)-1;
gid_t newGID = (gid_t)-1;
+ int saved_errno;
DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
@@ -728,59 +729,48 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
}
if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
- need_chown = True;
- }
- if (need_chown) {
- if ((newUID == (uid_t)-1
- || newUID == fsp->conn->server_info->utok.uid)) {
- if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
- DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
- strerror(errno)));
- return map_nt_error_from_unix(errno);
- }
-
- DEBUG(10,("chown %s, %u, %u succeeded.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
- if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf))
- return map_nt_error_from_unix(errno);
- need_chown = False;
- } else { /* chown is needed, but _after_ changing acl */
- sbuf.st_uid = newUID; /* OWNER@ in case of e_special */
- sbuf.st_gid = newGID; /* GROUP@ in case of e_special */
+ if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
+ DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
+ strerror(errno)));
+ return map_nt_error_from_unix(errno);
}
+
+ DEBUG(10,("chown %s, %u, %u succeeded.\n",
+ fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+ if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf))
+ return map_nt_error_from_unix(errno);
+
+ /* If we successfully chowned, we know we must
+ * be able to set the acl, so do it as root.
+ */
+ set_acl_as_root = true;
}
}
- if ((security_info_sent & DACL_SECURITY_INFORMATION)!=0 && psd->dacl!=NULL)
- {
- acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
- if (!acl)
- return map_nt_error_from_unix(errno);
+ if (!(security_info_sent & DACL_SECURITY_INFORMATION) || psd->dacl ==NULL) {
+ DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
+ return NT_STATUS_OK;
+ }
- smbacl4_dump_nfs4acl(10, acl);
+ acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
+ if (!acl)
+ return map_nt_error_from_unix(errno);
- result = set_nfs4_native(fsp, acl);
- if (result!=True)
- {
- DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno)));
- return map_nt_error_from_unix(errno);
- }
- } else
- DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
+ smbacl4_dump_nfs4acl(10, acl);
- /* Any chown pending? */
- if (need_chown) {
- DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
- if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
- DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
- strerror(errno)));
- return map_nt_error_from_unix(errno);
- }
- DEBUG(10,("chown#2 %s, %u, %u succeeded.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+ if (set_acl_as_root) {
+ become_root();
+ }
+ result = set_nfs4_native(fsp, acl);
+ saved_errno = errno;
+ if (set_acl_as_root) {
+ unbecome_root();
+ }
+ if (result!=True) {
+ errno = saved_errno;
+ DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno)));
+ return map_nt_error_from_unix(errno);
}
DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n"));
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index 6e5eae3085..9c1c1647ba 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -45,6 +45,14 @@ enum onefs_acl_wire_format
#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false
#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control"
#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true
+#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone"
+#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false
+#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids"
+#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false
+#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list"
+#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL
+#define PARM_IGNORE_SACL "ignore sacl"
+#define PARM_IGNORE_SACL_DEFAULT false
/*
* vfs interface handlers
@@ -93,6 +101,9 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
unsigned int *num_streams,
struct stream_struct **streams);
+int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname,
+ int flags, struct timespec times[3]);
+
NTSTATUS onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, SEC_DESC **ppdesc);
@@ -105,7 +116,7 @@ NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
* Utility functions
*/
NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
- struct ifs_security_descriptor *sd);
+ struct ifs_security_descriptor *sd, int snum);
NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
char **pbase, char **pstream);
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 9258e0cddc..b9ec2d68e0 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -35,7 +35,8 @@ const struct enum_list enum_onefs_acl_wire_format[] = {
* Turn SID into UID/GID and setup a struct ifs_identity
*/
static bool
-onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id, bool is_group)
+onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id,
+ bool is_group)
{
enum ifs_identity_type type = IFS_ID_TYPE_LAST+1;
uid_t uid = 0;
@@ -111,18 +112,137 @@ onefs_identity_to_sid(struct ifs_identity *id, DOM_SID *sid)
return true;
}
+static bool
+onefs_og_to_identity(DOM_SID *sid, struct ifs_identity * ident,
+ bool is_group, int snum)
+{
+ const DOM_SID *b_admin_sid = &global_sid_Builtin_Administrators;
+
+ if (!onefs_sid_to_identity(sid, ident, is_group)) {
+ if (!lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_IGNORE,
+ PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT)) {
+ DEBUG(3, ("Unresolvable SID (%s) found.\n",
+ sid_string_dbg(sid)));
+ return false;
+ }
+ if (!onefs_sid_to_identity(b_admin_sid, ident, is_group)) {
+ return false;
+ }
+ DEBUG(3, ("Mapping unresolvable owner SID (%s) to Builtin "
+ "Administrators group.\n",
+ sid_string_dbg(sid)));
+ }
+ return true;
+}
+
+static bool
+sid_in_ignore_list(DOM_SID * sid, int snum)
+{
+ const char ** sid_list = NULL;
+ DOM_SID match;
+
+ sid_list = lp_parm_string_list(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_IGNORE_LIST,
+ PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT);
+
+ /* Fast path a NULL list */
+ if (!sid_list || *sid_list == NULL)
+ return false;
+
+ while (*sid_list) {
+ if (string_to_sid(&match, *sid_list))
+ if (sid_equal(sid, &match))
+ return true;
+ sid_list++;
+ }
+
+ return false;
+}
+
+/**
+ * Convert a trustee to a struct identity
+ */
+static bool
+onefs_samba_ace_to_ace(SEC_ACE * samba_ace, struct ifs_ace * ace,
+ bool *mapped, int snum)
+{
+ struct ifs_identity ident = {.type=IFS_ID_TYPE_LAST, .id.uid=0};
+
+ SMB_ASSERT(ace);
+ SMB_ASSERT(mapped);
+ SMB_ASSERT(samba_ace);
+
+ if (onefs_sid_to_identity(&samba_ace->trustee, &ident, false)) {
+ *mapped = true;
+ } else {
+
+ SMB_ASSERT(ident.id.uid >= 0);
+
+ /* Ignore the sid if it's in the list */
+ if (sid_in_ignore_list(&samba_ace->trustee, snum)) {
+ DEBUG(3, ("Silently failing to set ACE for SID (%s) "
+ "because it is in the ignore sids list\n",
+ sid_string_dbg(&samba_ace->trustee)));
+ *mapped = false;
+ } else if ((samba_ace->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
+ lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_DENY_EVERYONE,
+ PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT)) {
+ /* If the ace is deny translated to Everyone */
+ DEBUG(3, ("Mapping unresolvable deny ACE SID (%s) "
+ "to Everyone.\n",
+ sid_string_dbg(&samba_ace->trustee)));
+ if (aclu_initialize_identity(&ident,
+ IFS_ID_TYPE_EVERYONE, 0, 0, False) != 0) {
+ DEBUG(2, ("aclu_initialize_identity() "
+ "failed making Everyone\n"));
+ return false;
+ }
+ *mapped = true;
+ } else if (lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_UNMAPPABLE_SIDS_IGNORE,
+ PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT)) {
+ DEBUG(3, ("Silently failing to set ACE for SID (%s) "
+ "because it is unresolvable\n",
+ sid_string_dbg(&samba_ace->trustee)));
+ *mapped = false;
+ } else {
+ /* Fail for lack of a better option */
+ return false;
+ }
+ }
+
+ if (*mapped) {
+ if (aclu_initialize_ace(ace, samba_ace->type,
+ samba_ace->access_mask, samba_ace->flags, 0,
+ &ident))
+ return false;
+
+ if ((ace->trustee.type == IFS_ID_TYPE_CREATOR_OWNER ||
+ ace->trustee.type == IFS_ID_TYPE_CREATOR_GROUP) &&
+ nt4_compatible_acls())
+ ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ }
+
+ return true;
+}
+
/**
* Convert a SEC_ACL to a struct ifs_security_acl
*/
static bool
-onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl)
+onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl,
+ bool * ignore_aces, int snum)
{
int num_aces = 0;
struct ifs_ace *aces = NULL;
- struct ifs_identity temp;
SEC_ACE *samba_aces;
+ bool mapped;
int i, j;
+ SMB_ASSERT(ignore_aces);
+
if ((!acl) || (!samba_acl))
return false;
@@ -134,39 +254,30 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl)
aces = SMB_MALLOC_ARRAY(struct ifs_ace, num_aces);
for (i = 0, j = 0; j < num_aces; i++, j++) {
- if (!onefs_sid_to_identity(&samba_aces[j].trustee,
- &temp, false))
+ if (!onefs_samba_ace_to_ace(&samba_aces[j],
+ &aces[i], &mapped, snum))
goto err_free;
- /*
- * XXX Act like we did pre-Thai: Silently fail setting
- * ACEs for BUILTIN accounts.
- */
- if (temp.id.uid == -1) {
- DEBUG(3, ("Silently failing to set ACE "
- "because our id was == -1.\n"));
+ if (!mapped)
i--;
- continue;
- }
-
- if (aclu_initialize_ace(&aces[i], samba_aces[i].type,
- samba_aces[i].access_mask, samba_aces[i].flags,
- 0, &temp))
- goto err_free;
-
- if ((aces[i].trustee.type == IFS_ID_TYPE_CREATOR_OWNER ||
- aces[i].trustee.type == IFS_ID_TYPE_CREATOR_GROUP) &&
- nt4_compatible_acls())
- aces[i].flags |= IFS_ACE_FLAG_INHERIT_ONLY;
}
num_aces = i;
}
+ /* If aces are given but we cannot apply them due to the reasons
+ * above we do not change the SD. However, if we are told to
+ * explicitly set an SD with 0 aces we honor this operation */
+ *ignore_aces = samba_acl->num_aces > 0 && num_aces < 1;
+
+ if (*ignore_aces == false)
+ if (aclu_initialize_acl(acl, aces, num_aces))
+ goto err_free;
+
if (aclu_initialize_acl(acl, aces, num_aces))
goto err_free;
- /* Currently aclu_initialize_acl should copy the aces over, allowing us
- * to immediately free */
+ /* Currently aclu_initialize_acl should copy the aces over, allowing
+ * us to immediately free */
free(aces);
return true;
@@ -697,10 +808,11 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
* @return NTSTATUS_OK if successful
*/
NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
- struct ifs_security_descriptor *sd)
+ struct ifs_security_descriptor *sd, int snum)
{
- struct ifs_security_acl dacl, sacl, *daclp, *saclp;
+ struct ifs_security_acl *daclp, *saclp;
struct ifs_identity owner, group, *ownerp, *groupp;
+ bool ignore_aces;
ownerp = NULL;
groupp = NULL;
@@ -709,58 +821,53 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
/* Setup owner */
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
- if (!onefs_sid_to_identity(psd->owner_sid, &owner, false))
+ if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum))
return NT_STATUS_UNSUCCESSFUL;
- /*
- * XXX Act like we did pre-Thai: Silently fail setting the
- * owner to a BUILTIN account.
- */
- if (owner.id.uid == -1) {
- DEBUG(3, ("Silently failing to set owner because our "
- "id was == -1.\n"));
- security_info_sent &= ~OWNER_SECURITY_INFORMATION;
- if (!security_info_sent)
- return NT_STATUS_OK;
- }
- else
- ownerp = &owner;
+ SMB_ASSERT(owner.id.uid >= 0);
+
+ ownerp = &owner;
}
/* Setup group */
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
- if (!onefs_sid_to_identity(psd->group_sid, &group, true))
+ if (!onefs_og_to_identity(psd->group_sid, &group, true, snum))
return NT_STATUS_UNSUCCESSFUL;
- /*
- * XXX Act like we did pre-Thai: Silently fail setting the
- * group to a BUILTIN account.
- */
- if (group.id.gid == -1) {
- DEBUG(3, ("Silently failing to set group because our "
- "id was == -1.\n"));
- security_info_sent &= ~GROUP_SECURITY_INFORMATION;
- if (!security_info_sent)
- return NT_STATUS_OK;
- }
- else
- groupp = &group;
+ SMB_ASSERT(group.id.gid >= 0);
+
+ groupp = &group;
}
/* Setup DACL */
if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) {
- daclp = &dacl;
-
- if (!onefs_samba_acl_to_acl(psd->dacl, &daclp))
+ if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces,
+ snum))
return NT_STATUS_UNSUCCESSFUL;
+
+ if (ignore_aces == true)
+ security_info_sent &= ~DACL_SECURITY_INFORMATION;
}
/* Setup SACL */
- if ((security_info_sent & SACL_SECURITY_INFORMATION) && (psd->sacl)) {
- saclp = &sacl;
-
- if (!onefs_samba_acl_to_acl(psd->sacl, &saclp))
- return NT_STATUS_UNSUCCESSFUL;
+ if (security_info_sent & SACL_SECURITY_INFORMATION) {
+
+ if (lp_parm_bool(snum, PARM_ONEFS_TYPE,
+ PARM_IGNORE_SACL, PARM_IGNORE_SACL_DEFAULT)) {
+ DEBUG(5, ("Ignoring SACLs.\n"));
+ security_info_sent &= ~SACL_SECURITY_INFORMATION;
+ } else {
+ if (psd->sacl) {
+ if (!onefs_samba_acl_to_acl(psd->sacl,
+ &saclp, &ignore_aces, snum))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ if (ignore_aces == true) {
+ security_info_sent &=
+ ~SACL_SECURITY_INFORMATION;
+ }
+ }
+ }
}
/* Setup ifs_security_descriptor */
@@ -789,7 +896,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
- status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd);
+ status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd,
+ SNUM(handle->conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("SD initialization failure: %s", nt_errstr(status)));
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 184fe4f0c9..e9543e237f 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -51,6 +51,25 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
return NT_STATUS_OK;
}
+int onefs_is_stream(const char *path, char **pbase, char **pstream,
+ bool *is_stream)
+{
+ (*is_stream) = is_ntfs_stream_name(path);
+
+ if (!(*is_stream)) {
+ return 0;
+ }
+
+ if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
+ pbase, pstream))) {
+ DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return 0;
+}
+
int onefs_close(vfs_handle_struct *handle, struct files_struct *fsp)
{
int ret2, ret = 0;
@@ -141,27 +160,18 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname,
char *nbase = NULL;
char *nsname = NULL;
- old_is_stream = is_ntfs_stream_name(oldname);
- new_is_stream = is_ntfs_stream_name(newname);
-
- if (!old_is_stream && !new_is_stream) {
- return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
- }
-
frame = talloc_stackframe();
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(),
- oldname, &obase,
- &osname))) {
- errno = ENOMEM;
- goto done;
- }
+ ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream);
+ if (ret)
+ return ret;
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(),
- newname, &nbase,
- &nsname))) {
- errno = ENOMEM;
- goto done;
+ ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream);
+ if (ret)
+ return ret;
+
+ if (!old_is_stream && !new_is_stream) {
+ return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
}
dir_fd = get_stream_dir_fd(handle->conn, obase, NULL);
@@ -237,18 +247,17 @@ static int stat_stream(vfs_handle_struct *handle, const char *base,
int onefs_stat(vfs_handle_struct *handle, const char *path,
SMB_STRUCT_STAT *sbuf)
{
+ int ret;
+ bool is_stream;
char *base = NULL;
char *stream = NULL;
- if (!is_ntfs_stream_name(path)) {
- return SMB_VFS_NEXT_STAT(handle, path, sbuf);
- }
+ ret = onefs_is_stream(path, &base, &stream, &is_stream);
+ if (ret)
+ return ret;
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
+ if (!is_stream) {
+ return SMB_VFS_NEXT_STAT(handle, path, sbuf);
}
/* If it's the ::$DATA stream just stat the base file name. */
@@ -285,18 +294,17 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
int onefs_lstat(vfs_handle_struct *handle, const char *path,
SMB_STRUCT_STAT *sbuf)
{
+ int ret;
+ bool is_stream;
char *base = NULL;
char *stream = NULL;
- if (!is_ntfs_stream_name(path)) {
- return SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
- }
+ ret = onefs_is_stream(path, &base, &stream, &is_stream);
+ if (ret)
+ return ret;
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
+ if (!is_stream) {
+ return SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
}
/* If it's the ::$DATA stream just stat the base file name. */
@@ -309,19 +317,19 @@ int onefs_lstat(vfs_handle_struct *handle, const char *path,
int onefs_unlink(vfs_handle_struct *handle, const char *path)
{
+ int ret;
+ bool is_stream;
char *base = NULL;
char *stream = NULL;
- int dir_fd, ret, saved_errno;
+ int dir_fd, saved_errno;
- if (!is_ntfs_stream_name(path)) {
- return SMB_VFS_NEXT_UNLINK(handle, path);
+ ret = onefs_is_stream(path, &base, &stream, &is_stream);
+ if (ret) {
+ return ret;
}
- if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path,
- &base, &stream))) {
- DEBUG(10, ("onefs_split_ntfs_stream_name failed\n"));
- errno = ENOMEM;
- return -1;
+ if (!is_stream) {
+ return SMB_VFS_NEXT_UNLINK(handle, path);
}
/* If it's the ::$DATA stream just unlink the base file name. */
@@ -342,6 +350,42 @@ int onefs_unlink(vfs_handle_struct *handle, const char *path)
return ret;
}
+int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname,
+ int flags, struct timespec times[3])
+{
+ int ret;
+ bool is_stream;
+ char *base;
+ char *stream;
+ int dirfd;
+ int saved_errno;
+
+ START_PROFILE(syscall_ntimes);
+
+ ret = onefs_is_stream(fname, &base, &stream, &is_stream);
+ if (ret)
+ return ret;
+
+ if (!is_stream) {
+ ret = vtimes(fname, times, flags);
+ return ret;
+ }
+
+ dirfd = get_stream_dir_fd(handle->conn, base, NULL);
+ if (dirfd < -1) {
+ return -1;
+ }
+
+ ret = enc_vtimesat(dirfd, stream, ENC_DEFAULT, times, flags);
+
+ END_PROFILE(syscall_ntimes);
+
+ saved_errno = errno;
+ close(dirfd);
+ errno = saved_errno;
+ return ret;
+}
+
int onefs_chflags(vfs_handle_struct *handle, const char *path,
unsigned int flags)
{
diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c
index ee257d8f90..4ebdf12a50 100644
--- a/source3/modules/onefs_system.c
+++ b/source3/modules/onefs_system.c
@@ -152,7 +152,7 @@ int onefs_sys_create_file(connection_struct *conn,
secinfo = (get_sec_info(sd) & IFS_SEC_INFO_KNOWN_MASK);
- status = onefs_samba_sd_to_sd(secinfo, sd, &ifs_sd);
+ status = onefs_samba_sd_to_sd(secinfo, sd, &ifs_sd, SNUM(conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("SD initialization failure: %s",
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index a078b9f9f6..5ebc3a12f8 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -25,8 +25,6 @@
#define AIXACL2_MODULE_NAME "aixacl2"
-extern int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid);
-
extern SMB_ACL_T aixacl_to_smbacl( struct acl *file_acl);
extern struct acl *aixacl_smb_to_aixacl(SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 6950ab2168..ac85d3a804 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -208,7 +208,8 @@ static int cap_chdir(vfs_handle_struct *handle, const char *path)
return SMB_VFS_NEXT_CHDIR(handle, cappath);
}
-static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
+static int cap_ntimes(vfs_handle_struct *handle, const char *path,
+ struct smb_file_time *ft)
{
char *cappath = capencode(talloc_tos(), path);
@@ -216,7 +217,7 @@ static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_NTIMES(handle, cappath, ts);
+ return SMB_VFS_NEXT_NTIMES(handle, cappath, ft);
}
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 47d178a33f..d0c341fdd3 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -252,9 +252,9 @@ static char *catia_getwd(vfs_handle_struct *handle, char *buf)
}
static int catia_ntimes(vfs_handle_struct *handle,
- const char *path, const struct timespec ts[2])
+ const char *path, struct smb_file_time *ft)
{
- return SMB_VFS_NEXT_NTIMES(handle, path, ts);
+ return SMB_VFS_NEXT_NTIMES(handle, path, ft);
}
static bool catia_symlink(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 61e1deb81e..a9aabab768 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -682,25 +682,26 @@ static char *vfswrap_getwd(vfs_handle_struct *handle, char *path)
system will support.
**********************************************************************/
-static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2])
+static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
+ struct smb_file_time *ft)
{
int result;
START_PROFILE(syscall_ntimes);
#if defined(HAVE_UTIMES)
- if (ts != NULL) {
+ if (ft != NULL) {
struct timeval tv[2];
- tv[0] = convert_timespec_to_timeval(ts[0]);
- tv[1] = convert_timespec_to_timeval(ts[1]);
+ tv[0] = convert_timespec_to_timeval(ft->atime);
+ tv[1] = convert_timespec_to_timeval(ft->mtime);
result = utimes(path, tv);
} else {
result = utimes(path, NULL);
}
#elif defined(HAVE_UTIME)
- if (ts != NULL) {
+ if (ft != NULL) {
struct utimbuf times;
- times.actime = convert_timespec_to_time_t(ts[0]);
- times.modtime = convert_timespec_to_time_t(ts[1]);
+ times.actime = convert_timespec_to_time_t(ft->atime);
+ times.modtime = convert_timespec_to_time_t(ft->mtime);
result = utime(path, times);
} else {
result = utime(path, NULL);
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 1d9983a753..73758a2d9d 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -172,7 +172,7 @@ static int smb_full_audit_chdir(vfs_handle_struct *handle,
static char *smb_full_audit_getwd(vfs_handle_struct *handle,
char *path);
static int smb_full_audit_ntimes(vfs_handle_struct *handle,
- const char *path, const struct timespec ts[2]);
+ const char *path, struct smb_file_time *ft);
static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
SMB_OFF_T len);
static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
@@ -1426,11 +1426,11 @@ static char *smb_full_audit_getwd(vfs_handle_struct *handle,
}
static int smb_full_audit_ntimes(vfs_handle_struct *handle,
- const char *path, const struct timespec ts[2])
+ const char *path, struct smb_file_time *ft)
{
int result;
- result = SMB_VFS_NEXT_NTIMES(handle, path, ts);
+ result = SMB_VFS_NEXT_NTIMES(handle, path, ft);
do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s", path);
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index 6b42c0f373..e048e89589 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -66,6 +66,39 @@ static int onefs_statvfs(vfs_handle_struct *handle, const char *path,
return result;
}
+static int onefs_ntimes(vfs_handle_struct *handle, const char *fname,
+ struct smb_file_time *ft)
+{
+ int flags = 0;
+ struct timespec times[3];
+
+ if (!null_timespec(ft->atime)) {
+ flags |= VT_ATIME;
+ times[0] = ft->atime;
+ DEBUG(6,("**** onefs_ntimes: actime: %s.%d\n",
+ time_to_asc(convert_timespec_to_time_t(ft->atime)),
+ ft->atime.tv_nsec));
+ }
+
+ if (!null_timespec(ft->mtime)) {
+ flags |= VT_MTIME;
+ times[1] = ft->mtime;
+ DEBUG(6,("**** onefs_ntimes: modtime: %s.%d\n",
+ time_to_asc(convert_timespec_to_time_t(ft->mtime)),
+ ft->mtime.tv_nsec));
+ }
+
+ if (!null_timespec(ft->create_time)) {
+ flags |= VT_BTIME;
+ times[2] = ft->create_time;
+ DEBUG(6,("**** onefs_ntimes: createtime: %s.%d\n",
+ time_to_asc(convert_timespec_to_time_t(ft->create_time)),
+ ft->create_time.tv_nsec));
+ }
+
+ return onefs_vtimes_streams(handle, fname, flags, times);
+}
+
static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
{
return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
@@ -92,6 +125,8 @@ static vfs_op_tuple onefs_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(onefs_ntimes), SMB_VFS_OP_NTIMES,
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_chflags), SMB_VFS_OP_CHFLAGS,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_streaminfo), SMB_VFS_OP_STREAMINFO,
diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c
index cb985e1be2..2b0edcdb4a 100644
--- a/source3/modules/vfs_recycle.c
+++ b/source3/modules/vfs_recycle.c
@@ -391,19 +391,21 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname,
bool touch_mtime)
{
SMB_STRUCT_STAT st;
- struct timespec ts[2];
+ struct smb_file_time ft;
int ret, err;
+ ZERO_STRUCT(ft);
+
if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) {
DEBUG(0,("recycle: stat for %s returned %s\n",
fname, strerror(errno)));
return;
}
- ts[0] = timespec_current(); /* atime */
- ts[1] = touch_mtime ? ts[0] : get_mtimespec(&st); /* mtime */
+ ft.atime = timespec_current(); /* atime */
+ ft.mtime = touch_mtime ? ft.atime : get_mtimespec(&st); /* mtime */
become_root();
- ret = SMB_VFS_NEXT_NTIMES(handle, fname, ts);
+ ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft);
err = errno;
unbecome_root();
if (ret == -1 ) {
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index c95600b642..56dd6ea8d8 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -393,9 +393,9 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle,
}
static int shadow_copy2_ntimes(vfs_handle_struct *handle,
- const char *fname, const struct timespec ts[2])
+ const char *fname, struct smb_file_time *ft)
{
- SHADOW2_NEXT(NTIMES, (handle, name, ts), int, -1);
+ SHADOW2_NEXT(NTIMES, (handle, name, ft), int, -1);
}
static int shadow_copy2_readlink(vfs_handle_struct *handle,