X-Git-Url: http://git.samba.org/samba.git/?p=ira%2Fwip.git;a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_xattr_tdb.c;h=f7fbfce4cb979f2232d9c301a78faab41996e5b1;hp=c707a1828f146641d1b2482cbabc58b3421f64d1;hb=010dfbf1fd26718ad197e3428ed0b03111f6c9e5;hpb=fd3ba988dca5014a9a2d5636506265c084e5db97 diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index c707a1828f1..f7fbfce4cb9 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -100,6 +100,7 @@ static NTSTATUS xattr_tdb_load_attrs(TALLOC_CTX *mem_ctx, 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, @@ -122,6 +123,8 @@ static struct db_record *xattr_tdb_lock_attrs(TALLOC_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))); @@ -177,25 +180,25 @@ static ssize_t xattr_tdb_getattr(struct db_context *db_ctx, return -1; } - for (i=0; inum_xattrs; i++) { - if (strcmp(attribs->xattrs[i].name, name) == 0) { + for (i=0; inum_eas; i++) { + if (strcmp(attribs->eas[i].name, name) == 0) { break; } } - if (i == attribs->num_xattrs) { + if (i == attribs->num_eas) { errno = ENOATTR; goto fail; } - if (attribs->xattrs[i].value.length > size) { + if (attribs->eas[i].value.length > size) { errno = ERANGE; goto fail; } - memcpy(value, attribs->xattrs[i].value.data, - attribs->xattrs[i].value.length); - result = attribs->xattrs[i].value.length; + memcpy(value, attribs->eas[i].value.data, + attribs->eas[i].value.length); + result = attribs->eas[i].value.length; fail: TALLOC_FREE(attribs); @@ -212,11 +215,11 @@ static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle, 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); } @@ -235,7 +238,7 @@ static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle, 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); } @@ -273,8 +276,8 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, return -1; } - for (i=0; inum_xattrs; i++) { - if (strcmp(attribs->xattrs[i].name, name) == 0) { + for (i=0; inum_eas; i++) { + if (strcmp(attribs->eas[i].name, name) == 0) { if (flags & XATTR_CREATE) { TALLOC_FREE(rec); errno = EEXIST; @@ -284,8 +287,8 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, } } - if (i == attribs->num_xattrs) { - struct tdb_xattr *tmp; + if (i == attribs->num_eas) { + struct xattr_EA *tmp; if (flags & XATTR_REPLACE) { TALLOC_FREE(rec); @@ -294,8 +297,8 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, } tmp = TALLOC_REALLOC_ARRAY( - attribs, attribs->xattrs, struct tdb_xattr, - attribs->num_xattrs + 1); + attribs, attribs->eas, struct xattr_EA, + attribs->num_eas+ 1); if (tmp == NULL) { DEBUG(0, ("TALLOC_REALLOC_ARRAY failed\n")); @@ -304,13 +307,13 @@ static int xattr_tdb_setattr(struct db_context *db_ctx, return -1; } - attribs->xattrs = tmp; - attribs->num_xattrs += 1; + attribs->eas = tmp; + attribs->num_eas += 1; } - attribs->xattrs[i].name = name; - attribs->xattrs[i].value.data = CONST_DISCARD(uint8 *, value); - attribs->xattrs[i].value.length = size; + attribs->eas[i].name = name; + attribs->eas[i].value.data = CONST_DISCARD(uint8 *, value); + attribs->eas[i].value.length = size; status = xattr_tdb_save_attrs(rec, attribs); @@ -334,11 +337,11 @@ static int xattr_tdb_setxattr(struct vfs_handle_struct *handle, 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); } @@ -358,7 +361,7 @@ static int xattr_tdb_fsetxattr(struct vfs_handle_struct *handle, 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); } @@ -386,15 +389,15 @@ static ssize_t xattr_tdb_listattr(struct db_context *db_ctx, } DEBUG(10, ("xattr_tdb_listattr: Found %d xattrs\n", - attribs->num_xattrs)); + attribs->num_eas)); - for (i=0; inum_xattrs; i++) { + for (i=0; inum_eas; i++) { size_t tmp; DEBUG(10, ("xattr_tdb_listattr: xattrs[i].name: %s\n", - attribs->xattrs[i].name)); + attribs->eas[i].name)); - tmp = strlen(attribs->xattrs[i].name); + tmp = strlen(attribs->eas[i].name); /* * Try to protect against overflow @@ -420,10 +423,10 @@ static ssize_t xattr_tdb_listattr(struct db_context *db_ctx, len = 0; - for (i=0; inum_xattrs; i++) { - strlcpy(list+len, attribs->xattrs[i].name, + for (i=0; inum_eas; i++) { + strlcpy(list+len, attribs->eas[i].name, size-len); - len += (strlen(attribs->xattrs[i].name) + 1); + len += (strlen(attribs->eas[i].name) + 1); } TALLOC_FREE(attribs); @@ -439,11 +442,11 @@ static ssize_t xattr_tdb_listxattr(struct vfs_handle_struct *handle, 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); } @@ -462,7 +465,7 @@ static ssize_t xattr_tdb_flistxattr(struct vfs_handle_struct *handle, 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); } @@ -496,23 +499,23 @@ static int xattr_tdb_removeattr(struct db_context *db_ctx, return -1; } - for (i=0; inum_xattrs; i++) { - if (strcmp(attribs->xattrs[i].name, name) == 0) { + for (i=0; inum_eas; i++) { + if (strcmp(attribs->eas[i].name, name) == 0) { break; } } - if (i == attribs->num_xattrs) { + if (i == attribs->num_eas) { TALLOC_FREE(rec); errno = ENOATTR; return -1; } - attribs->xattrs[i] = - attribs->xattrs[attribs->num_xattrs-1]; - attribs->num_xattrs -= 1; + attribs->eas[i] = + attribs->eas[attribs->num_eas-1]; + attribs->num_eas -= 1; - if (attribs->num_xattrs == 0) { + if (attribs->num_eas == 0) { rec->delete_rec(rec); TALLOC_FREE(rec); return 0; @@ -539,11 +542,11 @@ static int xattr_tdb_removexattr(struct vfs_handle_struct *handle, 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); } @@ -561,7 +564,7 @@ static int xattr_tdb_fremovexattr(struct vfs_handle_struct *handle, 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); } @@ -574,15 +577,18 @@ static bool xattr_tdb_init(int snum, struct db_context **p_db) { struct db_context *db; const char *dbname; + char *def_dbname; - dbname = lp_parm_const_string(snum, "xattr_tdb", "file", - lock_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(); @@ -593,37 +599,62 @@ static bool xattr_tdb_init(int snum, struct db_context **p_db) #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); @@ -636,7 +667,9 @@ static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path) TALLOC_FREE(rec); } - return 0; + out: + TALLOC_FREE(smb_fname_tmp); + return ret; } /* @@ -652,7 +685,7 @@ static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path) 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; } @@ -662,7 +695,7 @@ static int xattr_tdb_rmdir(vfs_handle_struct *handle, const char *path) 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); @@ -723,37 +756,23 @@ static int xattr_tdb_connect(vfs_handle_struct *handle, const char *service, 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); }