2006-02-04 01:19:41 +03:00
/*
* Unix SMB / Netbios implementation .
* SEC_DESC handling functions
* Copyright ( C ) Jeremy R . Allison 1995 - 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
2006-02-04 01:19:41 +03:00
* ( at your option ) any later version .
*
* 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 .
*
* 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/>.
2006-02-04 01:19:41 +03:00
*/
# include "includes.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2010-05-28 04:19:32 +04:00
# include "../librpc/gen_ndr/ndr_security.h"
2010-08-18 20:59:23 +04:00
# include "dbwrap.h"
2006-02-04 01:19:41 +03:00
/*******************************************************************
Create the share security tdb .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-03-28 01:10:57 +03:00
static struct db_context * share_db ; /* used for share security descriptors */
2006-02-04 01:19:41 +03:00
# define SHARE_DATABASE_VERSION_V1 1
# define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
2010-03-23 01:57:31 +03:00
# define SHARE_DATABASE_VERSION_V3 3 /* canonicalized sharenames as lower case */
2006-02-04 01:19:41 +03:00
2010-03-23 01:57:31 +03:00
# define SHARE_SECURITY_DB_KEY_PREFIX_STR "SECDESC / "
2006-02-04 01:19:41 +03:00
/* Map generic permissions to file object specific permissions */
2008-09-08 18:23:36 +04:00
extern const struct generic_mapping file_generic_mapping ;
2006-02-04 01:19:41 +03:00
2008-03-28 01:10:57 +03:00
static int delete_fn ( struct db_record * rec , void * priv )
{
rec - > delete_rec ( rec ) ;
return 0 ;
}
2006-02-04 01:19:41 +03:00
2010-03-23 01:57:31 +03:00
/*****************************************************
Looking for keys of the form : SHARE_SECURITY_DB_KEY_PREFIX_STR + " non lower case str " .
If we find one re - write it into a canonical case form .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int upgrade_v2_to_v3 ( struct db_record * rec , void * priv )
{
size_t prefix_len = strlen ( SHARE_SECURITY_DB_KEY_PREFIX_STR ) ;
const char * servicename = NULL ;
char * c_servicename = NULL ;
char * newkey = NULL ;
bool * p_upgrade_ok = ( bool * ) priv ;
NTSTATUS status ;
/* Is there space for a one character sharename ? */
if ( rec - > key . dsize < = prefix_len + 2 ) {
return 0 ;
}
/* Does it start with the share key prefix ? */
if ( memcmp ( rec - > key . dptr , SHARE_SECURITY_DB_KEY_PREFIX_STR ,
prefix_len ) ! = 0 ) {
return 0 ;
}
/* Is it a null terminated string as a key ? */
if ( rec - > key . dptr [ rec - > key . dsize - 1 ] ! = ' \0 ' ) {
return 0 ;
}
/* Bytes after the prefix are the sharename string. */
servicename = ( char * ) & rec - > key . dptr [ prefix_len ] ;
c_servicename = canonicalize_servicename ( talloc_tos ( ) , servicename ) ;
if ( ! c_servicename ) {
smb_panic ( " out of memory upgrading share security db from v2 -> v3 " ) ;
}
if ( strcmp ( servicename , c_servicename ) = = 0 ) {
/* Old and new names match. No canonicalization needed. */
TALLOC_FREE ( c_servicename ) ;
return 0 ;
}
/* Oops. Need to canonicalize name, delete old then store new. */
status = rec - > delete_rec ( rec ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " upgrade_v2_to_v3: Failed to delete secdesc for "
" %s: %s \n " , rec - > key . dptr , nt_errstr ( status ) ) ) ;
TALLOC_FREE ( c_servicename ) ;
* p_upgrade_ok = false ;
return - 1 ;
} else {
DEBUG ( 10 , ( " upgrade_v2_to_v3: deleted secdesc for "
" %s \n " , rec - > key . dptr ) ) ;
}
if ( ! ( newkey = talloc_asprintf ( talloc_tos ( ) ,
SHARE_SECURITY_DB_KEY_PREFIX_STR " %s " ,
c_servicename ) ) ) {
smb_panic ( " out of memory upgrading share security db from v2 -> v3 " ) ;
}
status = dbwrap_store ( share_db ,
string_term_tdb_data ( newkey ) ,
rec - > value ,
TDB_REPLACE ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " upgrade_v2_to_v3: Failed to store secdesc for "
" %s: %s \n " , c_servicename , nt_errstr ( status ) ) ) ;
TALLOC_FREE ( c_servicename ) ;
TALLOC_FREE ( newkey ) ;
* p_upgrade_ok = false ;
return - 1 ;
} else {
DEBUG ( 10 , ( " upgrade_v2_to_v3: stored secdesc for "
" %s \n " , newkey ) ) ;
}
TALLOC_FREE ( newkey ) ;
TALLOC_FREE ( c_servicename ) ;
return 0 ;
}
2009-08-27 03:17:38 +04:00
bool share_info_db_init ( void )
2006-02-04 01:19:41 +03:00
{
const char * vstring = " INFO/version " ;
int32 vers_id ;
2010-03-23 01:57:31 +03:00
int ret ;
bool upgrade_ok = true ;
2008-12-29 04:16:28 +03:00
2008-03-28 01:10:57 +03:00
if ( share_db ! = NULL ) {
2006-02-04 01:19:41 +03:00
return True ;
}
2008-08-07 10:20:05 +04:00
share_db = db_open ( NULL , state_path ( " share_info.tdb " ) , 0 ,
2008-03-28 10:27:11 +03:00
TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
2008-03-28 01:10:57 +03:00
if ( share_db = = NULL ) {
2006-02-04 01:19:41 +03:00
DEBUG ( 0 , ( " Failed to open share info database %s (%s) \n " ,
2007-11-01 22:53:44 +03:00
state_path ( " share_info.tdb " ) , strerror ( errno ) ) ) ;
2006-02-04 01:19:41 +03:00
return False ;
}
2008-12-29 04:16:28 +03:00
2008-03-28 01:10:57 +03:00
vers_id = dbwrap_fetch_int32 ( share_db , vstring ) ;
2010-03-23 01:57:31 +03:00
if ( vers_id = = SHARE_DATABASE_VERSION_V3 ) {
2008-03-28 01:10:57 +03:00
return true ;
}
if ( share_db - > transaction_start ( share_db ) ! = 0 ) {
DEBUG ( 0 , ( " transaction_start failed \n " ) ) ;
TALLOC_FREE ( share_db ) ;
return false ;
}
vers_id = dbwrap_fetch_int32 ( share_db , vstring ) ;
2010-03-23 01:57:31 +03:00
if ( vers_id = = SHARE_DATABASE_VERSION_V3 ) {
2008-03-28 01:10:57 +03:00
/*
* Race condition
*/
if ( share_db - > transaction_cancel ( share_db ) ) {
smb_panic ( " transaction_cancel failed " ) ;
}
return true ;
}
2006-02-04 01:19:41 +03:00
2010-03-23 01:57:31 +03:00
/* Move to at least V2. */
2006-02-04 01:19:41 +03:00
/* Cope with byte-reversed older versions of the db. */
if ( ( vers_id = = SHARE_DATABASE_VERSION_V1 ) | | ( IREV ( vers_id ) = = SHARE_DATABASE_VERSION_V1 ) ) {
/* Written on a bigendian machine with old fetch_int code. Save as le. */
2008-03-28 01:10:57 +03:00
if ( dbwrap_store_int32 ( share_db , vstring ,
SHARE_DATABASE_VERSION_V2 ) ! = 0 ) {
DEBUG ( 0 , ( " dbwrap_store_int32 failed \n " ) ) ;
goto cancel ;
}
2006-02-04 01:19:41 +03:00
vers_id = SHARE_DATABASE_VERSION_V2 ;
}
if ( vers_id ! = SHARE_DATABASE_VERSION_V2 ) {
2008-04-15 02:18:34 +04:00
ret = share_db - > traverse ( share_db , delete_fn , NULL ) ;
if ( ret < 0 ) {
DEBUG ( 0 , ( " traverse failed \n " ) ) ;
2008-03-28 01:10:57 +03:00
goto cancel ;
}
if ( dbwrap_store_int32 ( share_db , vstring ,
SHARE_DATABASE_VERSION_V2 ) ! = 0 ) {
DEBUG ( 0 , ( " dbwrap_store_int32 failed \n " ) ) ;
goto cancel ;
}
2006-02-04 01:19:41 +03:00
}
2010-03-23 01:57:31 +03:00
/* Finally upgrade to version 3, with canonicalized sharenames. */
ret = share_db - > traverse ( share_db , upgrade_v2_to_v3 , & upgrade_ok ) ;
if ( ret < 0 | | upgrade_ok = = false ) {
DEBUG ( 0 , ( " traverse failed \n " ) ) ;
goto cancel ;
}
if ( dbwrap_store_int32 ( share_db , vstring ,
SHARE_DATABASE_VERSION_V3 ) ! = 0 ) {
DEBUG ( 0 , ( " dbwrap_store_int32 failed \n " ) ) ;
goto cancel ;
}
2008-03-28 01:10:57 +03:00
if ( share_db - > transaction_commit ( share_db ) ! = 0 ) {
DEBUG ( 0 , ( " transaction_commit failed \n " ) ) ;
2008-08-08 05:42:06 +04:00
return false ;
2008-03-28 01:10:57 +03:00
}
return true ;
cancel :
if ( share_db - > transaction_cancel ( share_db ) ) {
smb_panic ( " transaction_cancel failed " ) ;
}
return false ;
2006-02-04 01:19:41 +03:00
}
/*******************************************************************
Fake up a Everyone , default access as a default .
def_access is a GENERIC_XXX access mode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-18 12:29:34 +04:00
struct security_descriptor * get_share_security_default ( TALLOC_CTX * ctx , size_t * psize , uint32 def_access )
2006-02-04 01:19:41 +03:00
{
2008-10-09 20:49:03 +04:00
uint32_t sa ;
2010-05-18 05:25:38 +04:00
struct security_ace ace ;
2010-05-18 05:30:40 +04:00
struct security_acl * psa = NULL ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * psd = NULL ;
2006-02-04 01:19:41 +03:00
uint32 spec_access = def_access ;
se_map_generic ( & spec_access , & file_generic_mapping ) ;
2008-10-09 20:49:03 +04:00
sa = ( def_access | spec_access ) ;
2006-02-04 01:19:41 +03:00
init_sec_ace ( & ace , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED , sa , 0 ) ;
if ( ( psa = make_sec_acl ( ctx , NT4_ACL_REVISION , 1 , & ace ) ) ! = NULL ) {
2007-12-21 00:27:01 +03:00
psd = make_sec_desc ( ctx , SECURITY_DESCRIPTOR_REVISION_1 ,
SEC_DESC_SELF_RELATIVE , NULL , NULL , NULL ,
psa , psize ) ;
2006-02-04 01:19:41 +03:00
}
if ( ! psd ) {
DEBUG ( 0 , ( " get_share_security: Failed to make SEC_DESC. \n " ) ) ;
return NULL ;
}
return psd ;
}
/*******************************************************************
Pull a security descriptor from the share tdb .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-18 12:29:34 +04:00
struct security_descriptor * get_share_security ( TALLOC_CTX * ctx , const char * servicename ,
2006-07-14 21:46:06 +04:00
size_t * psize )
2006-02-04 01:19:41 +03:00
{
2007-10-07 16:56:43 +04:00
char * key ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * psd = NULL ;
2007-10-07 16:56:43 +04:00
TDB_DATA data ;
2010-03-23 01:57:31 +03:00
char * c_servicename = canonicalize_servicename ( talloc_tos ( ) , servicename ) ;
2007-10-07 16:56:43 +04:00
NTSTATUS status ;
2006-02-04 01:19:41 +03:00
2010-03-23 01:57:31 +03:00
if ( ! c_servicename ) {
return NULL ;
}
2006-02-04 01:19:41 +03:00
if ( ! share_info_db_init ( ) ) {
2010-03-23 01:57:31 +03:00
TALLOC_FREE ( c_servicename ) ;
2006-02-04 01:19:41 +03:00
return NULL ;
}
2010-03-23 01:57:31 +03:00
if ( ! ( key = talloc_asprintf ( ctx , SHARE_SECURITY_DB_KEY_PREFIX_STR " %s " , c_servicename ) ) ) {
TALLOC_FREE ( c_servicename ) ;
2007-10-07 16:56:43 +04:00
DEBUG ( 0 , ( " talloc_asprintf failed \n " ) ) ;
return NULL ;
}
2006-02-04 01:19:41 +03:00
2010-03-23 01:57:31 +03:00
TALLOC_FREE ( c_servicename ) ;
2008-03-28 01:10:57 +03:00
data = dbwrap_fetch_bystring ( share_db , talloc_tos ( ) , key ) ;
2007-10-07 16:56:43 +04:00
TALLOC_FREE ( key ) ;
if ( data . dptr = = NULL ) {
return get_share_security_default ( ctx , psize ,
GENERIC_ALL_ACCESS ) ;
}
status = unmarshall_sec_desc ( ctx , data . dptr , data . dsize , & psd ) ;
2008-03-28 01:10:57 +03:00
TALLOC_FREE ( data . dptr ) ;
2008-03-28 00:54:10 +03:00
2007-10-07 16:56:43 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " unmarshall_sec_desc failed: %s \n " ,
nt_errstr ( status ) ) ) ;
2010-03-23 01:57:31 +03:00
return get_share_security_default ( ctx , psize ,
GENERIC_ALL_ACCESS ) ;
2006-02-04 01:19:41 +03:00
}
2010-03-23 01:57:31 +03:00
if ( psd ) {
2010-05-10 02:42:06 +04:00
* psize = ndr_size_security_descriptor ( psd , 0 ) ;
2010-03-23 01:57:31 +03:00
} else {
return get_share_security_default ( ctx , psize ,
GENERIC_ALL_ACCESS ) ;
}
2006-02-04 01:19:41 +03:00
return psd ;
}
/*******************************************************************
Store a security descriptor in the share db .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-18 12:29:34 +04:00
bool set_share_security ( const char * share_name , struct security_descriptor * psd )
2006-02-04 01:19:41 +03:00
{
2010-03-23 01:57:31 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-10-07 16:56:43 +04:00
char * key ;
2007-10-19 04:40:25 +04:00
bool ret = False ;
2007-10-07 16:56:43 +04:00
TDB_DATA blob ;
NTSTATUS status ;
2010-03-23 01:57:31 +03:00
char * c_share_name = canonicalize_servicename ( frame , share_name ) ;
2006-02-04 01:19:41 +03:00
2010-03-23 01:57:31 +03:00
if ( ! c_share_name ) {
goto out ;
2006-02-04 01:19:41 +03:00
}
2010-03-23 01:57:31 +03:00
if ( ! share_info_db_init ( ) ) {
goto out ;
}
2006-02-04 01:19:41 +03:00
2007-10-07 16:56:43 +04:00
status = marshall_sec_desc ( frame , psd , & blob . dptr , & blob . dsize ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " marshall_sec_desc failed: %s \n " ,
nt_errstr ( status ) ) ) ;
2006-02-04 01:19:41 +03:00
goto out ;
2007-10-07 16:56:43 +04:00
}
2010-03-23 01:57:31 +03:00
if ( ! ( key = talloc_asprintf ( frame , SHARE_SECURITY_DB_KEY_PREFIX_STR " %s " , c_share_name ) ) ) {
2007-10-07 16:56:43 +04:00
DEBUG ( 0 , ( " talloc_asprintf failed \n " ) ) ;
goto out ;
}
2008-03-28 13:53:00 +03:00
status = dbwrap_trans_store ( share_db , string_term_tdb_data ( key ) , blob ,
TDB_REPLACE ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " set_share_security: Failed to store secdesc for "
" %s: %s \n " , share_name , nt_errstr ( status ) ) ) ;
2007-10-07 16:56:43 +04:00
goto out ;
}
DEBUG ( 5 , ( " set_share_security: stored secdesc for %s \n " , share_name ) ) ;
ret = True ;
out :
TALLOC_FREE ( frame ) ;
2006-02-04 01:19:41 +03:00
return ret ;
}
/*******************************************************************
Delete a security descriptor .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool delete_share_security ( const char * servicename )
2006-02-04 01:19:41 +03:00
{
TDB_DATA kbuf ;
2007-10-07 21:58:48 +04:00
char * key ;
2008-03-28 13:57:54 +03:00
NTSTATUS status ;
2010-03-23 01:57:31 +03:00
char * c_servicename = canonicalize_servicename ( talloc_tos ( ) , servicename ) ;
if ( ! c_servicename ) {
return NULL ;
}
2006-02-04 01:19:41 +03:00
2008-12-29 04:16:28 +03:00
if ( ! share_info_db_init ( ) ) {
2010-03-23 01:57:31 +03:00
TALLOC_FREE ( c_servicename ) ;
2008-12-29 04:16:28 +03:00
return False ;
}
2010-03-23 01:57:31 +03:00
if ( ! ( key = talloc_asprintf ( talloc_tos ( ) , SHARE_SECURITY_DB_KEY_PREFIX_STR " %s " ,
c_servicename ) ) ) {
TALLOC_FREE ( c_servicename ) ;
2007-10-07 21:58:48 +04:00
return False ;
}
2007-03-29 11:30:22 +04:00
kbuf = string_term_tdb_data ( key ) ;
2006-02-04 01:19:41 +03:00
2008-03-28 13:57:54 +03:00
status = dbwrap_trans_delete ( share_db , kbuf ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 21:58:48 +04:00
DEBUG ( 0 , ( " delete_share_security: Failed to delete entry for "
2010-03-23 01:57:31 +03:00
" share %s: %s \n " , c_servicename , nt_errstr ( status ) ) ) ;
TALLOC_FREE ( c_servicename ) ;
2006-02-04 01:19:41 +03:00
return False ;
}
2010-03-23 01:57:31 +03:00
TALLOC_FREE ( c_servicename ) ;
2006-02-04 01:19:41 +03:00
return True ;
}
2006-07-17 23:53:15 +04:00
/*******************************************************************
Can this user access with share with the required permissions ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-08-26 16:08:22 +04:00
bool share_access_check ( const struct security_token * token , const char * sharename ,
2006-07-17 23:53:15 +04:00
uint32 desired_access )
{
uint32 granted ;
NTSTATUS status ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * psd = NULL ;
2006-07-17 23:53:15 +04:00
size_t sd_size ;
2008-01-06 16:17:15 +03:00
psd = get_share_security ( talloc_tos ( ) , sharename , & sd_size ) ;
2006-07-17 23:53:15 +04:00
if ( ! psd ) {
return True ;
}
2008-10-31 20:51:45 +03:00
status = se_access_check ( psd , token , desired_access , & granted ) ;
2006-07-17 23:53:15 +04:00
2008-01-06 16:17:15 +03:00
TALLOC_FREE ( psd ) ;
2008-10-31 20:51:45 +03:00
return NT_STATUS_IS_OK ( status ) ;
2006-07-17 23:53:15 +04:00
}
2006-02-04 01:19:41 +03:00
/***************************************************************************
Parse the contents of an acl string from a usershare file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-18 12:29:34 +04:00
bool parse_usershare_acl ( TALLOC_CTX * ctx , const char * acl_str , struct security_descriptor * * ppsd )
2006-02-04 01:19:41 +03:00
{
size_t s_size = 0 ;
const char * pacl = acl_str ;
int num_aces = 0 ;
2010-05-18 05:25:38 +04:00
struct security_ace * ace_list = NULL ;
2010-05-18 05:30:40 +04:00
struct security_acl * psa = NULL ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * psd = NULL ;
2006-02-04 01:19:41 +03:00
size_t sd_size = 0 ;
int i ;
* ppsd = NULL ;
/* If the acl string is blank return "Everyone:R" */
if ( ! * acl_str ) {
2010-05-18 12:29:34 +04:00
struct security_descriptor * default_psd = get_share_security_default ( ctx , & s_size , GENERIC_READ_ACCESS ) ;
2006-02-04 01:19:41 +03:00
if ( ! default_psd ) {
return False ;
}
* ppsd = default_psd ;
return True ;
}
num_aces = 1 ;
/* Add the number of ',' characters to get the number of aces. */
num_aces + = count_chars ( pacl , ' , ' ) ;
2010-05-18 05:25:38 +04:00
ace_list = TALLOC_ARRAY ( ctx , struct security_ace , num_aces ) ;
2006-02-04 01:19:41 +03:00
if ( ! ace_list ) {
return False ;
}
for ( i = 0 ; i < num_aces ; i + + ) {
2008-10-09 20:49:03 +04:00
uint32_t sa ;
2006-02-04 01:19:41 +03:00
uint32 g_access ;
uint32 s_access ;
2010-05-21 05:25:01 +04:00
struct dom_sid sid ;
2007-12-08 04:32:32 +03:00
char * sidstr ;
2007-12-21 00:27:01 +03:00
enum security_ace_type type = SEC_ACE_TYPE_ACCESS_ALLOWED ;
2006-02-04 01:19:41 +03:00
2007-12-08 04:32:32 +03:00
if ( ! next_token_talloc ( ctx , & pacl , & sidstr , " : " ) ) {
2006-02-04 01:19:41 +03:00
DEBUG ( 0 , ( " parse_usershare_acl: malformed usershare acl looking "
" for ':' in string '%s' \n " , pacl ) ) ;
return False ;
}
if ( ! string_to_sid ( & sid , sidstr ) ) {
DEBUG ( 0 , ( " parse_usershare_acl: failed to convert %s to sid. \n " ,
sidstr ) ) ;
return False ;
}
switch ( * pacl ) {
case ' F ' : /* Full Control, ie. R+W */
case ' f ' : /* Full Control, ie. R+W */
s_access = g_access = GENERIC_ALL_ACCESS ;
break ;
case ' R ' : /* Read only. */
case ' r ' : /* Read only. */
s_access = g_access = GENERIC_READ_ACCESS ;
break ;
case ' D ' : /* Deny all to this SID. */
case ' d ' : /* Deny all to this SID. */
type = SEC_ACE_TYPE_ACCESS_DENIED ;
s_access = g_access = GENERIC_ALL_ACCESS ;
break ;
default :
DEBUG ( 0 , ( " parse_usershare_acl: unknown acl type at %s. \n " ,
pacl ) ) ;
return False ;
}
pacl + + ;
if ( * pacl & & * pacl ! = ' , ' ) {
DEBUG ( 0 , ( " parse_usershare_acl: bad acl string at %s. \n " ,
pacl ) ) ;
return False ;
}
pacl + + ; /* Go past any ',' */
se_map_generic ( & s_access , & file_generic_mapping ) ;
2008-10-09 20:49:03 +04:00
sa = ( g_access | s_access ) ;
2006-02-04 01:19:41 +03:00
init_sec_ace ( & ace_list [ i ] , & sid , type , sa , 0 ) ;
}
if ( ( psa = make_sec_acl ( ctx , NT4_ACL_REVISION , num_aces , ace_list ) ) ! = NULL ) {
2007-12-21 00:27:01 +03:00
psd = make_sec_desc ( ctx , SECURITY_DESCRIPTOR_REVISION_1 ,
SEC_DESC_SELF_RELATIVE , NULL , NULL , NULL ,
psa , & sd_size ) ;
2006-02-04 01:19:41 +03:00
}
if ( ! psd ) {
DEBUG ( 0 , ( " parse_usershare_acl: Failed to make SEC_DESC. \n " ) ) ;
return False ;
}
* ppsd = psd ;
return True ;
}