X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_acl_tdb.c;h=5fc1bc03f2228465b4321bce163495c181a3356c;hb=HEAD;hp=1bc5973622ce9fd5ea7008d474a874fb4c521195;hpb=6b877102dbd7d375fdd240904f983e1f2196a100;p=samba.git diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 1bc5973622c..5ecba7ba757 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -22,18 +22,16 @@ #include "smbd/smbd.h" #include "system/filesys.h" #include "librpc/gen_ndr/xattr.h" -#include "librpc/gen_ndr/ndr_xattr.h" -#include "../lib/crypto/sha256.h" #include "dbwrap/dbwrap.h" #include "dbwrap/dbwrap_open.h" #include "auth.h" #include "util_tdb.h" +#include "vfs_acl_common.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS #define ACL_MODULE_NAME "acl_tdb" -#include "modules/vfs_acl_common.c" static unsigned int ref_count; static struct db_context *acl_db; @@ -51,7 +49,7 @@ static bool acl_tdb_init(void) return true; } - dbname = state_path("file_ntacls.tdb"); + dbname = state_path(talloc_tos(), "file_ntacls.tdb"); if (dbname == NULL) { errno = ENOSYS; @@ -91,24 +89,6 @@ static void disconnect_acl_tdb(struct vfs_handle_struct *handle) } } -/******************************************************************* - Fetch_lock the tdb acl record for a file -*******************************************************************/ - -static struct db_record *acl_tdb_lock(TALLOC_CTX *mem_ctx, - struct db_context *db, - const struct file_id *id) -{ - uint8_t id_buf[16]; - - /* For backwards compatibility only store the dev/inode. */ - push_file_id_16((char *)id_buf, id); - return dbwrap_fetch_locked(db, - mem_ctx, - make_tdb_data(id_buf, - sizeof(id_buf))); -} - /******************************************************************* Delete the tdb acl record for a file *******************************************************************/ @@ -119,31 +99,22 @@ static NTSTATUS acl_tdb_delete(vfs_handle_struct *handle, { NTSTATUS status; struct file_id id = vfs_file_id_from_sbuf(handle->conn, psbuf); - struct db_record *rec = acl_tdb_lock(talloc_tos(), db, &id); - - /* - * If rec == NULL there's not much we can do about it - */ + uint8_t id_buf[16]; - if (rec == NULL) { - DEBUG(10,("acl_tdb_delete: rec == NULL\n")); - TALLOC_FREE(rec); - return NT_STATUS_OK; - } + /* For backwards compatibility only store the dev/inode. */ + push_file_id_16(id_buf, &id); - status = dbwrap_record_delete(rec); - TALLOC_FREE(rec); + status = dbwrap_delete(db, make_tdb_data(id_buf, sizeof(id_buf))); return status; } /******************************************************************* - Pull a security descriptor into a DATA_BLOB from a tdb store. + Pull a security descriptor from an fsp into a DATA_BLOB from a tdb store. *******************************************************************/ -static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, +static NTSTATUS fget_acl_blob(TALLOC_CTX *ctx, vfs_handle_struct *handle, files_struct *fsp, - const struct smb_filename *smb_fname, DATA_BLOB *pblob) { uint8_t id_buf[16]; @@ -151,30 +122,16 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, struct file_id id; struct db_context *db = acl_db; NTSTATUS status = NT_STATUS_OK; - SMB_STRUCT_STAT sbuf; - - ZERO_STRUCT(sbuf); - - if (fsp) { - status = vfs_stat_fsp(fsp); - sbuf = fsp->fsp_name->st; - } else { - int ret = vfs_stat_smb_basename(handle->conn, - smb_fname->base_name, - &sbuf); - if (ret == -1) { - status = map_nt_error_from_unix(errno); - } - } + status = vfs_stat_fsp(fsp); if (!NT_STATUS_IS_OK(status)) { return status; } - id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st); /* For backwards compatibility only store the dev/inode. */ - push_file_id_16((char *)id_buf, &id); + push_file_id_16(id_buf, &id); status = dbwrap_fetch(db, ctx, @@ -187,8 +144,9 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, pblob->data = data.dptr; pblob->length = data.dsize; - DEBUG(10,("get_acl_blob: returned %u bytes from file %s\n", - (unsigned int)data.dsize, smb_fname->base_name )); + DBG_DEBUG("returned %u bytes from file %s\n", + (unsigned int)data.dsize, + fsp_str_dbg(fsp)); if (pblob->length == 0 || pblob->data == NULL) { return NT_STATUS_NOT_FOUND; @@ -206,9 +164,8 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, { uint8_t id_buf[16]; struct file_id id; - TDB_DATA data; + TDB_DATA data = { .dptr = pblob->data, .dsize = pblob->length }; struct db_context *db = acl_db; - struct db_record *rec; NTSTATUS status; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", @@ -222,47 +179,47 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st); /* For backwards compatibility only store the dev/inode. */ - push_file_id_16((char *)id_buf, &id); - rec = dbwrap_fetch_locked(db, talloc_tos(), - make_tdb_data(id_buf, - sizeof(id_buf))); - if (rec == NULL) { - DEBUG(0, ("store_acl_blob_fsp_tdb: fetch_lock failed\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - data.dptr = pblob->data; - data.dsize = pblob->length; - return dbwrap_record_store(rec, data, 0); + push_file_id_16(id_buf, &id); + + status = dbwrap_store( + db, make_tdb_data(id_buf, sizeof(id_buf)), data, 0); + return status; } /********************************************************************* - On unlink we need to delete the tdb record (if using tdb). + On unlinkat we need to delete the tdb record (if using tdb). *********************************************************************/ -static int unlink_acl_tdb(vfs_handle_struct *handle, - const struct smb_filename *smb_fname) +static int unlinkat_acl_tdb(vfs_handle_struct *handle, + struct files_struct *dirfsp, + const struct smb_filename *smb_fname, + int flags) { struct smb_filename *smb_fname_tmp = NULL; struct db_context *db = acl_db; int ret = -1; - smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname); + smb_fname_tmp = cp_smb_filename_nostream(talloc_tos(), smb_fname); if (smb_fname_tmp == NULL) { errno = ENOMEM; goto out; } - if (lp_posix_pathnames()) { - ret = SMB_VFS_LSTAT(handle->conn, smb_fname_tmp); - } else { - ret = SMB_VFS_STAT(handle->conn, smb_fname_tmp); - } - + ret = vfs_stat(handle->conn, smb_fname_tmp); if (ret == -1) { goto out; } - ret = unlink_acl_common(handle, smb_fname_tmp); + if (flags & AT_REMOVEDIR) { + ret = rmdir_acl_common(handle, + dirfsp, + smb_fname_tmp); + } else { + ret = unlink_acl_common(handle, + dirfsp, + smb_fname_tmp, + flags); + } if (ret == -1) { goto out; @@ -273,32 +230,6 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, return ret; } -/********************************************************************* - On rmdir we need to delete the tdb record (if using tdb). -*********************************************************************/ - -static int rmdir_acl_tdb(vfs_handle_struct *handle, - const struct smb_filename *smb_fname) -{ - - SMB_STRUCT_STAT sbuf; - struct db_context *db = acl_db; - int ret = -1; - - ret = vfs_stat_smb_basename(handle->conn, smb_fname->base_name, &sbuf); - if (ret == -1) { - return -1; - } - - ret = rmdir_acl_common(handle, smb_fname); - if (ret == -1) { - return -1; - } - - acl_tdb_delete(handle, db, &sbuf); - return 0; -} - /******************************************************************* Handle opening the storage tdb if so configured. *******************************************************************/ @@ -308,6 +239,8 @@ static int connect_acl_tdb(struct vfs_handle_struct *handle, const char *user) { int ret = SMB_VFS_NEXT_CONNECT(handle, service, user); + bool ok; + struct acl_common_config *config = NULL; if (ret < 0) { return ret; @@ -318,6 +251,12 @@ static int connect_acl_tdb(struct vfs_handle_struct *handle, return -1; } + ok = init_acl_common_config(handle, ACL_MODULE_NAME); + if (!ok) { + DBG_ERR("init_acl_common_config failed\n"); + return -1; + } + /* Ensure we have the parameters correct if we're * using this module. */ DEBUG(2,("connect_acl_tdb: setting 'inherit acls = true' " @@ -329,36 +268,44 @@ static int connect_acl_tdb(struct vfs_handle_struct *handle, lp_do_parameter(SNUM(handle->conn), "dos filemode", "true"); lp_do_parameter(SNUM(handle->conn), "force unknown acl user", "true"); - return 0; -} + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct acl_common_config, + return -1); -/********************************************************************* - Remove a Windows ACL - we're setting the underlying POSIX ACL. -*********************************************************************/ + if (config->ignore_system_acls) { + mode_t create_mask = lp_create_mask(SNUM(handle->conn)); + char *create_mask_str = NULL; -static int sys_acl_set_file_tdb(vfs_handle_struct *handle, - const char *path, - SMB_ACL_TYPE_T type, - SMB_ACL_T theacl) -{ - SMB_STRUCT_STAT sbuf; - struct db_context *db = acl_db; - int ret = -1; + if ((create_mask & 0666) != 0666) { + create_mask |= 0666; + create_mask_str = talloc_asprintf(handle, "0%o", + create_mask); + if (create_mask_str == NULL) { + DBG_ERR("talloc_asprintf failed\n"); + return -1; + } - ret = vfs_stat_smb_basename(handle->conn, path, &sbuf); - if (ret == -1) { - return -1; - } + DBG_NOTICE("setting 'create mask = %s'\n", create_mask_str); - ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, - path, - type, - theacl); - if (ret == -1) { - return -1; + lp_do_parameter (SNUM(handle->conn), + "create mask", create_mask_str); + + TALLOC_FREE(create_mask_str); + } + + DBG_NOTICE("setting 'directory mask = 0777', " + "'store dos attributes = yes' and all " + "'map ...' options to 'no'\n"); + + lp_do_parameter(SNUM(handle->conn), "directory mask", "0777"); + lp_do_parameter(SNUM(handle->conn), "map archive", "no"); + lp_do_parameter(SNUM(handle->conn), "map hidden", "no"); + lp_do_parameter(SNUM(handle->conn), "map readonly", "no"); + lp_do_parameter(SNUM(handle->conn), "map system", "no"); + lp_do_parameter(SNUM(handle->conn), "store dos attributes", + "yes"); } - acl_tdb_delete(handle, db, &sbuf); return 0; } @@ -368,8 +315,11 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle, static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, files_struct *fsp, + SMB_ACL_TYPE_T type, SMB_ACL_T theacl) { + struct acl_common_fsp_ext *ext = (struct acl_common_fsp_ext *) + VFS_FETCH_FSP_EXTENSION(handle, fsp); struct db_context *db = acl_db; NTSTATUS status; int ret; @@ -380,34 +330,57 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, } ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, - fsp, - theacl); + fsp, + type, + theacl); if (ret == -1) { return -1; } + if (ext != NULL && ext->setting_nt_acl) { + return 0; + } + acl_tdb_delete(handle, db, &fsp->fsp_name->st); return 0; } +static NTSTATUS acl_tdb_fget_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) +{ + NTSTATUS status; + status = fget_nt_acl_common(fget_acl_blob, handle, fsp, + security_info, mem_ctx, ppdesc); + return status; +} + +static NTSTATUS acl_tdb_fset_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t security_info_sent, + const struct security_descriptor *psd) +{ + NTSTATUS status; + status = fset_nt_acl_common(fget_acl_blob, store_acl_blob_fsp, + ACL_MODULE_NAME, + handle, fsp, security_info_sent, psd); + return status; +} + static struct vfs_fn_pointers vfs_acl_tdb_fns = { .connect_fn = connect_acl_tdb, .disconnect_fn = disconnect_acl_tdb, - .rmdir_fn = rmdir_acl_tdb, - .unlink_fn = unlink_acl_tdb, - .chmod_fn = chmod_acl_module_common, + .unlinkat_fn = unlinkat_acl_tdb, .fchmod_fn = fchmod_acl_module_common, - .fget_nt_acl_fn = fget_nt_acl_common, - .get_nt_acl_fn = get_nt_acl_common, - .fset_nt_acl_fn = fset_nt_acl_common, - .chmod_acl_fn = chmod_acl_acl_module_common, - .fchmod_acl_fn = fchmod_acl_acl_module_common, - .sys_acl_set_file_fn = sys_acl_set_file_tdb, + .fget_nt_acl_fn = acl_tdb_fget_nt_acl, + .fset_nt_acl_fn = acl_tdb_fset_nt_acl, .sys_acl_set_fd_fn = sys_acl_set_fd_tdb }; static_decl_vfs; -NTSTATUS vfs_acl_tdb_init(void) +NTSTATUS vfs_acl_tdb_init(TALLOC_CTX *ctx) { return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "acl_tdb", &vfs_acl_tdb_fns);