/* * On unlink we need to delete the tdb record */ static int posix_eadb_unlink(vfs_handle_struct *handle, const struct smb_filename *smb_fname) { struct smb_filename *smb_fname_tmp = NULL; int ret = -1; struct tdb_wrap *ea_tdb; SMB_VFS_HANDLE_GET_DATA(handle, ea_tdb, struct tdb_wrap, return -1); smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname); if (smb_fname_tmp == NULL) { errno = ENOMEM; return -1; } if (lp_posix_pathnames()) { ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp); } else { ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp); } if (ret == -1) { goto out; } if (smb_fname_tmp->st.st_ex_nlink == 1) { NTSTATUS status; /* Only remove record on last link to file. */ if (tdb_transaction_start(ea_tdb->tdb) != 0) { ret = -1; goto out; } status = unlink_posix_eadb_raw(ea_tdb, smb_fname->base_name, -1); if (!NT_STATUS_IS_OK(status)) { tdb_transaction_cancel(ea_tdb->tdb); ret = -1; goto out; } } ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp); if (ret == -1) { tdb_transaction_cancel(ea_tdb->tdb); goto out; } else { if (tdb_transaction_commit(ea_tdb->tdb) != 0) { ret = -1; goto out; } } out: TALLOC_FREE(smb_fname_tmp); return ret; }
static int streams_xattr_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { NTSTATUS status; int result = -1; char *xattr_name = NULL; if (!is_ntfs_stream_smb_fname(smb_fname)) { return SMB_VFS_NEXT_LSTAT(handle, smb_fname); } /* If the default stream is requested, just stat the base file. */ if (is_ntfs_default_stream_smb_fname(smb_fname)) { return streams_xattr_stat_base(handle, smb_fname, false); } /* Populate the stat struct with info from the base file. */ if (streams_xattr_stat_base(handle, smb_fname, false) == -1) { return -1; } /* Derive the xattr name to lookup. */ status = streams_xattr_get_name(handle, talloc_tos(), smb_fname->stream_name, &xattr_name); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; } /* Augment the base file's stat information before returning. */ smb_fname->st.st_ex_size = get_xattr_size(handle->conn, smb_fname, xattr_name); if (smb_fname->st.st_ex_size == -1) { SET_STAT_INVALID(smb_fname->st); errno = ENOENT; result = -1; goto fail; } smb_fname->st.st_ex_ino = stream_inode(&smb_fname->st, xattr_name); smb_fname->st.st_ex_mode &= ~S_IFMT; smb_fname->st.st_ex_mode |= S_IFREG; smb_fname->st.st_ex_blocks = smb_fname->st.st_ex_size / STAT_ST_BLOCKSIZE + 1; result = 0; fail: TALLOC_FREE(xattr_name); return result; }
/** * Helper to stat/lstat the base file of an smb_fname. */ static int streams_xattr_stat_base(vfs_handle_struct *handle, struct smb_filename *smb_fname, bool follow_links) { char *tmp_stream_name; int result; tmp_stream_name = smb_fname->stream_name; smb_fname->stream_name = NULL; if (follow_links) { result = SMB_VFS_NEXT_STAT(handle, smb_fname); } else { result = SMB_VFS_NEXT_LSTAT(handle, smb_fname); } smb_fname->stream_name = tmp_stream_name; return result; }
static int streams_xattr_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { NTSTATUS status; int result = -1; char *xattr_name = NULL; if (!is_ntfs_stream_smb_fname(smb_fname)) { return SMB_VFS_NEXT_LSTAT(handle, smb_fname); } /* If the default stream is requested, just stat the base file. */ if (is_ntfs_default_stream_smb_fname(smb_fname)) { return streams_xattr_stat_base(handle, smb_fname, false); } /* Populate the stat struct with info from the base file. */ if (streams_xattr_stat_base(handle, sm
static int fake_acls_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { int ret = -1; ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname); if (ret == 0) { TALLOC_CTX *frame = talloc_stackframe(); char *path; struct smb_filename smb_fname_base = { .base_name = smb_fname->base_name }; NTSTATUS status; /* * As we're calling getxattr directly here * we need to use only the base_name, not * the full name containing any stream name. */ status = get_full_smb_filename(frame, &smb_fname_base, &path); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); TALLOC_FREE(frame); return -1; } /* This isn't quite right (calling getxattr not * lgetxattr), but for the test purposes of this * module (fake NT ACLs from windows clients), it is * close enough. We removed the l*xattr functions * because linux doesn't support using them, but we * could fake them in xattr_tdb if we really wanted * to. We ignore errors because the link might not point anywhere */ fake_acls_uid(handle, path, &smb_fname->st.st_ex_uid); fake_acls_gid(handle, path, &smb_fname->st.st_ex_gid); TALLOC_FREE(frame); } return ret; }
static int skel_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { return SMB_VFS_NEXT_LSTAT(handle, smb_fname); }
static int skel_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) { return SMB_VFS_NEXT_LSTAT(handle, path, sbuf); }
static int cap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { pstring cappath; capencode(cappath, path); return SMB_VFS_NEXT_LSTAT(handle, conn, cappath, sbuf); }