diff options
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/include/proto.h | 1 | ||||
| -rw-r--r-- | source3/lib/errmap_unix.c | 136 | ||||
| -rw-r--r-- | source3/libsmb/clierror.c | 140 | ||||
| -rw-r--r-- | source3/modules/vfs_acl_xattr.c | 58 | 
4 files changed, 175 insertions, 160 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 30e309cd4e..d7acdcb910 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -515,6 +515,7 @@ void display_set_stderr(void);  /* The following definitions come from lib/errmap_unix.c  */  NTSTATUS map_nt_error_from_unix(int unix_error); +int map_errno_from_nt_status(NTSTATUS status);  /* The following definitions come from lib/events.c  */ diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 2cd2386c5c..9adb237096 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -128,3 +128,139 @@ NTSTATUS map_nt_error_from_unix(int unix_error)  	/* Default return */  	return NT_STATUS_ACCESS_DENIED;  } + +/* Return a UNIX errno from a NT status code */ +static const struct { +	NTSTATUS status; +	int error; +} nt_errno_map[] = { +        {NT_STATUS_ACCESS_VIOLATION, EACCES}, +        {NT_STATUS_INVALID_HANDLE, EBADF}, +        {NT_STATUS_ACCESS_DENIED, EACCES}, +        {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, +        {NT_STATUS_OBJECT_PATH_NOT_FOUND, ENOENT}, +        {NT_STATUS_SHARING_VIOLATION, EBUSY}, +        {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, +        {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, +        {NT_STATUS_PATH_NOT_COVERED, ENOENT}, +	{NT_STATUS_UNSUCCESSFUL, EINVAL}, +	{NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, +	{NT_STATUS_IN_PAGE_ERROR, EFAULT},  +	{NT_STATUS_BAD_NETWORK_NAME, ENOENT}, +#ifdef EDQUOT +	{NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, +	{NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, +	{NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, +	{NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, +#endif +#ifdef ETIME +	{NT_STATUS_TIMER_NOT_CANCELED, ETIME}, +#endif +	{NT_STATUS_INVALID_PARAMETER, EINVAL}, +	{NT_STATUS_NO_SUCH_DEVICE, ENODEV}, +	{NT_STATUS_NO_SUCH_FILE, ENOENT}, +#ifdef ENODATA +	{NT_STATUS_END_OF_FILE, ENODATA},  +#endif +#ifdef ENOMEDIUM +	{NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM},  +	{NT_STATUS_NO_MEDIA, ENOMEDIUM}, +#endif +	{NT_STATUS_NONEXISTENT_SECTOR, ESPIPE},  +        {NT_STATUS_NO_MEMORY, ENOMEM}, +	{NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, +	{NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, +	{NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, +	{NT_STATUS_ACCESS_DENIED, EACCES},  +	{NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, +	{NT_STATUS_WRONG_PASSWORD, EACCES}, +	{NT_STATUS_LOGON_FAILURE, EACCES}, +	{NT_STATUS_INVALID_WORKSTATION, EACCES}, +	{NT_STATUS_INVALID_LOGON_HOURS, EACCES}, +	{NT_STATUS_PASSWORD_EXPIRED, EACCES}, +	{NT_STATUS_ACCOUNT_DISABLED, EACCES}, +	{NT_STATUS_DISK_FULL, ENOSPC}, +	{NT_STATUS_INVALID_PIPE_STATE, EPIPE}, +	{NT_STATUS_PIPE_BUSY, EPIPE}, +	{NT_STATUS_PIPE_DISCONNECTED, EPIPE}, +	{NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS}, +	{NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, +	{NT_STATUS_NOT_SUPPORTED, ENOSYS}, +	{NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, +	{NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, +	{NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, +	{NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, +	{NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, +	{NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, +	{NT_STATUS_TOO_MANY_LINKS, EMLINK}, +	{NT_STATUS_NETWORK_BUSY, EBUSY}, +	{NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, +#ifdef ELIBACC +	{NT_STATUS_DLL_NOT_FOUND, ELIBACC}, +#endif +	{NT_STATUS_PIPE_BROKEN, EPIPE}, +	{NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, +	{NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, +	{NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, +#ifdef EPROTO +	{NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, +#endif +	{NT_STATUS_FLOAT_OVERFLOW, ERANGE}, +	{NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, +	{NT_STATUS_INTEGER_OVERFLOW, ERANGE}, +	{NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, +	{NT_STATUS_PIPE_CONNECTED, EISCONN}, +	{NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, +	{NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, +	{NT_STATUS_ILL_FORMED_PASSWORD, EACCES}, +	{NT_STATUS_PASSWORD_RESTRICTION, EACCES}, +	{NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, +	{NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, +	{NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, +	{NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, +	{NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, +	{NT_STATUS_CONNECTION_RESET, ENETRESET}, +#ifdef ENOTUNIQ +	{NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, +	{NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, +#endif +	{NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, +	{NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, +	{NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, +	{NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, +	{NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, +	{NT_STATUS_RETRY, EAGAIN}, +#ifdef ENOTUNIQ +	{NT_STATUS_DUPLICATE_NAME, ENOTUNIQ}, +#endif +#ifdef ECOMM +	{NT_STATUS_NET_WRITE_FAULT, ECOMM}, +#endif +#ifdef EXDEV +	{NT_STATUS_NOT_SAME_DEVICE, EXDEV}, +#endif +	{NT_STATUS(0), 0} +}; + +int map_errno_from_nt_status(NTSTATUS status) +{ +	int i; +	DEBUG(10,("map_errno_from_nt_status: 32 bit codes: code=%08x\n", +		NT_STATUS_V(status))); + +	/* Status codes without this bit set are not errors */ + +	if (!(NT_STATUS_V(status) & 0xc0000000)) { +		return 0; +	} + +	for (i=0;nt_errno_map[i].error;i++) { +		if (NT_STATUS_V(nt_errno_map[i].status) == +			    NT_STATUS_V(status)) { +			return nt_errno_map[i].error; +		} +	} + +	/* for all other cases - a default code */ +	return EINVAL; +} diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 36746419f7..54f8a7a43c 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -236,142 +236,6 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode)  	*ecode  = SVAL(cli->inbuf,smb_err);  } -/* Return a UNIX errno from a NT status code */ -static const struct { -	NTSTATUS status; -	int error; -} nt_errno_map[] = { -        {NT_STATUS_ACCESS_VIOLATION, EACCES}, -        {NT_STATUS_INVALID_HANDLE, EBADF}, -        {NT_STATUS_ACCESS_DENIED, EACCES}, -        {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, -        {NT_STATUS_OBJECT_PATH_NOT_FOUND, ENOENT}, -        {NT_STATUS_SHARING_VIOLATION, EBUSY}, -        {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, -        {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, -        {NT_STATUS_PATH_NOT_COVERED, ENOENT}, -	{NT_STATUS_UNSUCCESSFUL, EINVAL}, -	{NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, -	{NT_STATUS_IN_PAGE_ERROR, EFAULT},  -	{NT_STATUS_BAD_NETWORK_NAME, ENOENT}, -#ifdef EDQUOT -	{NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, -	{NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, -	{NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, -	{NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, -#endif -#ifdef ETIME -	{NT_STATUS_TIMER_NOT_CANCELED, ETIME}, -#endif -	{NT_STATUS_INVALID_PARAMETER, EINVAL}, -	{NT_STATUS_NO_SUCH_DEVICE, ENODEV}, -	{NT_STATUS_NO_SUCH_FILE, ENOENT}, -#ifdef ENODATA -	{NT_STATUS_END_OF_FILE, ENODATA},  -#endif -#ifdef ENOMEDIUM -	{NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM},  -	{NT_STATUS_NO_MEDIA, ENOMEDIUM}, -#endif -	{NT_STATUS_NONEXISTENT_SECTOR, ESPIPE},  -        {NT_STATUS_NO_MEMORY, ENOMEM}, -	{NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, -	{NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, -	{NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, -	{NT_STATUS_ACCESS_DENIED, EACCES},  -	{NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, -	{NT_STATUS_WRONG_PASSWORD, EACCES}, -	{NT_STATUS_LOGON_FAILURE, EACCES}, -	{NT_STATUS_INVALID_WORKSTATION, EACCES}, -	{NT_STATUS_INVALID_LOGON_HOURS, EACCES}, -	{NT_STATUS_PASSWORD_EXPIRED, EACCES}, -	{NT_STATUS_ACCOUNT_DISABLED, EACCES}, -	{NT_STATUS_DISK_FULL, ENOSPC}, -	{NT_STATUS_INVALID_PIPE_STATE, EPIPE}, -	{NT_STATUS_PIPE_BUSY, EPIPE}, -	{NT_STATUS_PIPE_DISCONNECTED, EPIPE}, -	{NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS}, -	{NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, -	{NT_STATUS_NOT_SUPPORTED, ENOSYS}, -	{NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, -	{NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, -	{NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, -	{NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, -	{NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, -	{NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, -	{NT_STATUS_TOO_MANY_LINKS, EMLINK}, -	{NT_STATUS_NETWORK_BUSY, EBUSY}, -	{NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, -#ifdef ELIBACC -	{NT_STATUS_DLL_NOT_FOUND, ELIBACC}, -#endif -	{NT_STATUS_PIPE_BROKEN, EPIPE}, -	{NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, -	{NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, -	{NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, -#ifdef EPROTO -	{NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, -#endif -	{NT_STATUS_FLOAT_OVERFLOW, ERANGE}, -	{NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, -	{NT_STATUS_INTEGER_OVERFLOW, ERANGE}, -	{NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, -	{NT_STATUS_PIPE_CONNECTED, EISCONN}, -	{NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, -	{NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, -	{NT_STATUS_ILL_FORMED_PASSWORD, EACCES}, -	{NT_STATUS_PASSWORD_RESTRICTION, EACCES}, -	{NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, -	{NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, -	{NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, -	{NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, -	{NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, -	{NT_STATUS_CONNECTION_RESET, ENETRESET}, -#ifdef ENOTUNIQ -	{NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, -	{NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, -#endif -	{NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, -	{NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, -	{NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, -	{NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, -	{NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, -	{NT_STATUS_RETRY, EAGAIN}, -#ifdef ENOTUNIQ -	{NT_STATUS_DUPLICATE_NAME, ENOTUNIQ}, -#endif -#ifdef ECOMM -	{NT_STATUS_NET_WRITE_FAULT, ECOMM}, -#endif -#ifdef EXDEV -	{NT_STATUS_NOT_SAME_DEVICE, EXDEV}, -#endif -	{NT_STATUS(0), 0} -}; - -/**************************************************************************** - The following mappings need tidying up and moving into libsmb/errormap.c... -****************************************************************************/ - -static int cli_errno_from_nt(NTSTATUS status) -{ -	int i; -        DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status))); - -        /* Status codes without this bit set are not errors */ - -        if (!(NT_STATUS_V(status) & 0xc0000000)) { -                return 0; -	} - -	for (i=0;nt_errno_map[i].error;i++) { -		if (NT_STATUS_V(nt_errno_map[i].status) == -		    NT_STATUS_V(status)) return nt_errno_map[i].error; -	} - -        /* for all other cases - a default code */ -        return EINVAL; -}  /* Return a UNIX errno appropriate for the error received in the last     packet. */ @@ -382,7 +246,7 @@ int cli_errno(struct cli_state *cli)  	if (cli_is_nt_error(cli)) {  		status = cli_nt_error(cli); -		return cli_errno_from_nt(status); +		return map_errno_from_nt_status(status);  	}          if (cli_is_dos_error(cli)) { @@ -391,7 +255,7 @@ int cli_errno(struct cli_state *cli)                  cli_dos_error(cli, &eclass, &ecode);  		status = dos_to_ntstatus(eclass, ecode); -		return cli_errno_from_nt(status); +		return map_errno_from_nt_status(status);          }          /* diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index a2f3477b76..80e44e51fc 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -133,26 +133,6 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,  	return NT_STATUS_OK;  } -static int mkdir_acl_xattr(vfs_handle_struct *handle,  const char *path, mode_t mode) -{ -	return SMB_VFS_NEXT_MKDIR(handle, path, mode); -} - -static int rmdir_acl_xattr(vfs_handle_struct *handle,  const char *path) -{ -	return SMB_VFS_NEXT_RMDIR(handle, path); -} - -static int open_acl_xattr(vfs_handle_struct *handle,  const char *fname, files_struct *fsp, int flags, mode_t mode) -{ -	return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); -} - -static int unlink_acl_xattr(vfs_handle_struct *handle,  const char *fname) -{ -	return SMB_VFS_NEXT_UNLINK(handle, fname); -} -  static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,  					files_struct *fsp,  					const char *name, @@ -198,6 +178,42 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,  	return status;  } +static int mkdir_acl_xattr(vfs_handle_struct *handle,  const char *path, mode_t mode) +{ +	return SMB_VFS_NEXT_MKDIR(handle, path, mode); +} + +/********************************************************************* + * Currently this only works for existing files. Need to work on + * inheritance for new files. +*********************************************************************/ + +static int open_acl_xattr(vfs_handle_struct *handle,  const char *fname, files_struct *fsp, int flags, mode_t mode) +{ +	uint32_t access_granted = 0; +	SEC_DESC *pdesc = NULL; +	NTSTATUS status = get_nt_acl_xattr_internal(handle, +					NULL, +					fname, +					(OWNER_SECURITY_INFORMATION | +					 GROUP_SECURITY_INFORMATION | +					 DACL_SECURITY_INFORMATION), +					&pdesc); +        if (NT_STATUS_IS_OK(status)) { +		/* See if we can access it. */ +		if (!se_access_check(pdesc, +					handle->conn->server_info->ptok, +					fsp->access_mask, +					&access_granted, +					&status)) { +			errno = map_errno_from_nt_status(status); +			return -1; +		} +        } + +	return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); +} +  static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,          uint32 security_info, SEC_DESC **ppdesc)  { @@ -312,9 +328,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,  static vfs_op_tuple skel_op_tuples[] =  {  	{SMB_VFS_OP(mkdir_acl_xattr), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT}, -	{SMB_VFS_OP(rmdir_acl_xattr), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},  	{SMB_VFS_OP(open_acl_xattr),  SMB_VFS_OP_OPEN,  SMB_VFS_LAYER_TRANSPARENT}, -	{SMB_VFS_OP(unlink_acl_xattr),SMB_VFS_OP_UNLINK,SMB_VFS_LAYER_TRANSPARENT},          /* NT File ACL operations */  | 
