2007-11-17 04:07:11 +03:00
/*
2003-08-28 00:04:23 +04:00
* CAP VFS module for Samba 3. x Version 0.3
*
* Copyright ( C ) Tim Potter , 1999 - 2000
* Copyright ( C ) Alexander Bokovoy , 2002 - 2003
* Copyright ( C ) Stefan ( metze ) Metzmacher , 2003
* Copyright ( C ) TAKAHASHI Motonobu ( monyo ) , 2003
2007-11-17 04:07:11 +03:00
* Copyright ( C ) Jeremy Allison , 2007
2003-08-28 00:04:23 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2003-08-28 00:04:23 +04:00
* ( at your option ) any later version .
2007-11-17 04:07:11 +03:00
*
2003-08-28 00:04:23 +04:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2007-11-17 04:07:11 +03:00
*
2003-08-28 00:04:23 +04:00
* You should have received a copy of the GNU General Public License
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2003-08-28 00:04:23 +04:00
*/
# include "includes.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2003-08-28 00:04:23 +04:00
/* cap functions */
2007-11-17 04:07:11 +03:00
static char * capencode ( TALLOC_CTX * ctx , const char * from ) ;
static char * capdecode ( TALLOC_CTX * ctx , const char * from ) ;
2003-08-28 00:04:23 +04:00
2008-10-14 03:59:36 +04:00
static uint64_t cap_disk_free ( vfs_handle_struct * handle , const char * path ,
2015-02-16 21:26:24 +03:00
uint64_t * bsize , uint64_t * dfree , uint64_t * dsize )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
2008-10-14 03:59:36 +04:00
return ( uint64_t ) - 1 ;
2007-11-17 04:07:11 +03:00
}
2015-02-16 21:26:24 +03:00
return SMB_VFS_NEXT_DISK_FREE ( handle , cappath , bsize , dfree , dsize ) ;
2003-08-28 00:04:23 +04:00
}
2016-01-10 15:10:10 +03:00
static int cap_get_quota ( vfs_handle_struct * handle , const char * path ,
enum SMB_QUOTA_TYPE qtype , unid_t id ,
SMB_DISK_QUOTA * dq )
{
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
return SMB_VFS_NEXT_GET_QUOTA ( handle , cappath , qtype , id , dq ) ;
}
2016-02-27 01:53:12 +03:00
static DIR * cap_opendir ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
const char * mask ,
uint32_t attr )
2003-08-28 00:04:23 +04:00
{
2016-02-27 01:53:12 +03:00
char * capname = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
struct smb_filename * cap_smb_fname = NULL ;
2007-11-17 04:07:11 +03:00
if ( ! capname ) {
errno = ENOMEM ;
return NULL ;
}
2016-02-27 01:53:12 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
capname ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-27 01:53:12 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( capname ) ;
errno = ENOMEM ;
return NULL ;
}
return SMB_VFS_NEXT_OPENDIR ( handle , cap_smb_fname , mask , attr ) ;
2003-08-28 00:04:23 +04:00
}
2012-03-28 06:18:14 +04:00
static struct dirent * cap_readdir ( vfs_handle_struct * handle ,
2012-03-28 06:22:03 +04:00
DIR * dirp ,
2009-07-19 04:32:44 +04:00
SMB_STRUCT_STAT * sbuf )
2003-08-28 00:04:23 +04:00
{
2012-03-28 06:18:14 +04:00
struct dirent * result ;
struct dirent * newdirent ;
2007-11-17 04:07:11 +03:00
char * newname ;
size_t newnamelen ;
2003-08-28 00:04:23 +04:00
DEBUG ( 3 , ( " cap: cap_readdir \n " ) ) ;
2007-11-17 04:07:11 +03:00
2009-01-23 07:14:38 +03:00
result = SMB_VFS_NEXT_READDIR ( handle , dirp , NULL ) ;
2007-11-17 04:07:11 +03:00
if ( ! result ) {
return NULL ;
}
newname = capdecode ( talloc_tos ( ) , result - > d_name ) ;
if ( ! newname ) {
return NULL ;
}
DEBUG ( 3 , ( " cap: cap_readdir: %s \n " , newname ) ) ;
newnamelen = strlen ( newname ) + 1 ;
2015-11-08 12:43:59 +03:00
newdirent = talloc_size (
talloc_tos ( ) , sizeof ( struct dirent ) + newnamelen ) ;
2007-11-17 04:07:11 +03:00
if ( ! newdirent ) {
return NULL ;
}
2015-11-08 12:43:59 +03:00
talloc_set_name_const ( newdirent , " struct dirent " ) ;
2012-03-28 06:18:14 +04:00
memcpy ( newdirent , result , sizeof ( struct dirent ) ) ;
2007-11-17 04:07:11 +03:00
memcpy ( & newdirent - > d_name , newname , newnamelen ) ;
return newdirent ;
2003-08-28 00:04:23 +04:00
}
2016-02-24 00:14:03 +03:00
static int cap_mkdir ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
mode_t mode )
2003-08-28 00:04:23 +04:00
{
2016-02-24 00:14:03 +03:00
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
struct smb_filename * cap_smb_fname = NULL ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2016-02-24 00:14:03 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-24 00:14:03 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
return SMB_VFS_NEXT_MKDIR ( handle , cap_smb_fname , mode ) ;
2003-08-28 00:04:23 +04:00
}
2016-02-25 01:02:45 +03:00
static int cap_rmdir ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
2003-08-28 00:04:23 +04:00
{
2016-02-25 01:02:45 +03:00
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
struct smb_filename * cap_smb_fname = NULL ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2016-02-25 01:02:45 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-02-25 01:02:45 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
return SMB_VFS_NEXT_RMDIR ( handle , cap_smb_fname ) ;
2003-08-28 00:04:23 +04:00
}
2009-06-16 23:01:13 +04:00
static int cap_open ( vfs_handle_struct * handle , struct smb_filename * smb_fname ,
files_struct * fsp , int flags , mode_t mode )
2003-08-28 00:04:23 +04:00
{
2009-06-16 23:01:13 +04:00
char * cappath ;
char * tmp_base_name = NULL ;
int ret ;
cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2009-06-16 23:01:13 +04:00
tmp_base_name = smb_fname - > base_name ;
smb_fname - > base_name = cappath ;
DEBUG ( 3 , ( " cap: cap_open for %s \n " , smb_fname_str_dbg ( smb_fname ) ) ) ;
ret = SMB_VFS_NEXT_OPEN ( handle , smb_fname , fsp , flags , mode ) ;
smb_fname - > base_name = tmp_base_name ;
TALLOC_FREE ( cappath ) ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2009-07-01 04:04:38 +04:00
static int cap_rename ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname_src ,
const struct smb_filename * smb_fname_dst )
2003-08-28 00:04:23 +04:00
{
2009-07-01 04:04:38 +04:00
char * capold = NULL ;
char * capnew = NULL ;
struct smb_filename * smb_fname_src_tmp = NULL ;
struct smb_filename * smb_fname_dst_tmp = NULL ;
int ret = - 1 ;
capold = capencode ( talloc_tos ( ) , smb_fname_src - > base_name ) ;
capnew = capencode ( talloc_tos ( ) , smb_fname_dst - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! capold | | ! capnew ) {
errno = ENOMEM ;
2009-07-01 04:04:38 +04:00
goto out ;
}
/* Setup temporary smb_filename structs. */
2013-04-11 18:16:58 +04:00
smb_fname_src_tmp = cp_smb_filename ( talloc_tos ( ) , smb_fname_src ) ;
if ( smb_fname_src_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-01 04:04:38 +04:00
goto out ;
}
2013-04-11 18:16:58 +04:00
smb_fname_dst_tmp = cp_smb_filename ( talloc_tos ( ) , smb_fname_dst ) ;
if ( smb_fname_dst_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-01 04:04:38 +04:00
goto out ;
2007-11-17 04:07:11 +03:00
}
2009-07-01 04:04:38 +04:00
smb_fname_src_tmp - > base_name = capold ;
smb_fname_dst_tmp - > base_name = capnew ;
ret = SMB_VFS_NEXT_RENAME ( handle , smb_fname_src_tmp ,
smb_fname_dst_tmp ) ;
out :
TALLOC_FREE ( capold ) ;
TALLOC_FREE ( capnew ) ;
TALLOC_FREE ( smb_fname_src_tmp ) ;
TALLOC_FREE ( smb_fname_dst_tmp ) ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2009-06-23 02:26:56 +04:00
static int cap_stat ( vfs_handle_struct * handle , struct smb_filename * smb_fname )
2003-08-28 00:04:23 +04:00
{
2009-06-23 02:26:56 +04:00
char * cappath ;
char * tmp_base_name = NULL ;
int ret ;
cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2009-06-23 02:26:56 +04:00
tmp_base_name = smb_fname - > base_name ;
smb_fname - > base_name = cappath ;
ret = SMB_VFS_NEXT_STAT ( handle , smb_fname ) ;
smb_fname - > base_name = tmp_base_name ;
TALLOC_FREE ( cappath ) ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2009-06-23 02:26:56 +04:00
static int cap_lstat ( vfs_handle_struct * handle , struct smb_filename * smb_fname )
2003-08-28 00:04:23 +04:00
{
2009-06-23 02:26:56 +04:00
char * cappath ;
char * tmp_base_name = NULL ;
int ret ;
cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2009-06-23 02:26:56 +04:00
tmp_base_name = smb_fname - > base_name ;
smb_fname - > base_name = cappath ;
ret = SMB_VFS_NEXT_LSTAT ( handle , smb_fname ) ;
smb_fname - > base_name = tmp_base_name ;
TALLOC_FREE ( cappath ) ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2009-07-02 20:27:44 +04:00
static int cap_unlink ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
2003-08-28 00:04:23 +04:00
{
2009-07-02 20:27:44 +04:00
struct smb_filename * smb_fname_tmp = NULL ;
char * cappath = NULL ;
int ret ;
2007-11-17 04:07:11 +03:00
2009-07-02 20:27:44 +04:00
cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2009-07-02 20:27:44 +04:00
/* Setup temporary smb_filename structs. */
2013-04-11 18:17:42 +04:00
smb_fname_tmp = cp_smb_filename ( talloc_tos ( ) , smb_fname ) ;
if ( smb_fname_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-02 20:27:44 +04:00
return - 1 ;
}
smb_fname_tmp - > base_name = cappath ;
ret = SMB_VFS_NEXT_UNLINK ( handle , smb_fname_tmp ) ;
TALLOC_FREE ( smb_fname_tmp ) ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2016-03-02 03:20:25 +03:00
static int cap_chmod ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
mode_t mode )
2003-08-28 00:04:23 +04:00
{
2016-03-02 03:20:25 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
int ret ;
int saved_errno ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2016-03-02 03:20:25 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-02 03:20:25 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_CHMOD ( handle , cap_smb_fname , mode ) ;
saved_errno = errno ;
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
errno = saved_errno ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2016-03-03 22:54:23 +03:00
static int cap_chown ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
uid_t uid ,
gid_t gid )
2003-08-28 00:04:23 +04:00
{
2016-03-03 22:54:23 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
int ret ;
int saved_errno ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2016-03-03 22:54:23 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-03 22:54:23 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_CHOWN ( handle , cap_smb_fname , uid , gid ) ;
saved_errno = errno ;
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
errno = saved_errno ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2016-03-04 01:34:57 +03:00
static int cap_lchown ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
uid_t uid ,
gid_t gid )
2007-05-24 03:55:12 +04:00
{
2016-03-04 01:34:57 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
int ret ;
int saved_errno ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2016-03-04 01:34:57 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-04 01:34:57 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_LCHOWN ( handle , cap_smb_fname , uid , gid ) ;
saved_errno = errno ;
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
errno = saved_errno ;
return ret ;
2007-05-24 03:55:12 +04:00
}
2006-07-11 22:01:26 +04:00
static int cap_chdir ( vfs_handle_struct * handle , const char * path )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2003-08-28 00:04:23 +04:00
DEBUG ( 3 , ( " cap: cap_chdir for %s \n " , path ) ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_CHDIR ( handle , cappath ) ;
2003-08-28 00:04:23 +04:00
}
2009-07-03 00:39:20 +04:00
static int cap_ntimes ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
2009-01-24 01:40:19 +03:00
struct smb_file_time * ft )
2003-08-28 00:04:23 +04:00
{
2009-07-03 00:39:20 +04:00
struct smb_filename * smb_fname_tmp = NULL ;
char * cappath = NULL ;
int ret ;
cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2009-07-03 00:39:20 +04:00
/* Setup temporary smb_filename structs. */
2013-04-11 18:18:39 +04:00
smb_fname_tmp = cp_smb_filename ( talloc_tos ( ) , smb_fname ) ;
if ( smb_fname_tmp = = NULL ) {
errno = ENOMEM ;
2009-07-03 00:39:20 +04:00
return - 1 ;
}
smb_fname_tmp - > base_name = cappath ;
ret = SMB_VFS_NEXT_NTIMES ( handle , smb_fname_tmp , ft ) ;
TALLOC_FREE ( smb_fname_tmp ) ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2009-07-19 04:32:44 +04:00
static int cap_symlink ( vfs_handle_struct * handle , const char * oldpath ,
const char * newpath )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * capold = capencode ( talloc_tos ( ) , oldpath ) ;
char * capnew = capencode ( talloc_tos ( ) , newpath ) ;
if ( ! capold | | ! capnew ) {
errno = ENOMEM ;
return - 1 ;
}
return SMB_VFS_NEXT_SYMLINK ( handle , capold , capnew ) ;
2003-08-28 00:04:23 +04:00
}
2009-07-19 04:32:44 +04:00
static int cap_readlink ( vfs_handle_struct * handle , const char * path ,
char * buf , size_t bufsiz )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_READLINK ( handle , cappath , buf , bufsiz ) ;
2003-08-28 00:04:23 +04:00
}
2006-07-11 22:01:26 +04:00
static int cap_link ( vfs_handle_struct * handle , const char * oldpath , const char * newpath )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * capold = capencode ( talloc_tos ( ) , oldpath ) ;
char * capnew = capencode ( talloc_tos ( ) , newpath ) ;
if ( ! capold | | ! capnew ) {
errno = ENOMEM ;
return - 1 ;
}
return SMB_VFS_NEXT_LINK ( handle , capold , capnew ) ;
2003-08-28 00:04:23 +04:00
}
2006-07-11 22:01:26 +04:00
static int cap_mknod ( vfs_handle_struct * handle , const char * path , mode_t mode , SMB_DEV_T dev )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_MKNOD ( handle , cappath , mode , dev ) ;
2003-08-28 00:04:23 +04:00
}
2010-11-20 03:29:26 +03:00
static char * cap_realpath ( vfs_handle_struct * handle , const char * path )
2003-08-28 00:04:23 +04:00
{
/* monyo need capencode'ed and capdecode'ed? */
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return NULL ;
}
2010-11-20 03:29:26 +03:00
return SMB_VFS_NEXT_REALPATH ( handle , cappath ) ;
2003-08-28 00:04:23 +04:00
}
2016-03-02 04:25:25 +03:00
static int cap_chmod_acl ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
mode_t mode )
2003-08-28 00:04:23 +04:00
{
2016-03-02 04:25:25 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
int ret ;
int saved_errno ;
2003-08-28 00:04:23 +04:00
/* If the underlying VFS doesn't have ACL support... */
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2016-03-02 04:25:25 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
2016-03-19 07:19:38 +03:00
NULL ,
smb_fname - > flags ) ;
2016-03-02 04:25:25 +03:00
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_CHMOD_ACL ( handle , cap_smb_fname , mode ) ;
saved_errno = errno ;
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
errno = saved_errno ;
return ret ;
2003-08-28 00:04:23 +04:00
}
2012-10-10 03:18:32 +04:00
static SMB_ACL_T cap_sys_acl_get_file ( vfs_handle_struct * handle ,
2017-05-24 03:11:18 +03:00
const struct smb_filename * smb_fname ,
SMB_ACL_TYPE_T type ,
TALLOC_CTX * mem_ctx )
2003-08-28 00:04:23 +04:00
{
2017-05-24 03:11:18 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
SMB_ACL_T ret ;
int saved_errno = 0 ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return ( SMB_ACL_T ) NULL ;
}
2017-05-24 03:11:18 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
NULL ,
smb_fname - > flags ) ;
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return ( SMB_ACL_T ) NULL ;
}
ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE ( handle , cap_smb_fname ,
type , mem_ctx ) ;
if ( ret = = NULL ) {
saved_errno = errno ;
}
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
if ( saved_errno ! = 0 ) {
errno = saved_errno ;
}
return ret ;
2003-08-28 00:04:23 +04:00
}
2017-05-24 20:47:46 +03:00
static int cap_sys_acl_set_file ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
SMB_ACL_TYPE_T acltype ,
SMB_ACL_T theacl )
2003-08-28 00:04:23 +04:00
{
2017-05-24 20:47:46 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
int ret ;
int saved_errno = 0 ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2017-05-24 20:47:46 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
NULL ,
smb_fname - > flags ) ;
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE ( handle , cap_smb_fname ,
acltype , theacl ) ;
if ( ret = = - 1 ) {
saved_errno = errno ;
}
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
if ( saved_errno ! = 0 ) {
errno = saved_errno ;
}
return ret ;
2003-08-28 00:04:23 +04:00
}
2017-05-24 01:33:31 +03:00
static int cap_sys_acl_delete_def_file ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname )
2003-08-28 00:04:23 +04:00
{
2017-05-24 01:33:31 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
int ret ;
int saved_errno = 0 ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2017-05-24 01:33:31 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
NULL ,
smb_fname - > flags ) ;
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE ( handle , cap_smb_fname ) ;
if ( ret = = - 1 ) {
saved_errno = errno ;
}
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
if ( saved_errno ) {
errno = saved_errno ;
}
return ret ;
2003-08-28 00:04:23 +04:00
}
2006-07-11 22:01:26 +04:00
static ssize_t cap_getxattr ( vfs_handle_struct * handle , const char * path , const char * name , void * value , size_t size )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
char * capname = capencode ( talloc_tos ( ) , name ) ;
if ( ! cappath | | ! capname ) {
errno = ENOMEM ;
return - 1 ;
}
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_GETXATTR ( handle , cappath , capname , value , size ) ;
2003-08-28 00:04:23 +04:00
}
2008-01-08 12:00:47 +03:00
static ssize_t cap_fgetxattr ( vfs_handle_struct * handle , struct files_struct * fsp , const char * path , void * value , size_t size )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2008-01-08 12:00:47 +03:00
return SMB_VFS_NEXT_FGETXATTR ( handle , fsp , cappath , value , size ) ;
2003-08-28 00:04:23 +04:00
}
2017-05-23 23:12:29 +03:00
static ssize_t cap_listxattr ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
char * list ,
size_t size )
2003-08-28 00:04:23 +04:00
{
2017-05-23 23:12:29 +03:00
struct smb_filename * cap_smb_fname = NULL ;
char * cappath = capencode ( talloc_tos ( ) , smb_fname - > base_name ) ;
ssize_t ret ;
int saved_errno = 0 ;
2007-11-17 04:07:11 +03:00
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2017-05-23 23:12:29 +03:00
cap_smb_fname = synthetic_smb_fname ( talloc_tos ( ) ,
cappath ,
NULL ,
NULL ,
smb_fname - > flags ) ;
if ( cap_smb_fname = = NULL ) {
TALLOC_FREE ( cappath ) ;
errno = ENOMEM ;
return - 1 ;
}
ret = SMB_VFS_NEXT_LISTXATTR ( handle , cap_smb_fname , list , size ) ;
if ( ret = = - 1 ) {
saved_errno = errno ;
}
TALLOC_FREE ( cappath ) ;
TALLOC_FREE ( cap_smb_fname ) ;
if ( saved_errno ) {
errno = saved_errno ;
}
return ret ;
2003-08-28 00:04:23 +04:00
}
2006-07-11 22:01:26 +04:00
static int cap_removexattr ( vfs_handle_struct * handle , const char * path , const char * name )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
char * capname = capencode ( talloc_tos ( ) , name ) ;
if ( ! cappath | | ! capname ) {
errno = ENOMEM ;
return - 1 ;
}
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_REMOVEXATTR ( handle , cappath , capname ) ;
2003-08-28 00:04:23 +04:00
}
2008-01-08 13:29:09 +03:00
static int cap_fremovexattr ( vfs_handle_struct * handle , struct files_struct * fsp , const char * path )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2008-01-08 13:29:09 +03:00
return SMB_VFS_NEXT_FREMOVEXATTR ( handle , fsp , cappath ) ;
2003-08-28 00:04:23 +04:00
}
2006-07-11 22:01:26 +04:00
static int cap_setxattr ( vfs_handle_struct * handle , const char * path , const char * name , const void * value , size_t size , int flags )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
char * capname = capencode ( talloc_tos ( ) , name ) ;
if ( ! cappath | | ! capname ) {
errno = ENOMEM ;
return - 1 ;
}
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_SETXATTR ( handle , cappath , capname , value , size , flags ) ;
2003-08-28 00:04:23 +04:00
}
2008-01-08 13:47:33 +03:00
static int cap_fsetxattr ( vfs_handle_struct * handle , struct files_struct * fsp , const char * path , const void * value , size_t size , int flags )
2003-08-28 00:04:23 +04:00
{
2007-11-17 04:07:11 +03:00
char * cappath = capencode ( talloc_tos ( ) , path ) ;
if ( ! cappath ) {
errno = ENOMEM ;
return - 1 ;
}
2008-01-08 13:47:33 +03:00
return SMB_VFS_NEXT_FSETXATTR ( handle , fsp , cappath , value , size , flags ) ;
2003-08-28 00:04:23 +04:00
}
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers vfs_cap_fns = {
2011-12-04 08:45:04 +04:00
. disk_free_fn = cap_disk_free ,
2016-01-10 15:10:10 +03:00
. get_quota_fn = cap_get_quota ,
2011-12-04 08:45:04 +04:00
. opendir_fn = cap_opendir ,
. readdir_fn = cap_readdir ,
. mkdir_fn = cap_mkdir ,
. rmdir_fn = cap_rmdir ,
2011-04-21 00:55:25 +04:00
. open_fn = cap_open ,
2011-12-04 08:45:04 +04:00
. rename_fn = cap_rename ,
. stat_fn = cap_stat ,
. lstat_fn = cap_lstat ,
. unlink_fn = cap_unlink ,
. chmod_fn = cap_chmod ,
. chown_fn = cap_chown ,
. lchown_fn = cap_lchown ,
. chdir_fn = cap_chdir ,
. ntimes_fn = cap_ntimes ,
. symlink_fn = cap_symlink ,
. readlink_fn = cap_readlink ,
. link_fn = cap_link ,
. mknod_fn = cap_mknod ,
. realpath_fn = cap_realpath ,
. chmod_acl_fn = cap_chmod_acl ,
. sys_acl_get_file_fn = cap_sys_acl_get_file ,
. sys_acl_set_file_fn = cap_sys_acl_set_file ,
. sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file ,
. getxattr_fn = cap_getxattr ,
. fgetxattr_fn = cap_fgetxattr ,
. listxattr_fn = cap_listxattr ,
. removexattr_fn = cap_removexattr ,
. fremovexattr_fn = cap_fremovexattr ,
. setxattr_fn = cap_setxattr ,
. fsetxattr_fn = cap_fsetxattr
2003-08-28 00:04:23 +04:00
} ;
2017-04-20 22:24:43 +03:00
NTSTATUS vfs_cap_init ( TALLOC_CTX * ) ;
NTSTATUS vfs_cap_init ( TALLOC_CTX * ctx )
2003-08-28 00:04:23 +04:00
{
2009-07-24 04:28:58 +04:00
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " cap " ,
& vfs_cap_fns ) ;
2003-08-28 00:04:23 +04:00
}
/* For CAP functions */
# define hex_tag ':'
# define hex2bin(c) hex2bin_table[(unsigned char)(c)]
# define bin2hex(c) bin2hex_table[(unsigned char)(c)]
# define is_hex(s) ((s)[0] == hex_tag)
static unsigned char hex2bin_table [ 256 ] = {
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x00 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x10 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x20 */
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x30 */
0000 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , 0000 , /* 0x40 */
0000 , 0000 , 0000 , 0000 , 0000 , 0000 , 0000 , 0000 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x50 */
0000 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , 0000 , /* 0x60 */
0000 , 0000 , 0000 , 0000 , 0000 , 0000 , 0000 , 0000 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x70 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x80 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0x90 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0xa0 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0xb0 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0xc0 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0xd0 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 0xe0 */
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 /* 0xf0 */
} ;
static unsigned char bin2hex_table [ 256 ] = " 0123456789abcdef " ;
/*******************************************************************
original code - > " :xx " - CAP format
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-17 04:07:11 +03:00
static char * capencode ( TALLOC_CTX * ctx , const char * from )
{
char * out = NULL ;
const char * p1 ;
char * to = NULL ;
size_t len = 0 ;
for ( p1 = from ; * p1 ; p1 + + ) {
if ( ( unsigned char ) * p1 > = 0x80 ) {
len + = 3 ;
} else {
len + + ;
}
}
len + + ;
2011-06-07 05:30:12 +04:00
to = talloc_array ( ctx , char , len ) ;
2007-11-17 04:07:11 +03:00
if ( ! to ) {
return NULL ;
}
for ( out = to ; * from ; ) {
/* buffer husoku error */
if ( ( unsigned char ) * from > = 0x80 ) {
* out + + = hex_tag ;
* out + + = bin2hex ( ( ( * from ) > > 4 ) & 0x0f ) ;
* out + + = bin2hex ( ( * from ) & 0x0f ) ;
from + + ;
} else {
* out + + = * from + + ;
}
}
* out = ' \0 ' ;
return to ;
2003-08-28 00:04:23 +04:00
}
/*******************************************************************
CAP - > original code
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* ":xx" -> a byte */
2007-11-17 04:07:11 +03:00
static char * capdecode ( TALLOC_CTX * ctx , const char * from )
{
const char * p1 ;
char * out = NULL ;
char * to = NULL ;
size_t len = 0 ;
for ( p1 = from ; * p1 ; len + + ) {
2010-01-13 08:43:23 +03:00
if ( is_hex ( p1 ) ) {
2007-11-17 04:07:11 +03:00
p1 + = 3 ;
} else {
p1 + + ;
}
}
2010-01-13 08:43:23 +03:00
len + + ;
2007-11-17 04:07:11 +03:00
2011-06-07 05:30:12 +04:00
to = talloc_array ( ctx , char , len ) ;
2007-11-17 04:07:11 +03:00
if ( ! to ) {
return NULL ;
}
for ( out = to ; * from ; ) {
if ( is_hex ( from ) ) {
* out + + = ( hex2bin ( from [ 1 ] ) < < 4 ) | ( hex2bin ( from [ 2 ] ) ) ;
from + = 3 ;
} else {
* out + + = * from + + ;
}
}
* out = ' \0 ' ;
return to ;
2003-08-28 00:04:23 +04:00
}