#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
+/*******************************************************************
+ Parse out a struct security_descriptor from a DATA_BLOB.
+*******************************************************************/
+
static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
- const struct timespec cts,
uint32 security_info,
struct security_descriptor **ppdesc)
{
return NT_STATUS_REVISION_MISMATCH;
}
-#if 0
- {
- struct timespec ts;
- /* Arg. This doesn't work. Too many activities
- * change the ctime. May have to roll back to
- * version 1.
- */
- /*
- * Check that the ctime timestamp is ealier
- * than the stored timestamp.
- */
-
- ts = nt_time_to_unix_timespec(&xacl.info.sd_ts->last_changed);
-
- if (timespec_compare(&cts, &ts) > 0) {
- DEBUG(5, ("parse_acl_blob: stored ACL out of date "
- "(%s > %s.\n",
- timestring(ctx, cts.tv_sec),
- timestring(ctx, ts.tv_sec)));
- return NT_STATUS_EA_CORRUPT_ERROR;
- }
- }
-#endif
-
- *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_ts->sd->type | SEC_DESC_SELF_RELATIVE,
+ *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE,
(security_info & OWNER_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->owner_sid : NULL,
+ ? xacl.info.sd_hs->sd->owner_sid : NULL,
(security_info & GROUP_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->group_sid : NULL,
+ ? xacl.info.sd_hs->sd->group_sid : NULL,
(security_info & SACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->sacl : NULL,
+ ? xacl.info.sd_hs->sd->sacl : NULL,
(security_info & DACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->dacl : NULL,
+ ? xacl.info.sd_hs->sd->dacl : NULL,
&sd_size);
TALLOC_FREE(xacl.info.sd);
return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
+/*******************************************************************
+ Pull a security descriptor into a DATA_BLOB from a xattr.
+*******************************************************************/
+
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
vfs_handle_struct *handle,
files_struct *fsp,
return NT_STATUS_OK;
}
+/*******************************************************************
+ Create a DATA_BLOB from a security descriptor.
+*******************************************************************/
+
static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
{
struct xattr_NTACL xacl;
- struct security_descriptor_timestamp sd_ts;
+ struct security_descriptor_hash sd_hs;
enum ndr_err_code ndr_err;
TALLOC_CTX *ctx = talloc_tos();
- struct timespec curr = timespec_current();
ZERO_STRUCT(xacl);
- ZERO_STRUCT(sd_ts);
-
- /* Horrid hack as setting an xattr changes the ctime
- * on Linux. This gives a race of 1 second during
- * which we would not see a POSIX ACL set.
- */
- curr.tv_sec += 1;
+ ZERO_STRUCT(sd_hs);
xacl.version = 2;
- xacl.info.sd_ts = &sd_ts;
- xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd);
- unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
-
- DEBUG(10, ("create_acl_blob: timestamp stored as %s\n",
- timestring(ctx, curr.tv_sec) ));
+ xacl.info.sd_hs = &sd_hs;
+ xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd);
+ memset(&xacl.info.sd_hs->hash[0], '\0', 16);
ndr_err = ndr_push_struct_blob(
pblob, ctx, NULL, &xacl,
return NT_STATUS_OK;
}
-static NTSTATUS store_acl_blob_fsp(files_struct *fsp,
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given an fsp pointer.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+ files_struct *fsp,
DATA_BLOB *pblob)
{
int ret;
return NT_STATUS_OK;
}
-static NTSTATUS store_acl_blob_pathname(connection_struct *conn,
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given a pathname.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
const char *fname,
DATA_BLOB *pblob)
{
+ connection_struct *conn = handle->conn;
int ret;
int saved_errno = 0;
return NT_STATUS_OK;
}
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given a pathname.
+*******************************************************************/
static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
files_struct *fsp,
{
TALLOC_CTX *ctx = talloc_tos();
DATA_BLOB blob;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status;
if (fsp && name == NULL) {
return status;
}
- if (fsp && fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
- } else {
- if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
- }
-
- status = parse_acl_blob(&blob, get_ctimespec(&sbuf),
- security_info, ppdesc);
+ status = parse_acl_blob(&blob, security_info, ppdesc);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("parse_acl_blob returned %s\n",
nt_errstr(status)));
return status;
}
if (fsp) {
- return store_acl_blob_fsp(fsp, &blob);
+ return store_acl_blob_fsp(handle, fsp, &blob);
} else {
- return store_acl_blob_pathname(handle->conn, fname, &blob);
+ return store_acl_blob_pathname(handle, fname, &blob);
}
}
return ret;
}
+/*********************************************************************
+ Fetch a security descriptor given an fsp.
+*********************************************************************/
+
static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, struct security_descriptor **ppdesc)
{
}
return NT_STATUS_OK;
}
+
+ DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
+ fsp->fsp_name,
+ nt_errstr(status) ));
+
return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
security_info, ppdesc);
}
+/*********************************************************************
+ Fetch a security descriptor given a pathname.
+*********************************************************************/
+
static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
const char *name, uint32 security_info, struct security_descriptor **ppdesc)
{
}
return NT_STATUS_OK;
}
+
+ DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
+ name,
+ nt_errstr(status) ));
+
return SMB_VFS_NEXT_GET_NT_ACL(handle, name,
security_info, ppdesc);
}
+/*********************************************************************
+ Store a security descriptor given an fsp.
+*********************************************************************/
+
static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info_sent, const struct security_descriptor *psd)
{
CONST_DISCARD(struct security_descriptor *,psd));
}
create_acl_blob(psd, &blob);
- store_acl_blob_fsp(fsp, &blob);
+ store_acl_blob_fsp(handle, fsp, &blob);
return NT_STATUS_OK;
}
+/*********************************************************************
+ Remove a Windows ACL - we're setting the underlying POSIX ACL.
+*********************************************************************/
+
+static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
+ const char *name,
+ SMB_ACL_TYPE_T type,
+ SMB_ACL_T theacl)
+{
+ int ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
+ name,
+ type,
+ theacl);
+ if (ret == -1) {
+ return -1;
+ }
+
+ become_root();
+ SMB_VFS_REMOVEXATTR(handle->conn, name, XATTR_NTACL_NAME);
+ unbecome_root();
+
+ return ret;
+}
+
+/*********************************************************************
+ Remove a Windows ACL - we're setting the underlying POSIX ACL.
+*********************************************************************/
+
+static int sys_acl_set_fd_xattr(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_ACL_T theacl)
+{
+ int ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle,
+ fsp,
+ theacl);
+ if (ret == -1) {
+ return -1;
+ }
+
+ become_root();
+ SMB_VFS_FREMOVEXATTR(fsp, XATTR_NTACL_NAME);
+ unbecome_root();
+
+ return ret;
+}
+
/* VFS operations structure */
static vfs_op_tuple skel_op_tuples[] =
{SMB_VFS_OP(get_nt_acl_xattr), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(fset_nt_acl_xattr),SMB_VFS_OP_FSET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ /* POSIX ACL operations. */
+ {SMB_VFS_OP(sys_acl_set_file_xattr), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(sys_acl_set_fd_xattr), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
NTSTATUS vfs_acl_xattr_init(void)