#include "includes.h"
+#include "smbd/smbd.h"
/* cap functions */
static char *capencode(TALLOC_CTX *ctx, const char *from);
static char *capdecode(TALLOC_CTX *ctx, const char *from);
-static uint64_t cap_disk_free(vfs_handle_struct *handle, const char *path,
- bool small_query, uint64_t *bsize,
- uint64_t *dfree, uint64_t *dsize)
+static uint64_t cap_disk_free(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uint64_t *bsize,
+ uint64_t *dfree,
+ uint64_t *dsize)
{
- char *cappath = capencode(talloc_tos(), path);
+ char *capname = capencode(talloc_tos(), smb_fname->base_name);
+ struct smb_filename *cap_smb_fname = NULL;
- if (!cappath) {
+ if (!capname) {
+ errno = ENOMEM;
+ return (uint64_t)-1;
+ }
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capname,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(capname);
errno = ENOMEM;
return (uint64_t)-1;
}
- return SMB_VFS_NEXT_DISK_FREE(handle, cappath, small_query, bsize,
- dfree, dsize);
+ return SMB_VFS_NEXT_DISK_FREE(handle, cap_smb_fname,
+ bsize, dfree, dsize);
}
-static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
+static int cap_get_quota(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ enum SMB_QUOTA_TYPE qtype,
+ unid_t id,
+ SMB_DISK_QUOTA *dq)
{
- char *capname = capencode(talloc_tos(), fname);
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ struct smb_filename *cap_smb_fname = NULL;
+
+ if (!cappath) {
+ errno = ENOMEM;
+ return -1;
+ }
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+ return SMB_VFS_NEXT_GET_QUOTA(handle, cap_smb_fname, qtype, id, dq);
+}
+
+static DIR *cap_opendir(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ const char *mask,
+ uint32_t attr)
+{
+ char *capname = capencode(talloc_tos(), smb_fname->base_name);
+ struct smb_filename *cap_smb_fname = NULL;
if (!capname) {
errno = ENOMEM;
return NULL;
}
- return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capname,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(capname);
+ errno = ENOMEM;
+ return NULL;
+ }
+ return SMB_VFS_NEXT_OPENDIR(handle, cap_smb_fname, mask, attr);
}
-static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static struct dirent *cap_readdir(vfs_handle_struct *handle,
+ DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
- SMB_STRUCT_DIRENT *result;
- SMB_STRUCT_DIRENT *newdirent;
+ struct dirent *result;
+ struct dirent *newdirent;
char *newname;
size_t newnamelen;
DEBUG(3,("cap: cap_readdir\n"));
}
DEBUG(3,("cap: cap_readdir: %s\n", newname));
newnamelen = strlen(newname)+1;
- newdirent = (SMB_STRUCT_DIRENT *)TALLOC_ARRAY(talloc_tos(),
- char,
- sizeof(SMB_STRUCT_DIRENT)+
- newnamelen);
+ newdirent = talloc_size(
+ talloc_tos(), sizeof(struct dirent) + newnamelen);
if (!newdirent) {
return NULL;
}
- memcpy(newdirent, result, sizeof(SMB_STRUCT_DIRENT));
+ talloc_set_name_const(newdirent, "struct dirent");
+ memcpy(newdirent, result, sizeof(struct dirent));
memcpy(&newdirent->d_name, newname, newnamelen);
return newdirent;
}
-static int cap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
+static int cap_mkdir(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ mode_t mode)
{
- char *cappath = capencode(talloc_tos(), path);
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ struct smb_filename *cap_smb_fname = NULL;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_MKDIR(handle, cappath, mode);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return SMB_VFS_NEXT_MKDIR(handle, cap_smb_fname, mode);
}
-static int cap_rmdir(vfs_handle_struct *handle, const char *path)
+static int cap_rmdir(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
- char *cappath = capencode(talloc_tos(), path);
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ struct smb_filename *cap_smb_fname = NULL;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_RMDIR(handle, cappath);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return SMB_VFS_NEXT_RMDIR(handle, cap_smb_fname);
}
static int cap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
return ret;
}
-static int cap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
+static int cap_rename(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname_src,
+ const struct smb_filename *smb_fname_dst)
{
- char *capold = capencode(talloc_tos(), oldname);
- char *capnew = capencode(talloc_tos(), newname);
-
+ char *capold = NULL;
+ char *capnew = NULL;
+ struct smb_filename *smb_fname_src_tmp = NULL;
+ struct smb_filename *smb_fname_dst_tmp = NULL;
+ int ret = -1;
+
+ capold = capencode(talloc_tos(), smb_fname_src->base_name);
+ capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
if (!capold || !capnew) {
errno = ENOMEM;
- return -1;
+ goto out;
+ }
+
+ /* Setup temporary smb_filename structs. */
+ smb_fname_src_tmp = cp_smb_filename(talloc_tos(), smb_fname_src);
+ if (smb_fname_src_tmp == NULL) {
+ errno = ENOMEM;
+ goto out;
+ }
+ smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), smb_fname_dst);
+ if (smb_fname_dst_tmp == NULL) {
+ errno = ENOMEM;
+ goto out;
}
- return SMB_VFS_NEXT_RENAME(handle, capold, capnew);
+
+ smb_fname_src_tmp->base_name = capold;
+ smb_fname_dst_tmp->base_name = capnew;
+
+ ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp,
+ smb_fname_dst_tmp);
+ out:
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(smb_fname_src_tmp);
+ TALLOC_FREE(smb_fname_dst_tmp);
+
+ return ret;
}
static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
return ret;
}
-static int cap_unlink(vfs_handle_struct *handle, const char *path)
+static int cap_unlink(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *smb_fname_tmp = NULL;
+ char *cappath = NULL;
+ int ret;
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_UNLINK(handle, cappath);
+
+ /* Setup temporary smb_filename structs. */
+ smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
+ if (smb_fname_tmp == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ smb_fname_tmp->base_name = cappath;
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
+
+ TALLOC_FREE(smb_fname_tmp);
+ return ret;
}
-static int cap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
+static int cap_chmod(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ mode_t mode)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_CHMOD(handle, cappath, mode);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_CHMOD(handle, cap_smb_fname, mode);
+ saved_errno = errno;
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ errno = saved_errno;
+ return ret;
}
-static int cap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int cap_chown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_CHOWN(handle, cappath, uid, gid);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_CHOWN(handle, cap_smb_fname, uid, gid);
+ saved_errno = errno;
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ errno = saved_errno;
+ return ret;
}
-static int cap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int cap_lchown(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uid_t uid,
+ gid_t gid)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LCHOWN(handle, cappath, uid, gid);
+
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
+ saved_errno = errno;
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ errno = saved_errno;
+ return ret;
}
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,
+static int cap_ntimes(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
struct smb_file_time *ft)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *smb_fname_tmp = NULL;
+ char *cappath = NULL;
+ int ret;
+
+ cappath = capencode(talloc_tos(), smb_fname->base_name);
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_NTIMES(handle, cappath, ft);
+
+ /* Setup temporary smb_filename structs. */
+ smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
+ if (smb_fname_tmp == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ smb_fname_tmp->base_name = cappath;
+
+ ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
+
+ TALLOC_FREE(smb_fname_tmp);
+ return ret;
}
-static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle,
+ const char *link_contents,
+ const struct smb_filename *new_smb_fname)
{
- char *capold = capencode(talloc_tos(), oldpath);
- char *capnew = capencode(talloc_tos(), newpath);
+ char *capold = capencode(talloc_tos(), link_contents);
+ char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
+ struct smb_filename *new_cap_smb_fname = NULL;
+ int saved_errno = 0;
+ int ret;
if (!capold || !capnew) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
+ new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capnew,
+ NULL,
+ NULL,
+ new_smb_fname->flags);
+ if (new_cap_smb_fname == NULL) {
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_SYMLINK(handle,
+ capold,
+ new_cap_smb_fname);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(new_cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int cap_readlink(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
{
- char *cappath = capencode(talloc_tos(), path);
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ struct smb_filename *cap_smb_fname = NULL;
+ int saved_errno = 0;
+ int ret;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz);
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_READLINK(handle, cap_smb_fname, buf, bufsiz);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cap_link(vfs_handle_struct *handle,
+ const struct smb_filename *old_smb_fname,
+ const struct smb_filename *new_smb_fname)
{
- char *capold = capencode(talloc_tos(), oldpath);
- char *capnew = capencode(talloc_tos(), newpath);
+ char *capold = capencode(talloc_tos(), old_smb_fname->base_name);
+ char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
+ struct smb_filename *old_cap_smb_fname = NULL;
+ struct smb_filename *new_cap_smb_fname = NULL;
+ int saved_errno = 0;
+ int ret;
if (!capold || !capnew) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LINK(handle, capold, capnew);
+ old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capold,
+ NULL,
+ NULL,
+ old_smb_fname->flags);
+ if (old_cap_smb_fname == NULL) {
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ errno = ENOMEM;
+ return -1;
+ }
+ new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ capnew,
+ NULL,
+ NULL,
+ new_smb_fname->flags);
+ if (new_cap_smb_fname == NULL) {
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(old_cap_smb_fname);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_LINK(handle, old_cap_smb_fname, new_cap_smb_fname);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(capold);
+ TALLOC_FREE(capnew);
+ TALLOC_FREE(old_cap_smb_fname);
+ TALLOC_FREE(new_cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev)
+static int cap_mknod(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ mode_t mode,
+ SMB_DEV_T dev)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno = 0;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev);
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_MKNOD(handle, cap_smb_fname, mode, dev);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path)
+static char *cap_realpath(vfs_handle_struct *handle, const char *path)
{
/* monyo need capencode'ed and capdecode'ed? */
char *cappath = capencode(talloc_tos(), path);
errno = ENOMEM;
return NULL;
}
- return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
+ return SMB_VFS_NEXT_REALPATH(handle, cappath);
}
-static int cap_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode)
+static int cap_chmod_acl(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ mode_t mode)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno;
/* If the underlying VFS doesn't have ACL support... */
- if (!handle->vfs_next.ops.chmod_acl) {
- errno = ENOSYS;
+ if (!cappath) {
+ errno = ENOMEM;
return -1;
}
- if (!cappath) {
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_CHMOD_ACL(handle, cappath, mode);
+
+ ret = SMB_VFS_NEXT_CHMOD_ACL(handle, cap_smb_fname, mode);
+ saved_errno = errno;
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ errno = saved_errno;
+ return ret;
}
-static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T type)
+static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ SMB_ACL_TYPE_T type,
+ TALLOC_CTX *mem_ctx)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ SMB_ACL_T ret;
+ int saved_errno = 0;
if (!cappath) {
errno = ENOMEM;
return (SMB_ACL_T)NULL;
}
- return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath, type);
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return (SMB_ACL_T)NULL;
+ }
+ ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
+ type, mem_ctx);
+ if (ret == NULL) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int cap_sys_acl_set_file(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ SMB_ACL_TYPE_T acltype,
+ SMB_ACL_T theacl)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno = 0;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cappath, acltype, theacl);
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cap_smb_fname,
+ acltype, theacl);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
+static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ int ret;
+ int saved_errno = 0;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cappath);
-}
-
-static ssize_t cap_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size)
-{
- char *cappath = capencode(talloc_tos(), path);
- char *capname = capencode(talloc_tos(), name);
-
- if (!cappath || !capname) {
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_GETXATTR(handle, cappath, capname, value, size);
+ ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static ssize_t cap_lgetxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t
-size)
+static ssize_t cap_getxattr(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ const char *name,
+ void *value,
+ size_t size)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
char *capname = capencode(talloc_tos(), name);
+ ssize_t ret;
+ int saved_errno = 0;
if (!cappath || !capname) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LGETXATTR(handle, cappath, capname, value, size);
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(capname);
+ errno = ENOMEM;
+ return -1;
+ }
+ ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
+ capname, value, size);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(capname);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno) {
+ errno = saved_errno;
+ }
+ return ret;
}
static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
}
-static ssize_t cap_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
+static ssize_t cap_listxattr(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ char *list,
+ size_t size)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+ ssize_t ret;
+ int saved_errno = 0;
if (!cappath) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LISTXATTR(handle, cappath, list, size);
-}
-
-static ssize_t cap_llistxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
-{
- char *cappath = capencode(talloc_tos(), path);
-
- if (!cappath) {
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LLISTXATTR(handle, cappath, list, size);
+ ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno) {
+ errno = saved_errno;
+ }
+ return ret;
}
-static int cap_removexattr(vfs_handle_struct *handle, const char *path, const char *name)
+static int cap_removexattr(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ const char *name)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
char *capname = capencode(talloc_tos(), name);
+ int ret;
+ int saved_errno = 0;
if (!cappath || !capname) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_REMOVEXATTR(handle, cappath, capname);
-}
-
-static int cap_lremovexattr(vfs_handle_struct *handle, const char *path, const char *name)
-{
- char *cappath = capencode(talloc_tos(), path);
- char *capname = capencode(talloc_tos(), name);
-
- if (!cappath || !capname) {
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(capname);
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LREMOVEXATTR(handle, cappath, capname);
+ ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(capname);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno) {
+ errno = saved_errno;
+ }
+ return ret;
}
static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
}
-static int cap_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
+static int cap_setxattr(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
{
- char *cappath = capencode(talloc_tos(), path);
+ struct smb_filename *cap_smb_fname = NULL;
+ char *cappath = capencode(talloc_tos(), smb_fname->base_name);
char *capname = capencode(talloc_tos(), name);
+ int ret;
+ int saved_errno = 0;
if (!cappath || !capname) {
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_SETXATTR(handle, cappath, capname, value, size, flags);
-}
-
-static int cap_lsetxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
-{
- char *cappath = capencode(talloc_tos(), path);
- char *capname = capencode(talloc_tos(), name);
-
- if (!cappath || !capname) {
+ cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+ cappath,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (cap_smb_fname == NULL) {
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(capname);
errno = ENOMEM;
return -1;
}
- return SMB_VFS_NEXT_LSETXATTR(handle, cappath, capname, value, size, flags);
+ ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
+ capname, value, size, flags);
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+ TALLOC_FREE(cappath);
+ TALLOC_FREE(capname);
+ TALLOC_FREE(cap_smb_fname);
+ if (saved_errno) {
+ errno = saved_errno;
+ }
+ return ret;
}
static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
}
-/* VFS operations structure */
-
-static vfs_op_tuple cap_op_tuples[] = {
-
- /* Disk operations */
-
- {SMB_VFS_OP(cap_disk_free), SMB_VFS_OP_DISK_FREE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* Directory operations */
-
- {SMB_VFS_OP(cap_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
-
- /* File operations */
-
- {SMB_VFS_OP(cap_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lchown), SMB_VFS_OP_LCHOWN, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
-
- /* POSIX ACL operations */
-
- {SMB_VFS_OP(cap_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
-
- {SMB_VFS_OP(cap_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, SMB_VFS_LAYER_TRANSPARENT},
-
- /* EA operations. */
- {SMB_VFS_OP(cap_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fgetxattr), SMB_VFS_OP_FGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_llistxattr), SMB_VFS_OP_LLISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lremovexattr), SMB_VFS_OP_LREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(cap_fsetxattr), SMB_VFS_OP_FSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
-
- {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+static struct vfs_fn_pointers vfs_cap_fns = {
+ .disk_free_fn = cap_disk_free,
+ .get_quota_fn = cap_get_quota,
+ .opendir_fn = cap_opendir,
+ .readdir_fn = cap_readdir,
+ .mkdir_fn = cap_mkdir,
+ .rmdir_fn = cap_rmdir,
+ .open_fn = cap_open,
+ .rename_fn = cap_rename,
+ .stat_fn = cap_stat,
+ .lstat_fn = cap_lstat,
+ .unlink_fn = cap_unlink,
+ .chmod_fn = cap_chmod,
+ .chown_fn = cap_chown,
+ .lchown_fn = cap_lchown,
+ .chdir_fn = cap_chdir,
+ .ntimes_fn = cap_ntimes,
+ .symlink_fn = cap_symlink,
+ .readlink_fn = cap_readlink,
+ .link_fn = cap_link,
+ .mknod_fn = cap_mknod,
+ .realpath_fn = cap_realpath,
+ .chmod_acl_fn = cap_chmod_acl,
+ .sys_acl_get_file_fn = cap_sys_acl_get_file,
+ .sys_acl_set_file_fn = cap_sys_acl_set_file,
+ .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
+ .getxattr_fn = cap_getxattr,
+ .fgetxattr_fn = cap_fgetxattr,
+ .listxattr_fn = cap_listxattr,
+ .removexattr_fn = cap_removexattr,
+ .fremovexattr_fn = cap_fremovexattr,
+ .setxattr_fn = cap_setxattr,
+ .fsetxattr_fn = cap_fsetxattr
};
-NTSTATUS vfs_cap_init(void);
-NTSTATUS vfs_cap_init(void)
+NTSTATUS vfs_cap_init(TALLOC_CTX *);
+NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
{
- return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap", cap_op_tuples);
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
+ &vfs_cap_fns);
}
/* For CAP functions */
}
len++;
- to = TALLOC_ARRAY(ctx, char, len);
+ to = talloc_array(ctx, char, len);
if (!to) {
return NULL;
}
size_t len = 0;
for (p1 = from; *p1; len++) {
- if (is_hex(from)) {
+ if (is_hex(p1)) {
p1 += 3;
} else {
p1++;
}
}
+ len++;
- to = TALLOC_ARRAY(ctx, char, len);
+ to = talloc_array(ctx, char, len);
if (!to) {
return NULL;
}