2011-07-15 17:57:26 +04:00
/*
2004-05-02 16:13:16 +04:00
* Convert AFS acls to NT acls and vice versa .
*
* Copyright ( C ) Volker Lendecke , 2003
*
* 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
2004-05-02 16:13:16 +04:00
* ( at your option ) any later version .
2011-07-15 17:57:26 +04:00
*
2004-05-02 16:13:16 +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 .
2011-07-15 17:57:26 +04:00
*
2004-05-02 16:13:16 +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/>.
2004-05-02 16:13:16 +04:00
*/
# include "includes.h"
2011-03-30 17:14:05 +04:00
# include "system/filesys.h"
2011-03-23 00:34:22 +03:00
# include "smbd/smbd.h"
2011-07-15 17:54:25 +04:00
# include "../librpc/gen_ndr/lsa.h"
# include "../libcli/security/security.h"
# include "../libcli/security/dom_sid.h"
# include "passdb.h"
2014-04-15 00:35:21 +04:00
# include "lib/afs/afs_settoken.h"
2004-05-02 16:13:16 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_VFS
# include <afs/stds.h>
2014-05-14 17:39:44 +04:00
# include <afs/afs_args.h>
2004-05-02 16:13:16 +04:00
# include <afs/venus.h>
# include <afs/prs_fs.h>
2011-05-04 01:08:27 +04:00
# define MAXSIZE 2049
2004-05-02 16:13:16 +04:00
2010-05-21 05:25:01 +04:00
extern const struct dom_sid global_sid_World ;
extern const struct dom_sid global_sid_Builtin_Administrators ;
extern const struct dom_sid global_sid_Builtin_Backup_Operators ;
extern const struct dom_sid global_sid_Authenticated_Users ;
extern const struct dom_sid global_sid_NULL ;
2004-05-02 16:13:16 +04:00
2004-12-17 12:05:41 +03:00
static char space_replacement = ' % ' ;
2005-11-08 23:13:26 +03:00
/* Do we expect SIDs as pts names? */
2007-10-19 04:40:25 +04:00
static bool sidpts ;
2005-11-08 23:13:26 +03:00
2004-05-02 16:13:16 +04:00
struct afs_ace {
2007-10-19 04:40:25 +04:00
bool positive ;
2004-05-02 16:13:16 +04:00
char * name ;
2010-05-21 05:25:01 +04:00
struct dom_sid sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2015-05-03 06:11:02 +03:00
uint32_t rights ;
2004-05-02 16:13:16 +04:00
struct afs_ace * next ;
} ;
struct afs_acl {
TALLOC_CTX * ctx ;
int type ;
int num_aces ;
struct afs_ace * acelist ;
} ;
struct afs_iob {
char * in , * out ;
2015-05-03 06:11:02 +03:00
uint16_t in_size , out_size ;
2004-05-02 16:13:16 +04:00
} ;
2007-10-19 04:40:25 +04:00
static bool init_afs_acl ( struct afs_acl * acl )
2004-05-02 16:13:16 +04:00
{
ZERO_STRUCT ( * acl ) ;
acl - > ctx = talloc_init ( " afs_acl " ) ;
if ( acl - > ctx = = NULL ) {
DEBUG ( 10 , ( " Could not init afs_acl " ) ) ;
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2011-07-15 17:58:40 +04:00
return true ;
2004-05-02 16:13:16 +04:00
}
static void free_afs_acl ( struct afs_acl * acl )
{
2004-08-17 14:48:31 +04:00
if ( acl - > ctx ! = NULL )
talloc_destroy ( acl - > ctx ) ;
acl - > ctx = NULL ;
acl - > num_aces = 0 ;
acl - > acelist = NULL ;
2004-05-02 16:13:16 +04:00
}
static struct afs_ace * clone_afs_ace ( TALLOC_CTX * mem_ctx , struct afs_ace * ace )
{
2011-06-07 05:38:41 +04:00
struct afs_ace * result = talloc ( mem_ctx , struct afs_ace ) ;
2004-05-02 16:13:16 +04:00
if ( result = = NULL )
return NULL ;
* result = * ace ;
result - > next = NULL ;
result - > name = talloc_strdup ( mem_ctx , ace - > name ) ;
if ( result - > name = = NULL ) {
return NULL ;
}
return result ;
}
static struct afs_ace * new_afs_ace ( TALLOC_CTX * mem_ctx ,
2007-10-19 04:40:25 +04:00
bool positive ,
2015-05-03 06:11:02 +03:00
const char * name , uint32_t rights )
2004-05-02 16:13:16 +04:00
{
2010-05-21 05:25:01 +04:00
struct dom_sid sid ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType type ;
2004-05-02 16:13:16 +04:00
struct afs_ace * result ;
if ( strcmp ( name , " system:administrators " ) = = 0 ) {
sid_copy ( & sid , & global_sid_Builtin_Administrators ) ;
type = SID_NAME_ALIAS ;
} else if ( strcmp ( name , " system:anyuser " ) = = 0 ) {
sid_copy ( & sid , & global_sid_World ) ;
type = SID_NAME_ALIAS ;
} else if ( strcmp ( name , " system:authuser " ) = = 0 ) {
sid_copy ( & sid , & global_sid_Authenticated_Users ) ;
type = SID_NAME_WKN_GRP ;
} else if ( strcmp ( name , " system:backup " ) = = 0 ) {
sid_copy ( & sid , & global_sid_Builtin_Backup_Operators ) ;
type = SID_NAME_ALIAS ;
2005-11-08 23:13:26 +03:00
} else if ( sidpts ) {
/* All PTS users/groups are expressed as SIDs */
sid_copy ( & sid , & global_sid_NULL ) ;
type = SID_NAME_UNKNOWN ;
if ( string_to_sid ( & sid , name ) ) {
2006-06-20 15:06:09 +04:00
const char * user , * domain ;
2005-11-08 23:13:26 +03:00
/* We have to find the type, look up the SID */
2007-08-30 23:48:31 +04:00
lookup_sid ( talloc_tos ( ) , & sid ,
2006-06-20 15:06:09 +04:00
& domain , & user , & type ) ;
2005-11-08 23:13:26 +03:00
}
2004-05-02 16:13:16 +04:00
} else {
2006-06-20 15:06:09 +04:00
const char * domain , * uname ;
2005-12-03 21:34:13 +03:00
char * p ;
2004-05-02 16:13:16 +04:00
2006-06-20 15:06:09 +04:00
p = strchr_m ( name , * lp_winbind_separator ( ) ) ;
2005-12-03 21:34:13 +03:00
if ( p ! = NULL ) {
* p = ' \\ ' ;
2004-05-02 16:13:16 +04:00
}
2005-12-03 21:34:13 +03:00
2007-08-30 23:48:31 +04:00
if ( ! lookup_name ( talloc_tos ( ) , name , LOOKUP_NAME_ALL ,
2006-06-20 15:06:09 +04:00
& domain , & uname , & sid , & type ) ) {
2004-05-02 16:13:16 +04:00
DEBUG ( 10 , ( " Could not find AFS user %s \n " , name ) ) ;
sid_copy ( & sid , & global_sid_NULL ) ;
type = SID_NAME_UNKNOWN ;
}
}
2011-06-07 05:38:41 +04:00
result = talloc ( mem_ctx , struct afs_ace ) ;
2004-05-02 16:13:16 +04:00
if ( result = = NULL ) {
DEBUG ( 0 , ( " Could not talloc AFS ace \n " ) ) ;
return NULL ;
}
result - > name = talloc_strdup ( mem_ctx , name ) ;
if ( result - > name = = NULL ) {
DEBUG ( 0 , ( " Could not talloc AFS ace name \n " ) ) ;
return NULL ;
}
result - > sid = sid ;
result - > type = type ;
result - > positive = positive ;
result - > rights = rights ;
return result ;
}
static void add_afs_ace ( struct afs_acl * acl ,
2007-10-19 04:40:25 +04:00
bool positive ,
2015-05-03 06:11:02 +03:00
const char * name , uint32_t rights )
2004-05-02 16:13:16 +04:00
{
struct afs_ace * ace ;
2004-08-17 14:48:31 +04:00
for ( ace = acl - > acelist ; ace ! = NULL ; ace = ace - > next ) {
if ( ( ace - > positive = = positive ) & &
( strequal ( ace - > name , name ) ) ) {
ace - > rights | = rights ;
return ;
}
}
2004-05-02 16:13:16 +04:00
ace = new_afs_ace ( acl - > ctx , positive , name , rights ) ;
ace - > next = acl - > acelist ;
acl - > acelist = ace ;
acl - > num_aces + = 1 ;
DEBUG ( 10 , ( " add_afs_ace: Added %s entry for %s with rights %d \n " ,
ace - > positive ? " positive " : " negative " ,
ace - > name , ace - > rights ) ) ;
}
/* AFS ACLs in string form are a long string of fields delimited with \n.
*
* First line : Number of positive entries
* Second line : Number of negative entries
* Third and following lines : The entries themselves
*
* An ACE is a line of two fields , delimited by \ t .
*
* First field : Name
* Second field : Rights
*/
2007-10-19 04:40:25 +04:00
static bool parse_afs_acl ( struct afs_acl * acl , const char * acl_str )
2004-05-02 16:13:16 +04:00
{
int nplus , nminus ;
int aces ;
2011-05-04 01:08:27 +04:00
char str [ MAXSIZE ] ;
2004-05-02 16:13:16 +04:00
char * p = str ;
2011-05-04 01:08:27 +04:00
strlcpy ( str , acl_str , MAXSIZE ) ;
2004-05-02 16:13:16 +04:00
if ( sscanf ( p , " %d " , & nplus ) ! = 1 )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
DEBUG ( 10 , ( " Found %d positive entries \n " , nplus ) ) ;
if ( ( p = strchr ( p , ' \n ' ) ) = = NULL )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
p + = 1 ;
if ( sscanf ( p , " %d " , & nminus ) ! = 1 )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
DEBUG ( 10 , ( " Found %d negative entries \n " , nminus ) ) ;
if ( ( p = strchr ( p , ' \n ' ) ) = = NULL )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
p + = 1 ;
for ( aces = nplus + nminus ; aces > 0 ; aces - - )
{
2004-12-17 12:05:41 +03:00
const char * namep ;
fstring name ;
2015-05-03 06:11:02 +03:00
uint32_t rights ;
2004-12-17 12:05:41 +03:00
char * space ;
2004-05-02 16:13:16 +04:00
2004-12-17 12:05:41 +03:00
namep = p ;
2004-05-02 16:13:16 +04:00
if ( ( p = strchr ( p , ' \t ' ) ) = = NULL )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
* p = ' \0 ' ;
p + = 1 ;
if ( sscanf ( p , " %d " , & rights ) ! = 1 )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
if ( ( p = strchr ( p , ' \n ' ) ) = = NULL )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
p + = 1 ;
2004-12-17 12:05:41 +03:00
fstrcpy ( name , namep ) ;
while ( ( space = strchr_m ( name , space_replacement ) ) ! = NULL )
* space = ' ' ;
2004-05-02 16:13:16 +04:00
add_afs_ace ( acl , nplus > 0 , name , rights ) ;
nplus - = 1 ;
}
2011-07-15 17:58:40 +04:00
return true ;
2004-05-02 16:13:16 +04:00
}
2007-10-19 04:40:25 +04:00
static bool unparse_afs_acl ( struct afs_acl * acl , char * acl_str )
2004-05-02 16:13:16 +04:00
{
/* TODO: String length checks!!!! */
int positives = 0 ;
int negatives = 0 ;
fstring line ;
2011-07-15 18:12:46 +04:00
struct afs_ace * ace = acl - > acelist ;
2004-05-02 16:13:16 +04:00
* acl_str = 0 ;
while ( ace ! = NULL ) {
if ( ace - > positive )
positives + + ;
else
negatives + + ;
ace = ace - > next ;
}
fstr_sprintf ( line , " %d \n " , positives ) ;
2012-03-30 04:13:07 +04:00
if ( strlcat ( acl_str , line , MAXSIZE ) > = MAXSIZE ) {
return false ;
}
2004-05-02 16:13:16 +04:00
fstr_sprintf ( line , " %d \n " , negatives ) ;
2012-03-30 04:13:07 +04:00
if ( strlcat ( acl_str , line , MAXSIZE ) > = MAXSIZE ) {
return false ;
}
2004-05-02 16:13:16 +04:00
ace = acl - > acelist ;
while ( ace ! = NULL ) {
fstr_sprintf ( line , " %s \t %d \n " , ace - > name , ace - > rights ) ;
2012-03-30 04:13:07 +04:00
if ( strlcat ( acl_str , line , MAXSIZE ) > = MAXSIZE ) {
return false ;
}
2004-05-02 16:13:16 +04:00
ace = ace - > next ;
}
2011-07-15 17:58:40 +04:00
return true ;
2004-05-02 16:13:16 +04:00
}
2015-05-03 06:11:02 +03:00
static uint32_t afs_to_nt_file_rights ( uint32_t rights )
2004-05-02 16:13:16 +04:00
{
2015-05-03 06:11:02 +03:00
uint32_t result = 0 ;
2004-05-02 16:13:16 +04:00
if ( rights & PRSFS_READ )
result | = FILE_READ_DATA | FILE_READ_EA |
FILE_EXECUTE | FILE_READ_ATTRIBUTES |
READ_CONTROL_ACCESS | SYNCHRONIZE_ACCESS ;
if ( rights & PRSFS_WRITE )
result | = FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES |
FILE_WRITE_EA | FILE_APPEND_DATA ;
if ( rights & PRSFS_LOCK )
result | = WRITE_OWNER_ACCESS ;
if ( rights & PRSFS_DELETE )
result | = DELETE_ACCESS ;
return result ;
}
2015-05-03 06:11:02 +03:00
static void afs_to_nt_dir_rights ( uint32_t afs_rights , uint32_t * nt_rights ,
uint8_t * flag )
2004-05-02 16:13:16 +04:00
{
2004-08-17 14:48:31 +04:00
* nt_rights = 0 ;
* flag = SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_CONTAINER_INHERIT ;
2004-05-02 16:13:16 +04:00
2004-08-17 14:48:31 +04:00
if ( afs_rights & PRSFS_INSERT )
* nt_rights | = FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY ;
2004-05-02 16:13:16 +04:00
2004-08-17 14:48:31 +04:00
if ( afs_rights & PRSFS_LOOKUP )
* nt_rights | = FILE_READ_DATA | FILE_READ_EA |
2004-05-02 16:13:16 +04:00
FILE_EXECUTE | FILE_READ_ATTRIBUTES |
READ_CONTROL_ACCESS | SYNCHRONIZE_ACCESS ;
2004-08-17 14:48:31 +04:00
if ( afs_rights & PRSFS_WRITE )
* nt_rights | = FILE_WRITE_ATTRIBUTES | FILE_WRITE_DATA |
2004-05-02 16:13:16 +04:00
FILE_APPEND_DATA | FILE_WRITE_EA ;
2004-08-17 14:48:31 +04:00
if ( ( afs_rights & ( PRSFS_INSERT | PRSFS_LOOKUP | PRSFS_DELETE ) ) = =
2004-05-02 16:13:16 +04:00
( PRSFS_INSERT | PRSFS_LOOKUP | PRSFS_DELETE ) )
2004-08-17 14:48:31 +04:00
* nt_rights | = FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA |
2004-05-02 16:13:16 +04:00
GENERIC_WRITE_ACCESS ;
2004-08-17 14:48:31 +04:00
if ( afs_rights & PRSFS_DELETE )
* nt_rights | = DELETE_ACCESS ;
2004-05-02 16:13:16 +04:00
2004-08-17 14:48:31 +04:00
if ( afs_rights & PRSFS_ADMINISTER )
* nt_rights | = FILE_DELETE_CHILD | WRITE_DAC_ACCESS |
2004-05-02 16:13:16 +04:00
WRITE_OWNER_ACCESS ;
2004-08-17 14:48:31 +04:00
if ( ( afs_rights & PRSFS_LOOKUP ) = =
( afs_rights & ( PRSFS_LOOKUP | PRSFS_READ ) ) ) {
/* Only lookup right */
* flag = SEC_ACE_FLAG_CONTAINER_INHERIT ;
}
}
# define AFS_FILE_RIGHTS (PRSFS_READ|PRSFS_WRITE|PRSFS_LOCK)
# define AFS_DIR_RIGHTS (PRSFS_INSERT|PRSFS_LOOKUP|PRSFS_DELETE|PRSFS_ADMINISTER)
static void split_afs_acl ( struct afs_acl * acl ,
struct afs_acl * dir_acl ,
struct afs_acl * file_acl )
{
struct afs_ace * ace ;
init_afs_acl ( dir_acl ) ;
init_afs_acl ( file_acl ) ;
for ( ace = acl - > acelist ; ace ! = NULL ; ace = ace - > next ) {
if ( ace - > rights & AFS_FILE_RIGHTS ) {
add_afs_ace ( file_acl , ace - > positive , ace - > name ,
ace - > rights & AFS_FILE_RIGHTS ) ;
}
if ( ace - > rights & AFS_DIR_RIGHTS ) {
add_afs_ace ( dir_acl , ace - > positive , ace - > name ,
ace - > rights & AFS_DIR_RIGHTS ) ;
}
}
}
2007-10-19 04:40:25 +04:00
static bool same_principal ( struct afs_ace * x , struct afs_ace * y )
2004-08-17 14:48:31 +04:00
{
return ( ( x - > positive = = y - > positive ) & &
2010-08-26 17:48:50 +04:00
( dom_sid_compare ( & x - > sid , & y - > sid ) = = 0 ) ) ;
2004-05-02 16:13:16 +04:00
}
2004-08-17 14:48:31 +04:00
static void merge_afs_acls ( struct afs_acl * dir_acl ,
struct afs_acl * file_acl ,
struct afs_acl * target )
{
struct afs_ace * ace ;
init_afs_acl ( target ) ;
for ( ace = dir_acl - > acelist ; ace ! = NULL ; ace = ace - > next ) {
struct afs_ace * file_ace ;
2011-07-15 17:58:40 +04:00
bool found = false ;
2004-08-17 14:48:31 +04:00
for ( file_ace = file_acl - > acelist ;
file_ace ! = NULL ;
file_ace = file_ace - > next ) {
if ( ! same_principal ( ace , file_ace ) )
continue ;
add_afs_ace ( target , ace - > positive , ace - > name ,
ace - > rights | file_ace - > rights ) ;
2011-07-15 17:58:40 +04:00
found = true ;
2004-08-17 14:48:31 +04:00
break ;
}
if ( ! found )
add_afs_ace ( target , ace - > positive , ace - > name ,
ace - > rights ) ;
}
for ( ace = file_acl - > acelist ; ace ! = NULL ; ace = ace - > next ) {
struct afs_ace * dir_ace ;
2011-07-15 17:58:40 +04:00
bool already_seen = false ;
2004-08-17 14:48:31 +04:00
for ( dir_ace = dir_acl - > acelist ;
dir_ace ! = NULL ;
dir_ace = dir_ace - > next ) {
if ( ! same_principal ( ace , dir_ace ) )
continue ;
2011-07-15 17:58:40 +04:00
already_seen = true ;
2004-08-17 14:48:31 +04:00
break ;
}
if ( ! already_seen )
add_afs_ace ( target , ace - > positive , ace - > name ,
ace - > rights ) ;
}
}
# define PERMS_READ 0x001200a9
# define PERMS_CHANGE 0x001301bf
# define PERMS_FULL 0x001f01ff
static struct static_dir_ace_mapping {
2015-05-03 06:11:02 +03:00
uint8_t type ;
uint8_t flags ;
uint32_t mask ;
uint32_t afs_rights ;
2004-08-17 14:48:31 +04:00
} ace_mappings [ ] = {
/* Full control */
{ 0 , SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT ,
PERMS_FULL , 127 /* rlidwka */ } ,
/* Change (write) */
{ 0 , SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT ,
PERMS_CHANGE , 63 /* rlidwk */ } ,
/* Read (including list folder content) */
{ 0 , SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT ,
PERMS_READ , 9 /* rl */ } ,
/* Read without list folder content -- same as "l" */
{ 0 , SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT ,
0x00120089 , 8 /* l */ } ,
2004-11-18 11:16:59 +03:00
/* some stupid workaround for preventing fallbacks */
{ 0 , 0x3 , 0x0012019F , 9 /* rl */ } ,
{ 0 , 0x13 , PERMS_FULL , 127 /* full */ } ,
/* read, delete and execute access plus synchronize */
{ 0 , 0x3 , 0x001300A9 , 9 /* should be rdl, set to rl */ } ,
/* classical read list */
{ 0 , 0x13 , 0x001200A9 , 9 /* rl */ } ,
/* almost full control, no delete */
{ 0 , 0x13 , PERMS_CHANGE , 63 /* rwidlk */ } ,
2004-08-17 14:48:31 +04:00
/* List folder */
{ 0 , SEC_ACE_FLAG_CONTAINER_INHERIT ,
PERMS_READ , 8 /* l */ } ,
/* FULL without inheritance -- in all cases here we also get
the corresponding INHERIT_ONLY ACE in the same ACL */
{ 0 , 0 , PERMS_FULL , 127 /* rlidwka */ } ,
/* FULL inherit only -- counterpart to previous one */
{ 0 , SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ,
2010-06-03 01:48:15 +04:00
PERMS_FULL | SEC_GENERIC_WRITE , 127 /* rlidwka */ } ,
2004-08-17 14:48:31 +04:00
/* CHANGE without inheritance -- in all cases here we also get
the corresponding INHERIT_ONLY ACE in the same ACL */
{ 0 , 0 , PERMS_CHANGE , 63 /* rlidwk */ } ,
/* CHANGE inherit only -- counterpart to previous one */
{ 0 , SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ,
2010-06-03 01:48:15 +04:00
PERMS_CHANGE | SEC_GENERIC_WRITE , 63 /* rlidwk */ } ,
2004-08-17 14:48:31 +04:00
/* End marker, hopefully there's no afs right 9999 :-) */
{ 0 , 0 , 0 , 9999 }
} ;
2015-05-03 06:11:02 +03:00
static uint32_t nt_to_afs_dir_rights ( const char * filename , const struct security_ace * ace )
2004-05-02 16:13:16 +04:00
{
2015-05-03 06:11:02 +03:00
uint32_t result = 0 ;
uint32_t rights = ace - > access_mask ;
uint8_t flags = ace - > flags ;
2004-08-17 14:48:31 +04:00
struct static_dir_ace_mapping * m ;
for ( m = & ace_mappings [ 0 ] ; m - > afs_rights ! = 9999 ; m + + ) {
if ( ( ace - > type = = m - > type ) & &
( ace - > flags = = m - > flags ) & &
2007-08-09 00:06:17 +04:00
( ace - > access_mask = = m - > mask ) )
2004-08-17 14:48:31 +04:00
return m - > afs_rights ;
}
2004-11-18 11:16:59 +03:00
DEBUG ( 1 , ( " AFSACL FALLBACK: 0x%X 0x%X 0x%X %s %X \n " ,
2007-08-09 00:06:17 +04:00
ace - > type , ace - > flags , ace - > access_mask , filename , rights ) ) ;
2004-05-02 16:13:16 +04:00
if ( rights & ( GENERIC_ALL_ACCESS | WRITE_DAC_ACCESS ) ) {
result | = PRSFS_READ | PRSFS_WRITE | PRSFS_INSERT |
PRSFS_LOOKUP | PRSFS_DELETE | PRSFS_LOCK |
PRSFS_ADMINISTER ;
}
if ( rights & ( GENERIC_READ_ACCESS | FILE_READ_DATA ) ) {
2004-08-17 14:48:31 +04:00
result | = PRSFS_LOOKUP ;
if ( flags & SEC_ACE_FLAG_OBJECT_INHERIT ) {
result | = PRSFS_READ ;
}
}
if ( rights & ( GENERIC_WRITE_ACCESS | FILE_WRITE_DATA ) ) {
result | = PRSFS_INSERT | PRSFS_DELETE ;
if ( flags & SEC_ACE_FLAG_OBJECT_INHERIT ) {
result | = PRSFS_WRITE | PRSFS_LOCK ;
}
}
return result ;
}
2015-05-03 06:11:02 +03:00
static uint32_t nt_to_afs_file_rights ( const char * filename , const struct security_ace * ace )
2004-08-17 14:48:31 +04:00
{
2015-05-03 06:11:02 +03:00
uint32_t result = 0 ;
uint32_t rights = ace - > access_mask ;
2004-08-17 14:48:31 +04:00
if ( rights & ( GENERIC_READ_ACCESS | FILE_READ_DATA ) ) {
result | = PRSFS_READ ;
2004-05-02 16:13:16 +04:00
}
if ( rights & ( GENERIC_WRITE_ACCESS | FILE_WRITE_DATA ) ) {
2004-08-17 14:48:31 +04:00
result | = PRSFS_WRITE | PRSFS_LOCK ;
2004-05-02 16:13:16 +04:00
}
return result ;
}
2007-12-04 11:45:14 +03:00
static size_t afs_to_nt_acl_common ( struct afs_acl * afs_acl ,
SMB_STRUCT_STAT * psbuf ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2007-12-04 11:45:14 +03:00
struct security_descriptor * * ppdesc )
2004-05-02 16:13:16 +04:00
{
2010-05-18 05:25:38 +04:00
struct security_ace * nt_ace_list ;
2010-05-21 05:25:01 +04:00
struct dom_sid owner_sid , group_sid ;
2010-05-18 05:30:40 +04:00
struct security_acl * psa = NULL ;
2004-05-02 16:13:16 +04:00
int good_aces ;
size_t sd_size ;
struct afs_ace * afs_ace ;
2009-05-14 17:34:42 +04:00
uid_to_sid ( & owner_sid , psbuf - > st_ex_uid ) ;
gid_to_sid ( & group_sid , psbuf - > st_ex_gid ) ;
2004-05-02 16:13:16 +04:00
2007-05-05 02:01:26 +04:00
if ( afs_acl - > num_aces ) {
2011-06-07 05:30:12 +04:00
nt_ace_list = talloc_array ( mem_ctx , struct security_ace , afs_acl - > num_aces ) ;
2004-05-02 16:13:16 +04:00
2007-04-30 06:39:34 +04:00
if ( nt_ace_list = = NULL )
return 0 ;
} else {
nt_ace_list = NULL ;
}
2004-05-02 16:13:16 +04:00
afs_ace = afs_acl - > acelist ;
good_aces = 0 ;
while ( afs_ace ! = NULL ) {
2008-10-09 20:49:03 +04:00
uint32_t nt_rights ;
2015-05-03 06:11:02 +03:00
uint8_t flag = SEC_ACE_FLAG_OBJECT_INHERIT |
2004-08-17 14:48:31 +04:00
SEC_ACE_FLAG_CONTAINER_INHERIT ;
2004-05-02 16:13:16 +04:00
if ( afs_ace - > type = = SID_NAME_UNKNOWN ) {
DEBUG ( 10 , ( " Ignoring unknown name %s \n " ,
afs_ace - > name ) ) ;
afs_ace = afs_ace - > next ;
continue ;
}
2009-05-14 17:34:42 +04:00
if ( S_ISDIR ( psbuf - > st_ex_mode ) )
2004-08-17 14:48:31 +04:00
afs_to_nt_dir_rights ( afs_ace - > rights , & nt_rights ,
& flag ) ;
2004-05-02 16:13:16 +04:00
else
nt_rights = afs_to_nt_file_rights ( afs_ace - > rights ) ;
init_sec_ace ( & nt_ace_list [ good_aces + + ] , & ( afs_ace - > sid ) ,
2008-10-09 20:49:03 +04:00
SEC_ACE_TYPE_ACCESS_ALLOWED , nt_rights , flag ) ;
2004-05-02 16:13:16 +04:00
afs_ace = afs_ace - > next ;
}
psa = make_sec_acl ( mem_ctx , NT4_ACL_REVISION ,
good_aces , nt_ace_list ) ;
if ( psa = = NULL )
return 0 ;
2010-05-18 14:52:18 +04:00
* ppdesc = make_sec_desc ( mem_ctx , SD_REVISION ,
2004-05-02 16:13:16 +04:00
SEC_DESC_SELF_RELATIVE ,
2010-06-03 01:22:12 +04:00
( security_info & SECINFO_OWNER )
2004-05-02 16:13:16 +04:00
? & owner_sid : NULL ,
2010-06-03 01:25:18 +04:00
( security_info & SECINFO_GROUP )
2004-05-02 16:13:16 +04:00
? & group_sid : NULL ,
NULL , psa , & sd_size ) ;
return sd_size ;
}
2007-12-04 11:45:14 +03:00
static size_t afs_to_nt_acl ( struct afs_acl * afs_acl ,
struct connection_struct * conn ,
2009-07-11 05:11:32 +04:00
struct smb_filename * smb_fname ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2007-12-04 11:45:14 +03:00
struct security_descriptor * * ppdesc )
{
2009-10-17 04:20:40 +04:00
int ret ;
2016-03-15 21:46:58 +03:00
/*
* We can directly use SMB_VFS_STAT here , as if this was a
* POSIX call on a symlink , we ' ve already refused it .
* For a Windows acl mapped call on a symlink , we want to follow
* it .
*/
2007-12-04 11:45:14 +03:00
/* Get the stat struct for the owner info. */
2016-03-15 21:46:58 +03:00
ret = SMB_VFS_STAT ( conn , smb_fname ) ;
2009-10-17 04:20:40 +04:00
if ( ret = = - 1 ) {
2007-12-04 11:45:14 +03:00
return 0 ;
}
2009-07-11 05:11:32 +04:00
return afs_to_nt_acl_common ( afs_acl , & smb_fname - > st , security_info ,
2012-10-10 04:50:27 +04:00
mem_ctx , ppdesc ) ;
2007-12-04 11:45:14 +03:00
}
static size_t afs_fto_nt_acl ( struct afs_acl * afs_acl ,
struct files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2007-12-04 11:45:14 +03:00
struct security_descriptor * * ppdesc )
{
SMB_STRUCT_STAT sbuf ;
2011-02-08 07:46:36 +03:00
if ( fsp - > fh - > fd = = - 1 ) {
2007-12-04 11:45:14 +03:00
/* Get the stat struct for the owner info. */
return afs_to_nt_acl ( afs_acl , fsp - > conn , fsp - > fsp_name ,
2012-10-10 04:50:27 +04:00
security_info , mem_ctx , ppdesc ) ;
2007-12-04 11:45:14 +03:00
}
2008-01-07 15:21:26 +03:00
if ( SMB_VFS_FSTAT ( fsp , & sbuf ) ! = 0 ) {
2007-12-04 11:45:14 +03:00
return 0 ;
}
2013-02-09 05:08:28 +04:00
return afs_to_nt_acl_common ( afs_acl , & sbuf , security_info ,
mem_ctx , ppdesc ) ;
2007-12-04 11:45:14 +03:00
}
2010-05-21 05:25:01 +04:00
static bool mappable_sid ( const struct dom_sid * sid )
2004-08-17 14:48:31 +04:00
{
2010-05-21 05:25:01 +04:00
struct dom_sid domain_sid ;
2004-08-17 14:48:31 +04:00
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( sid , & global_sid_Builtin_Administrators ) = = 0 )
2011-07-15 17:58:40 +04:00
return true ;
2004-08-17 14:48:31 +04:00
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( sid , & global_sid_World ) = = 0 )
2011-07-15 17:58:40 +04:00
return true ;
2004-08-17 14:48:31 +04:00
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( sid , & global_sid_Authenticated_Users ) = = 0 )
2011-07-15 17:58:40 +04:00
return true ;
2004-08-17 14:48:31 +04:00
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( sid , & global_sid_Builtin_Backup_Operators ) = = 0 )
2011-07-15 17:58:40 +04:00
return true ;
2004-08-17 14:48:31 +04:00
string_to_sid ( & domain_sid , " S-1-5-21 " ) ;
if ( sid_compare_domain ( sid , & domain_sid ) = = 0 )
2011-07-15 17:58:40 +04:00
return true ;
2004-08-17 14:48:31 +04:00
2011-07-15 17:58:40 +04:00
return false ;
2004-08-17 14:48:31 +04:00
}
2007-10-19 04:40:25 +04:00
static bool nt_to_afs_acl ( const char * filename ,
2015-05-03 06:11:02 +03:00
uint32_t security_info_sent ,
2008-10-08 04:50:01 +04:00
const struct security_descriptor * psd ,
2015-05-03 06:11:02 +03:00
uint32_t ( * nt_to_afs_rights ) ( const char * filename ,
2010-05-18 05:25:38 +04:00
const struct security_ace * ace ) ,
2004-05-02 16:13:16 +04:00
struct afs_acl * afs_acl )
{
2010-05-18 05:30:40 +04:00
const struct security_acl * dacl ;
2004-05-02 16:13:16 +04:00
int i ;
/* Currently we *only* look at the dacl */
2010-06-03 01:35:44 +04:00
if ( ( ( security_info_sent & SECINFO_DACL ) = = 0 ) | |
2004-05-02 16:13:16 +04:00
( psd - > dacl = = NULL ) )
2011-07-15 17:58:40 +04:00
return true ;
2004-05-02 16:13:16 +04:00
if ( ! init_afs_acl ( afs_acl ) )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
dacl = psd - > dacl ;
for ( i = 0 ; i < dacl - > num_aces ; i + + ) {
2010-05-18 05:25:38 +04:00
const struct security_ace * ace = & ( dacl - > aces [ i ] ) ;
2006-06-20 15:06:09 +04:00
const char * dom_name , * name ;
2006-09-08 18:28:06 +04:00
enum lsa_SidType name_type ;
2004-12-17 12:05:41 +03:00
char * p ;
2004-05-02 16:13:16 +04:00
if ( ace - > type ! = SEC_ACE_TYPE_ACCESS_ALLOWED ) {
/* First cut: Only positive ACEs */
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2004-08-17 14:48:31 +04:00
if ( ! mappable_sid ( & ace - > trustee ) ) {
DEBUG ( 10 , ( " Ignoring unmappable SID %s \n " ,
2007-12-15 23:11:36 +03:00
sid_string_dbg ( & ace - > trustee ) ) ) ;
2004-08-17 14:48:31 +04:00
continue ;
}
2010-08-26 17:48:50 +04:00
if ( dom_sid_compare ( & ace - > trustee ,
2004-05-02 16:13:16 +04:00
& global_sid_Builtin_Administrators ) = = 0 ) {
2006-06-20 15:06:09 +04:00
name = " system:administrators " ;
2004-05-02 16:13:16 +04:00
2010-08-26 17:48:50 +04:00
} else if ( dom_sid_compare ( & ace - > trustee ,
2004-05-02 16:13:16 +04:00
& global_sid_World ) = = 0 ) {
2006-06-20 15:06:09 +04:00
name = " system:anyuser " ;
2004-05-02 16:13:16 +04:00
2010-08-26 17:48:50 +04:00
} else if ( dom_sid_compare ( & ace - > trustee ,
2004-05-02 16:13:16 +04:00
& global_sid_Authenticated_Users ) = = 0 ) {
2006-06-20 15:06:09 +04:00
name = " system:authuser " ;
2004-05-02 16:13:16 +04:00
2010-08-26 17:48:50 +04:00
} else if ( dom_sid_compare ( & ace - > trustee ,
2004-05-02 16:13:16 +04:00
& global_sid_Builtin_Backup_Operators )
= = 0 ) {
2006-06-20 15:06:09 +04:00
name = " system:backup " ;
2004-05-02 16:13:16 +04:00
} else {
2007-08-30 23:48:31 +04:00
if ( ! lookup_sid ( talloc_tos ( ) , & ace - > trustee ,
2006-06-20 15:06:09 +04:00
& dom_name , & name , & name_type ) ) {
2004-08-17 14:48:31 +04:00
DEBUG ( 1 , ( " AFSACL: Could not lookup SID %s on file %s \n " ,
2007-12-15 23:11:36 +03:00
sid_string_dbg ( & ace - > trustee ) ,
filename ) ) ;
2004-08-17 14:48:31 +04:00
continue ;
2004-05-02 16:13:16 +04:00
}
if ( ( name_type = = SID_NAME_USER ) | |
2004-08-17 14:48:31 +04:00
( name_type = = SID_NAME_DOM_GRP ) | |
2006-06-20 15:06:09 +04:00
( name_type = = SID_NAME_ALIAS ) ) {
char * tmp ;
2007-08-30 23:48:31 +04:00
tmp = talloc_asprintf ( talloc_tos ( ) , " %s%s%s " ,
2006-06-20 15:06:09 +04:00
dom_name , lp_winbind_separator ( ) ,
name ) ;
if ( tmp = = NULL ) {
2011-07-15 17:58:40 +04:00
return false ;
2006-06-20 15:06:09 +04:00
}
2012-08-09 04:01:00 +04:00
if ( ! strlower_m ( tmp ) ) {
return false ;
}
2006-06-20 15:06:09 +04:00
name = tmp ;
2004-05-02 16:13:16 +04:00
}
2005-11-08 23:13:26 +03:00
if ( sidpts ) {
2018-12-08 17:37:21 +03:00
struct dom_sid_buf buf ;
2005-11-08 23:13:26 +03:00
/* Expect all users/groups in pts as SIDs */
2006-06-20 15:06:09 +04:00
name = talloc_strdup (
2007-08-30 23:48:31 +04:00
talloc_tos ( ) ,
2018-12-08 17:37:21 +03:00
dom_sid_str_buf ( & ace - > trustee , & buf ) ) ;
2006-06-20 15:06:09 +04:00
if ( name = = NULL ) {
2011-07-15 17:58:40 +04:00
return false ;
2006-06-20 15:06:09 +04:00
}
2005-11-08 23:13:26 +03:00
}
2004-05-02 16:13:16 +04:00
}
2004-12-17 12:05:41 +03:00
while ( ( p = strchr_m ( name , ' ' ) ) ! = NULL )
* p = space_replacement ;
2011-07-15 17:58:40 +04:00
add_afs_ace ( afs_acl , true , name ,
2004-08-17 14:48:31 +04:00
nt_to_afs_rights ( filename , ace ) ) ;
2004-05-02 16:13:16 +04:00
}
2011-07-15 17:58:40 +04:00
return true ;
2004-05-02 16:13:16 +04:00
}
2011-07-15 18:16:11 +04:00
static bool afs_get_afs_acl ( const char * filename , struct afs_acl * acl )
2004-05-02 16:13:16 +04:00
{
struct afs_iob iob ;
int ret ;
char space [ MAXSIZE ] ;
DEBUG ( 5 , ( " afs_get_afs_acl: %s \n " , filename ) ) ;
iob . in_size = 0 ;
iob . out_size = MAXSIZE ;
iob . in = iob . out = space ;
ret = afs_syscall ( AFSCALL_PIOCTL , filename , VIOCGETAL ,
( char * ) & iob , 0 ) ;
if ( ret ) {
DEBUG ( 1 , ( " got error from PIOCTL: %d \n " , ret ) ) ;
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
if ( ! init_afs_acl ( acl ) )
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
if ( ! parse_afs_acl ( acl , space ) ) {
DEBUG ( 1 , ( " Could not parse AFS acl \n " ) ) ;
free_afs_acl ( acl ) ;
2011-07-15 17:58:40 +04:00
return false ;
2004-05-02 16:13:16 +04:00
}
2011-07-15 17:58:40 +04:00
return true ;
2004-05-02 16:13:16 +04:00
}
/* For setting an AFS ACL we have to take care of the ACEs we could
* not properly map to SIDs . Merge all of them into the new ACL . */
static void merge_unknown_aces ( struct afs_acl * src , struct afs_acl * dst )
{
struct afs_ace * ace ;
for ( ace = src - > acelist ; ace ! = NULL ; ace = ace - > next )
{
struct afs_ace * copy ;
if ( ace - > type ! = SID_NAME_UNKNOWN ) {
DEBUG ( 10 , ( " Not merging known ACE for %s \n " ,
ace - > name ) ) ;
continue ;
}
DEBUG ( 10 , ( " Merging unknown ACE for %s \n " , ace - > name ) ) ;
copy = clone_afs_ace ( dst - > ctx , ace ) ;
if ( copy = = NULL ) {
DEBUG ( 0 , ( " Could not clone ACE for %s \n " , ace - > name ) ) ;
continue ;
}
copy - > next = dst - > acelist ;
dst - > acelist = copy ;
dst - > num_aces + = 1 ;
}
}
2007-06-27 02:49:10 +04:00
static NTSTATUS afs_set_nt_acl ( vfs_handle_struct * handle , files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info_sent ,
2008-10-08 04:50:01 +04:00
const struct security_descriptor * psd )
2004-05-02 16:13:16 +04:00
{
struct afs_acl old_afs_acl , new_afs_acl ;
2004-08-17 14:48:31 +04:00
struct afs_acl dir_acl , file_acl ;
2011-05-04 01:08:27 +04:00
char acl_string [ MAXSIZE ] ;
2004-05-02 16:13:16 +04:00
struct afs_iob iob ;
2004-08-17 14:48:31 +04:00
int ret = - 1 ;
2007-11-17 04:07:11 +03:00
char * name = NULL ;
2004-08-17 14:48:31 +04:00
const char * fileacls ;
fileacls = lp_parm_const_string ( SNUM ( handle - > conn ) , " afsacl " , " fileacls " ,
" yes " ) ;
2011-07-15 17:58:40 +04:00
sidpts = lp_parm_bool ( SNUM ( handle - > conn ) , " afsacl " , " sidpts " , false ) ;
2005-11-08 23:13:26 +03:00
2004-08-17 14:48:31 +04:00
ZERO_STRUCT ( old_afs_acl ) ;
ZERO_STRUCT ( new_afs_acl ) ;
ZERO_STRUCT ( dir_acl ) ;
ZERO_STRUCT ( file_acl ) ;
2009-07-11 05:11:32 +04:00
name = talloc_strdup ( talloc_tos ( ) , fsp - > fsp_name - > base_name ) ;
2007-11-17 04:07:11 +03:00
if ( ! name ) {
return NT_STATUS_NO_MEMORY ;
}
2004-05-02 16:13:16 +04:00
if ( ! fsp - > is_directory ) {
2005-07-12 13:18:50 +04:00
/* We need to get the name of the directory containing the
* file , this is where the AFS acls live */
2004-08-17 14:48:31 +04:00
char * p = strrchr ( name , ' / ' ) ;
2005-07-12 13:18:50 +04:00
if ( p ! = NULL ) {
* p = ' \0 ' ;
} else {
2007-11-17 04:07:11 +03:00
name = talloc_strdup ( talloc_tos ( ) , " . " ) ;
if ( ! name ) {
return NT_STATUS_NO_MEMORY ;
}
2004-08-17 14:48:31 +04:00
}
2004-05-02 16:13:16 +04:00
}
2004-08-17 14:48:31 +04:00
if ( ! afs_get_afs_acl ( name , & old_afs_acl ) ) {
2009-07-11 05:11:32 +04:00
DEBUG ( 3 , ( " Could not get old ACL of %s \n " , fsp_str_dbg ( fsp ) ) ) ;
2004-08-17 14:48:31 +04:00
goto done ;
2004-05-02 16:13:16 +04:00
}
2004-08-17 14:48:31 +04:00
split_afs_acl ( & old_afs_acl , & dir_acl , & file_acl ) ;
if ( fsp - > is_directory ) {
if ( ! strequal ( fileacls , " yes " ) ) {
/* Throw away file acls, we depend on the
* inheritance ACEs that also give us file
* permissions */
free_afs_acl ( & file_acl ) ;
}
free_afs_acl ( & dir_acl ) ;
2009-07-11 05:11:32 +04:00
if ( ! nt_to_afs_acl ( fsp - > fsp_name - > base_name ,
security_info_sent , psd ,
2004-08-17 14:48:31 +04:00
nt_to_afs_dir_rights , & dir_acl ) )
goto done ;
} else {
if ( strequal ( fileacls , " no " ) ) {
ret = - 1 ;
goto done ;
}
if ( strequal ( fileacls , " ignore " ) ) {
ret = 0 ;
goto done ;
}
free_afs_acl ( & file_acl ) ;
2009-07-11 05:11:32 +04:00
if ( ! nt_to_afs_acl ( fsp - > fsp_name - > base_name ,
security_info_sent , psd ,
2004-08-17 14:48:31 +04:00
nt_to_afs_file_rights , & file_acl ) )
goto done ;
2004-05-02 16:13:16 +04:00
}
2004-08-17 14:48:31 +04:00
merge_afs_acls ( & dir_acl , & file_acl , & new_afs_acl ) ;
2004-05-02 16:13:16 +04:00
merge_unknown_aces ( & old_afs_acl , & new_afs_acl ) ;
unparse_afs_acl ( & new_afs_acl , acl_string ) ;
iob . in = acl_string ;
iob . in_size = 1 + strlen ( iob . in ) ;
iob . out = NULL ;
iob . out_size = 0 ;
2004-08-17 14:48:31 +04:00
DEBUG ( 10 , ( " trying to set acl '%s' on file %s \n " , iob . in , name ) ) ;
2004-05-02 16:13:16 +04:00
2004-08-17 14:48:31 +04:00
ret = afs_syscall ( AFSCALL_PIOCTL , name , VIOCSETAL , ( char * ) & iob , 0 ) ;
2004-05-02 16:13:16 +04:00
if ( ret ! = 0 ) {
DEBUG ( 10 , ( " VIOCSETAL returned %d \n " , ret ) ) ;
}
2004-08-17 14:48:31 +04:00
done :
free_afs_acl ( & dir_acl ) ;
free_afs_acl ( & file_acl ) ;
free_afs_acl ( & old_afs_acl ) ;
free_afs_acl ( & new_afs_acl ) ;
2007-06-27 02:49:10 +04:00
return ( ret = = 0 ) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED ;
2004-05-02 16:13:16 +04:00
}
2007-10-13 23:06:49 +04:00
static NTSTATUS afsacl_fget_nt_acl ( struct vfs_handle_struct * handle ,
struct files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info ,
2012-10-10 04:50:27 +04:00
TALLOC_CTX * mem_ctx ,
2007-10-13 23:06:49 +04:00
struct security_descriptor * * ppdesc )
2004-05-02 16:13:16 +04:00
{
2007-12-04 11:45:14 +03:00
struct afs_acl acl ;
size_t sd_size ;
2009-07-11 05:11:32 +04:00
DEBUG ( 5 , ( " afsacl_fget_nt_acl: %s \n " , fsp_str_dbg ( fsp ) ) ) ;
2007-12-04 11:45:14 +03:00
2011-07-15 17:58:40 +04:00
sidpts = lp_parm_bool ( SNUM ( fsp - > conn ) , " afsacl " , " sidpts " , false ) ;
2007-12-04 11:45:14 +03:00
2009-07-11 05:11:32 +04:00
if ( ! afs_get_afs_acl ( fsp - > fsp_name - > base_name , & acl ) ) {
2007-12-04 11:45:14 +03:00
return NT_STATUS_ACCESS_DENIED ;
}
2012-10-10 04:50:27 +04:00
sd_size = afs_fto_nt_acl ( & acl , fsp , security_info , mem_ctx , ppdesc ) ;
2007-12-04 11:45:14 +03:00
free_afs_acl ( & acl ) ;
return ( sd_size ! = 0 ) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED ;
2004-05-02 16:13:16 +04:00
}
2007-12-04 11:45:14 +03:00
2007-10-13 23:06:49 +04:00
static NTSTATUS afsacl_get_nt_acl ( struct vfs_handle_struct * handle ,
2016-03-18 02:44:50 +03:00
const struct smb_filename * smb_fname ,
uint32_t security_info ,
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * ppdesc )
2004-05-02 16:13:16 +04:00
{
2007-12-04 11:45:14 +03:00
struct afs_acl acl ;
size_t sd_size ;
2016-03-18 02:44:50 +03:00
DEBUG ( 5 , ( " afsacl_get_nt_acl: %s \n " , smb_fname - > base_name ) ) ;
2007-12-04 11:45:14 +03:00
2011-07-15 17:58:40 +04:00
sidpts = lp_parm_bool ( SNUM ( handle - > conn ) , " afsacl " , " sidpts " , false ) ;
2007-12-04 11:45:14 +03:00
2016-03-18 02:44:50 +03:00
if ( ! afs_get_afs_acl ( smb_fname - > base_name , & acl ) ) {
2007-12-04 11:45:14 +03:00
return NT_STATUS_ACCESS_DENIED ;
}
2009-07-11 05:11:32 +04:00
sd_size = afs_to_nt_acl ( & acl , handle - > conn , smb_fname , security_info ,
2012-10-10 04:50:27 +04:00
mem_ctx , ppdesc ) ;
2007-12-04 11:45:14 +03:00
free_afs_acl ( & acl ) ;
return ( sd_size ! = 0 ) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED ;
2004-05-02 16:13:16 +04:00
}
2014-05-25 02:35:09 +04:00
static NTSTATUS afsacl_fset_nt_acl ( vfs_handle_struct * handle ,
2004-05-02 16:13:16 +04:00
files_struct * fsp ,
2015-05-03 06:11:02 +03:00
uint32_t security_info_sent ,
2010-05-18 12:29:34 +04:00
const struct security_descriptor * psd )
2004-05-02 16:13:16 +04:00
{
2004-08-17 14:48:31 +04:00
return afs_set_nt_acl ( handle , fsp , security_info_sent , psd ) ;
2004-05-02 16:13:16 +04:00
}
2004-12-17 12:05:41 +03:00
static int afsacl_connect ( vfs_handle_struct * handle ,
const char * service ,
const char * user )
{
2009-12-01 02:53:04 +03:00
const char * spc ;
int ret = SMB_VFS_NEXT_CONNECT ( handle , service , user ) ;
if ( ret < 0 ) {
return ret ;
}
2004-12-17 12:05:41 +03:00
spc = lp_parm_const_string ( SNUM ( handle - > conn ) , " afsacl " , " space " , " % " ) ;
if ( spc ! = NULL )
space_replacement = spc [ 0 ] ;
2009-12-01 02:53:04 +03:00
return 0 ;
2004-12-17 12:05:41 +03:00
}
2012-10-10 09:45:44 +04:00
/* We don't have a linear form of the AFS ACL yet */
2017-05-24 03:35:59 +03:00
static int afsacl_sys_acl_blob_get_file ( vfs_handle_struct * handle ,
const struct smb_filename * smb_fname ,
TALLOC_CTX * mem_ctx ,
char * * blob_description ,
DATA_BLOB * blob )
2012-10-10 09:45:44 +04:00
{
errno = ENOSYS ;
return - 1 ;
}
/* We don't have a linear form of the AFS ACL yet */
static int afsacl_sys_acl_blob_get_fd ( vfs_handle_struct * handle , files_struct * fsp , TALLOC_CTX * mem_ctx , char * * blob_description , DATA_BLOB * blob )
{
errno = ENOSYS ;
return - 1 ;
}
2009-07-24 04:28:58 +04:00
static struct vfs_fn_pointers vfs_afsacl_fns = {
. connect_fn = afsacl_connect ,
2011-12-04 08:45:04 +04:00
. fget_nt_acl_fn = afsacl_fget_nt_acl ,
. get_nt_acl_fn = afsacl_get_nt_acl ,
2012-10-10 09:45:44 +04:00
. fset_nt_acl_fn = afsacl_fset_nt_acl ,
. sys_acl_blob_get_file_fn = afsacl_sys_acl_blob_get_file ,
. sys_acl_blob_get_fd_fn = afsacl_sys_acl_blob_get_fd
2004-05-02 16:13:16 +04:00
} ;
2017-12-16 01:32:12 +03:00
static_decl_vfs ;
2017-04-20 22:24:43 +03:00
NTSTATUS vfs_afsacl_init ( TALLOC_CTX * ctx )
2004-05-02 16:13:16 +04:00
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " afsacl " ,
2009-07-24 04:28:58 +04:00
& vfs_afsacl_fns ) ;
2004-05-02 16:13:16 +04:00
}