* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-/* NOTE: This is an experimental module, not yet finished. JRA. */
-
#include "includes.h"
+#include "smbd/smbd.h"
#include "librpc/gen_ndr/xattr.h"
#include "librpc/gen_ndr/ndr_xattr.h"
-#include "../lib/crypto/crypto.h"
+#include "../lib/crypto/sha256.h"
+#include "auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
Pull a security descriptor into a DATA_BLOB from a xattr.
*******************************************************************/
+static ssize_t getxattr_do(vfs_handle_struct *handle,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ const char *xattr_name,
+ uint8_t *val,
+ size_t size)
+{
+ ssize_t sizeret;
+ int saved_errno = 0;
+
+ become_root();
+ if (fsp && fsp->fh->fd != -1) {
+ sizeret = SMB_VFS_FGETXATTR(fsp, xattr_name, val, size);
+ } else {
+ sizeret = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name,
+ XATTR_NTACL_NAME, val, size);
+ }
+ if (sizeret == -1) {
+ saved_errno = errno;
+ }
+ unbecome_root();
+
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
+
+ return sizeret;
+}
+
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
vfs_handle_struct *handle,
files_struct *fsp,
- const char *name,
+ const struct smb_filename *smb_fname,
DATA_BLOB *pblob)
{
- size_t size = 1024;
+ size_t size = 4096;
uint8_t *val = NULL;
uint8_t *tmp;
ssize_t sizeret;
- int saved_errno = 0;
ZERO_STRUCTP(pblob);
again:
- tmp = TALLOC_REALLOC_ARRAY(ctx, val, uint8_t, size);
+ tmp = talloc_realloc(ctx, val, uint8_t, size);
if (tmp == NULL) {
TALLOC_FREE(val);
return NT_STATUS_NO_MEMORY;
}
val = tmp;
- become_root();
- if (fsp && fsp->fh->fd != -1) {
- sizeret = SMB_VFS_FGETXATTR(fsp, XATTR_NTACL_NAME, val, size);
- } else {
- sizeret = SMB_VFS_GETXATTR(handle->conn, name,
- XATTR_NTACL_NAME, val, size);
+ sizeret =
+ getxattr_do(handle, fsp, smb_fname, XATTR_NTACL_NAME, val, size);
+
+ if (sizeret >= 0) {
+ pblob->data = val;
+ pblob->length = sizeret;
+ return NT_STATUS_OK;
}
- if (sizeret == -1) {
- saved_errno = errno;
+
+ if (errno != ERANGE) {
+ goto err;
}
- unbecome_root();
- /* Max ACL size is 65536 bytes. */
- if (sizeret == -1) {
- errno = saved_errno;
- if ((errno == ERANGE) && (size != 65536)) {
- /* Too small, try again. */
- size = 65536;
- goto again;
- }
+ /* Too small, try again. */
+ sizeret =
+ getxattr_do(handle, fsp, smb_fname, XATTR_NTACL_NAME, NULL, 0);
+ if (sizeret < 0) {
+ goto err;
+ }
- /* Real error - exit here. */
- TALLOC_FREE(val);
- return map_nt_error_from_unix(errno);
+ if (size < sizeret) {
+ size = sizeret;
}
- pblob->data = val;
- pblob->length = sizeret;
- return NT_STATUS_OK;
+ if (size > 65536) {
+ /* Max ACL size is 65536 bytes. */
+ errno = ERANGE;
+ goto err;
+ }
+
+ goto again;
+ err:
+ /* Real error - exit here. */
+ TALLOC_FREE(val);
+ return map_nt_error_from_unix(errno);
}
/*******************************************************************
ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
pblob->data, pblob->length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
XATTR_NTACL_NAME,
pblob->data, pblob->length, 0);
}
}
unbecome_root();
if (ret) {
- errno = saved_errno;
DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s"
"with error %s\n",
fsp_str_dbg(fsp),
- strerror(errno) ));
- return map_nt_error_from_unix(errno);
+ strerror(saved_errno) ));
+ errno = saved_errno;
+ return map_nt_error_from_unix(saved_errno);
}
return NT_STATUS_OK;
}
*********************************************************************/
static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
- const char *name,
- SMB_ACL_TYPE_T type,
- SMB_ACL_T theacl)
+ const struct smb_filename *smb_fname,
+ SMB_ACL_TYPE_T type,
+ SMB_ACL_T theacl)
{
int ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
- name,
+ smb_fname,
type,
theacl);
if (ret == -1) {
}
become_root();
- SMB_VFS_REMOVEXATTR(handle->conn, name, XATTR_NTACL_NAME);
+ SMB_VFS_REMOVEXATTR(handle->conn, smb_fname,
+ XATTR_NTACL_NAME);
unbecome_root();
return ret;
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;
}
+ ok = init_acl_common_config(handle);
+ 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_xattr: setting 'inherit acls = true' "
lp_do_parameter(SNUM(handle->conn), "dos filemode", "true");
lp_do_parameter(SNUM(handle->conn), "force unknown acl user", "true");
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct acl_common_config,
+ return -1);
+
+ if (config->ignore_system_acls) {
+ mode_t create_mask = lp_create_mask(SNUM(handle->conn));
+ char *create_mask_str = NULL;
+
+ 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;
+ }
+
+ DBG_NOTICE("setting 'create mask = %s'\n", create_mask_str);
+
+ 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");
+ }
+
return 0;
}
static struct vfs_fn_pointers vfs_acl_xattr_fns = {
.connect_fn = connect_acl_xattr,
- .opendir = opendir_acl_common,
- .mkdir = mkdir_acl_common,
- .rmdir = rmdir_acl_common,
- .open = open_acl_common,
- .create_file = create_file_acl_common,
- .unlink = unlink_acl_common,
- .fget_nt_acl = fget_nt_acl_common,
- .get_nt_acl = get_nt_acl_common,
- .fset_nt_acl = fset_nt_acl_common,
- .sys_acl_set_file = sys_acl_set_file_xattr,
- .sys_acl_set_fd = sys_acl_set_fd_xattr
+ .rmdir_fn = rmdir_acl_common,
+ .unlink_fn = unlink_acl_common,
+ .chmod_fn = chmod_acl_module_common,
+ .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_xattr,
+ .sys_acl_set_fd_fn = sys_acl_set_fd_xattr
};
-NTSTATUS vfs_acl_xattr_init(void)
+static_decl_vfs;
+NTSTATUS vfs_acl_xattr_init(TALLOC_CTX *ctx)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "acl_xattr",
&vfs_acl_xattr_fns);