NTSTATUS status;
TDB_DATA data;
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
if (db_ctx->fetch(db_ctx, mem_ctx,
const struct file_id *id)
{
uint8 id_buf[16];
+
+ /* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
return db_ctx->fetch_locked(db_ctx, mem_ctx,
make_tdb_data(id_buf, sizeof(id_buf)));
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_getattr(db, &id, name, value, size);
}
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_getattr(db, &id, name, value, size);
}
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_setattr(db, &id, name, value, size, flags);
}
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_setattr(db, &id, name, value, size, flags);
}
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_listattr(db, &id, list, size);
}
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_listattr(db, &id, list, size);
}
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_removeattr(db, &id, name);
}
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
return xattr_tdb_removeattr(db, &id, name);
}
{
struct db_context *db;
const char *dbname;
+ char *def_dbname;
- dbname = lp_parm_const_string(snum, "xattr_tdb", "file",
- state_path("xattr.tdb"));
-
- if (dbname == NULL) {
+ def_dbname = state_path("xattr.tdb");
+ if (def_dbname == NULL) {
errno = ENOSYS;
return false;
}
+ dbname = lp_parm_const_string(snum, "xattr_tdb", "file", def_dbname);
+
+ /* now we know dbname is not NULL */
+
become_root();
db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
unbecome_root();
#else
errno = ENOSYS;
#endif
+ TALLOC_FREE(def_dbname);
return false;
}
*p_db = db;
+ TALLOC_FREE(def_dbname);
return true;
}
/*
* On unlink we need to delete the tdb record
*/
-static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path)
+static int xattr_tdb_unlink(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
- SMB_STRUCT_STAT sbuf;
+ struct smb_filename *smb_fname_tmp = NULL;
struct file_id id;
struct db_context *db;
struct db_record *rec;
- int ret;
+ NTSTATUS status;
+ int ret = -1;
+ bool remove_record = false;
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
return -1;
}
- ret = SMB_VFS_NEXT_UNLINK(handle, path);
+ if (lp_posix_pathnames()) {
+ ret = SMB_VFS_LSTAT(handle->conn, smb_fname_tmp);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn, smb_fname_tmp);
+ }
+ if (ret == -1) {
+ goto out;
+ }
+
+ if (smb_fname_tmp->st.st_ex_nlink == 1) {
+ /* Only remove record on last link to file. */
+ remove_record = true;
+ }
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
if (ret == -1) {
- return -1;
+ goto out;
+ }
+
+ if (!remove_record) {
+ goto out;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &smb_fname_tmp->st);
rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id);
TALLOC_FREE(rec);
}
- return 0;
+ out:
+ TALLOC_FREE(smb_fname_tmp);
+ return ret;
}
/*
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
- if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
return -1;
}
return -1;
}
- id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+ id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id);
return res;
}
- fstrcpy(sname, service);
- snum = find_service(sname);
+ snum = find_service(service, sname);
if (snum == -1) {
/*
* Should not happen, but we should not fail just *here*.
return 0;
}
-/* VFS operations structure */
-
-static const vfs_op_tuple xattr_tdb_ops[] = {
- {SMB_VFS_OP(xattr_tdb_getxattr), SMB_VFS_OP_GETXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_fgetxattr), SMB_VFS_OP_FGETXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_setxattr), SMB_VFS_OP_SETXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_fsetxattr), SMB_VFS_OP_FSETXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_listxattr), SMB_VFS_OP_LISTXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_flistxattr), SMB_VFS_OP_FLISTXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_removexattr), SMB_VFS_OP_REMOVEXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_fremovexattr), SMB_VFS_OP_FREMOVEXATTR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_unlink), SMB_VFS_OP_UNLINK,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_rmdir), SMB_VFS_OP_RMDIR,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(xattr_tdb_connect), SMB_VFS_OP_CONNECT,
- SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+static struct vfs_fn_pointers vfs_xattr_tdb_fns = {
+ .getxattr = xattr_tdb_getxattr,
+ .fgetxattr = xattr_tdb_fgetxattr,
+ .setxattr = xattr_tdb_setxattr,
+ .fsetxattr = xattr_tdb_fsetxattr,
+ .listxattr = xattr_tdb_listxattr,
+ .flistxattr = xattr_tdb_flistxattr,
+ .removexattr = xattr_tdb_removexattr,
+ .fremovexattr = xattr_tdb_fremovexattr,
+ .unlink = xattr_tdb_unlink,
+ .rmdir = xattr_tdb_rmdir,
+ .connect_fn = xattr_tdb_connect,
};
NTSTATUS vfs_xattr_tdb_init(void);
NTSTATUS vfs_xattr_tdb_init(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "xattr_tdb",
- xattr_tdb_ops);
+ &vfs_xattr_tdb_fns);
}