{
int ret;
TALLOC_CTX *frame = talloc_stackframe();
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status = create_synthetic_smb_fname_split(frame, path, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- TALLOC_FREE(frame);
+ struct smb_filename *smb_fname;
+
+ smb_fname = synthetic_smb_fname(frame, path, NULL, NULL, 0);
+ if (smb_fname == NULL) {
+ TALLOC_FREE(frame);
+ errno = ENOMEM;
return -1;
}
TALLOC_FREE(frame);
return -1;
}
+
+ if (size == 0) {
+ TALLOC_FREE(frame);
+ return xattr_size;
+ }
+
if (blob.length > size) {
TALLOC_FREE(frame);
errno = ERANGE;
TALLOC_FREE(frame);
return -1;
}
+
+ if (size == 0) {
+ TALLOC_FREE(frame);
+ return xattr_size;
+ }
+
if (blob.length > size) {
TALLOC_FREE(frame);
errno = ERANGE;
become_root();
db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600,
- DBWRAP_LOCK_ORDER_2);
+ DBWRAP_LOCK_ORDER_2, DBWRAP_FLAG_NONE);
unbecome_root();
if (db == NULL) {
return true;
}
+static int xattr_tdb_open(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
+{
+ struct db_context *db = NULL;
+ TALLOC_CTX *frame = NULL;
+ int ret;
+
+ fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle,
+ smb_fname, fsp,
+ flags,
+ mode);
+
+ if (fsp->fh->fd < 0) {
+ return fsp->fh->fd;
+ }
+
+ if ((flags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)) {
+ return fsp->fh->fd;
+ }
+
+ /*
+ * We know we used O_CREAT|O_EXCL and it worked.
+ * We must have created the file.
+ */
+
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+ if (ret == -1) {
+ /* Can't happen... */
+ DBG_WARNING("SMB_VFS_FSTAT failed on file %s (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno));
+ return -1;
+ }
+ fsp->file_id = SMB_VFS_FILE_ID_CREATE(fsp->conn, &smb_fname->st);
+
+ frame = talloc_stackframe();
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+ if (!xattr_tdb_init(-1, frame, &db))
+ {
+ TALLOC_FREE(frame); return -1;
+ });
+
+ xattr_tdb_remove_all_attrs(db, &fsp->file_id);
+ TALLOC_FREE(frame);
+ return fsp->fh->fd;
+}
+
+static int xattr_tdb_mkdir(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ mode_t mode)
+{
+ struct db_context *db = NULL;
+ TALLOC_CTX *frame = NULL;
+ struct file_id fileid;
+ int ret;
+ struct smb_filename *smb_fname_tmp = NULL;
+
+ ret = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode);
+ if (ret < 0) {
+ return ret;
+ }
+
+ frame = talloc_stackframe();
+ smb_fname_tmp = cp_smb_filename(frame, smb_fname);
+ if (smb_fname_tmp == NULL) {
+ TALLOC_FREE(frame);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* Always use LSTAT here - we just creaded the directory. */
+ ret = SMB_VFS_LSTAT(handle->conn, smb_fname_tmp);
+ if (ret == -1) {
+ /* Rename race. Let upper level take care of it. */
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ if (!S_ISDIR(smb_fname_tmp->st.st_ex_mode)) {
+ /* Rename race. Let upper level take care of it. */
+ TALLOC_FREE(frame);
+ return -1;
+ }
+
+ fileid = SMB_VFS_FILE_ID_CREATE(handle->conn, &smb_fname_tmp->st);
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+ if (!xattr_tdb_init(-1, frame, &db))
+ {
+ TALLOC_FREE(frame); return -1;
+ });
+
+ xattr_tdb_remove_all_attrs(db, &fileid);
+ TALLOC_FREE(frame);
+ return 0;
+}
+
/*
* On unlink we need to delete the tdb record
*/
return -1;
}
- if (lp_posix_pathnames()) {
+ if (smb_fname_tmp->flags & SMB_FILENAME_POSIX_PATH) {
ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
} else {
ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp);
/*
* On rmdir we need to delete the tdb record
*/
-static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path)
+static int xattr_tdb_rmdir(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
SMB_STRUCT_STAT sbuf;
struct file_id id;
TALLOC_FREE(frame); return -1;
});
- if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
+ if (vfs_stat_smb_basename(handle->conn,
+ smb_fname,
+ &sbuf) == -1) {
TALLOC_FREE(frame);
return -1;
}
- ret = SMB_VFS_NEXT_RMDIR(handle, path);
+ ret = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
if (ret == -1) {
TALLOC_FREE(frame);
.flistxattr_fn = xattr_tdb_flistxattr,
.removexattr_fn = xattr_tdb_removexattr,
.fremovexattr_fn = xattr_tdb_fremovexattr,
+ .open_fn = xattr_tdb_open,
+ .mkdir_fn = xattr_tdb_mkdir,
.unlink_fn = xattr_tdb_unlink,
.rmdir_fn = xattr_tdb_rmdir,
.connect_fn = xattr_tdb_connect,
};
-NTSTATUS vfs_xattr_tdb_init(void);
-NTSTATUS vfs_xattr_tdb_init(void)
+NTSTATUS vfs_xattr_tdb_init(TALLOC_CTX *);
+NTSTATUS vfs_xattr_tdb_init(TALLOC_CTX *ctx)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "xattr_tdb",
&vfs_xattr_tdb_fns);