X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_acl_tdb.c;h=5fc1bc03f2228465b4321bce163495c181a3356c;hp=647d133d3966ef641325b3ea5a61339771dd1b47;hb=HEAD;hpb=cde73e2ecec75f0b068555203962b43a4438d349;ds=sidebyside diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 647d133d396..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/crypto.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; @@ -59,7 +57,8 @@ static bool acl_tdb_init(void) } become_root(); - acl_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + acl_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600, + DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE); unbecome_root(); if (acl_db == NULL) { @@ -90,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 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 *******************************************************************/ @@ -118,60 +99,39 @@ 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 char *name, DATA_BLOB *pblob) { - uint8 id_buf[16]; + uint8_t id_buf[16]; TDB_DATA data; 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_fname(handle->conn, 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, @@ -184,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, 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; @@ -201,11 +162,10 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, files_struct *fsp, DATA_BLOB *pblob) { - uint8 id_buf[16]; + 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", @@ -219,48 +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; - NTSTATUS status; int ret = -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); + 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; @@ -271,36 +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 char *path) -{ - - SMB_STRUCT_STAT sbuf; - struct db_context *db = acl_db; - int ret = -1; - - if (lp_posix_pathnames()) { - ret = vfs_lstat_smb_fname(handle->conn, path, &sbuf); - } else { - ret = vfs_stat_smb_fname(handle->conn, path, &sbuf); - } - - if (ret == -1) { - return -1; - } - - ret = rmdir_acl_common(handle, path); - if (ret == -1) { - return -1; - } - - acl_tdb_delete(handle, db, &sbuf); - return 0; -} - /******************************************************************* Handle opening the storage tdb if so configured. *******************************************************************/ @@ -310,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; @@ -320,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' " @@ -331,41 +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; + } - if (lp_posix_pathnames()) { - ret = vfs_lstat_smb_fname(handle->conn, path, &sbuf); - } else { - ret = vfs_stat_smb_fname(handle->conn, path, &sbuf); - } + DBG_NOTICE("setting 'create mask = %s'\n", create_mask_str); - if (ret == -1) { - return -1; - } + lp_do_parameter (SNUM(handle->conn), + "create mask", create_mask_str); - ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, - path, - type, - theacl); - if (ret == -1) { - return -1; + 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; } @@ -375,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; @@ -387,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 = disconnect_acl_tdb, - .rmdir = rmdir_acl_tdb, - .create_file = create_file_acl_common, - .unlink = unlink_acl_tdb, - .chmod = chmod_acl_module_common, - .fchmod = fchmod_acl_module_common, - .fget_nt_acl = fget_nt_acl_common, - .get_nt_acl = get_nt_acl_common, - .fset_nt_acl = fset_nt_acl_common, - .chmod_acl = chmod_acl_acl_module_common, - .fchmod_acl = fchmod_acl_acl_module_common, - .sys_acl_set_file = sys_acl_set_file_tdb, - .sys_acl_set_fd = sys_acl_set_fd_tdb + .disconnect_fn = disconnect_acl_tdb, + .unlinkat_fn = unlinkat_acl_tdb, + .fchmod_fn = fchmod_acl_module_common, + .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 }; -NTSTATUS vfs_acl_tdb_init(void) +static_decl_vfs; +NTSTATUS vfs_acl_tdb_init(TALLOC_CTX *ctx) { return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "acl_tdb", &vfs_acl_tdb_fns);