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"
2011-02-26 01:20:06 +03:00
# include "system/filesys.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"
2011-07-07 19:42:08 +04:00
# include "dbwrap/dbwrap.h"
2011-07-06 18:40:21 +04:00
# include "dbwrap/dbwrap_open.h"
2011-05-05 13:25:29 +04:00
# include "util_tdb.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 )
{
2011-08-17 12:46:22 +04:00
dbwrap_record_delete ( rec ) ;
2008-03-28 01:10:57 +03:00
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 ;
2011-08-17 12:46:22 +04:00
TDB_DATA key ;
TDB_DATA value ;
key = dbwrap_record_get_key ( rec ) ;
2010-03-23 01:57:31 +03:00
/* Is there space for a one character sharename ? */
2011-08-17 12:46:22 +04:00
if ( key . dsize < = prefix_len + 2 ) {
2010-03-23 01:57:31 +03:00
return 0 ;
}
/* Does it start with the share key prefix ? */
2011-08-17 12:46:22 +04:00
if ( memcmp ( key . dptr , SHARE_SECURITY_DB_KEY_PREFIX_STR ,
2010-03-23 01:57:31 +03:00
prefix_len ) ! = 0 ) {
return 0 ;
}
/* Is it a null terminated string as a key ? */
2011-08-17 12:46:22 +04:00
if ( key . dptr [ key . dsize - 1 ] ! = ' \0 ' ) {
2010-03-23 01:57:31 +03:00
return 0 ;
}
/* Bytes after the prefix are the sharename string. */
2011-08-17 12:46:22 +04:00
servicename = ( char * ) & key . dptr [ prefix_len ] ;
2010-03-23 01:57:31 +03:00
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. */
2011-08-17 12:46:22 +04:00
status = dbwrap_record_delete ( rec ) ;
2010-03-23 01:57:31 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " upgrade_v2_to_v3: Failed to delete secdesc for "
2011-08-17 12:46:22 +04:00
" %s: %s \n " , ( const char * ) key . dptr ,
nt_errstr ( status ) ) ) ;
2010-03-23 01:57:31 +03:00
TALLOC_FREE ( c_servicename ) ;
* p_upgrade_ok = false ;
return - 1 ;
} else {
DEBUG ( 10 , ( " upgrade_v2_to_v3: deleted secdesc for "
2011-08-17 12:46:22 +04:00
" %s \n " , ( const char * ) key . dptr ) ) ;
2010-03-23 01:57:31 +03:00
}
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 " ) ;
}
2011-08-17 12:46:22 +04:00
value = dbwrap_record_get_value ( rec ) ;
2010-03-23 01:57:31 +03:00
status = dbwrap_store ( share_db ,
string_term_tdb_data ( newkey ) ,
2011-08-17 12:46:22 +04:00
value ,
2010-03-23 01:57:31 +03:00
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 " ;
2015-05-16 00:56:25 +03:00
int32_t vers_id = 0 ;
2010-03-23 01:57:31 +03:00
bool upgrade_ok = true ;
2011-08-17 12:46:22 +04:00
NTSTATUS status ;
2014-11-02 22:21:25 +03:00
char * db_path ;
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 ;
}
2014-11-02 22:21:25 +03:00
db_path = state_path ( " share_info.tdb " ) ;
if ( db_path = = NULL ) {
return false ;
}
share_db = db_open ( NULL , db_path , 0 ,
2012-01-06 20:19:54 +04:00
TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ,
2014-01-27 17:49:12 +04:00
DBWRAP_LOCK_ORDER_1 , DBWRAP_FLAG_NONE ) ;
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 " ,
2014-11-02 22:21:25 +03:00
db_path , strerror ( errno ) ) ) ;
TALLOC_FREE ( db_path ) ;
2006-02-04 01:19:41 +03:00
return False ;
}
2014-11-02 22:21:25 +03:00
TALLOC_FREE ( db_path ) ;
2008-12-29 04:16:28 +03:00
2012-06-14 22:26:28 +04:00
status = dbwrap_fetch_int32_bystring ( share_db , vstring , & vers_id ) ;
2011-10-06 22:34:55 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
vers_id = 0 ;
}
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 ;
}
2011-08-17 12:46:22 +04:00
if ( dbwrap_transaction_start ( share_db ) ! = 0 ) {
2008-03-28 01:10:57 +03:00
DEBUG ( 0 , ( " transaction_start failed \n " ) ) ;
TALLOC_FREE ( share_db ) ;
return false ;
}
2012-06-14 22:26:28 +04:00
status = dbwrap_fetch_int32_bystring ( share_db , vstring , & vers_id ) ;
2011-10-06 22:34:55 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
vers_id = 0 ;
}
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
*/
2011-08-17 12:46:22 +04:00
if ( dbwrap_transaction_cancel ( share_db ) ) {
2008-03-28 01:10:57 +03:00
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
2012-06-14 22:30:16 +04:00
status = dbwrap_store_int32_bystring (
share_db , vstring , SHARE_DATABASE_VERSION_V2 ) ;
2011-10-06 23:24:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dbwrap_store_int32 failed: %s \n " ,
nt_errstr ( status ) ) ) ;
2008-03-28 01:10:57 +03:00
goto cancel ;
}
2006-02-04 01:19:41 +03:00
vers_id = SHARE_DATABASE_VERSION_V2 ;
}
if ( vers_id ! = SHARE_DATABASE_VERSION_V2 ) {
2011-08-17 12:46:22 +04:00
status = dbwrap_traverse ( share_db , delete_fn , NULL , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-04-15 02:18:34 +04:00
DEBUG ( 0 , ( " traverse failed \n " ) ) ;
2008-03-28 01:10:57 +03:00
goto cancel ;
}
2012-06-14 22:30:16 +04:00
status = dbwrap_store_int32_bystring (
share_db , vstring , SHARE_DATABASE_VERSION_V2 ) ;
2011-10-06 23:24:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dbwrap_store_int32 failed: %s \n " ,
nt_errstr ( status ) ) ) ;
2008-03-28 01:10:57 +03:00
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. */
2011-08-17 12:46:22 +04:00
status = dbwrap_traverse ( share_db , upgrade_v2_to_v3 , & upgrade_ok , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) | | upgrade_ok = = false ) {
2010-03-23 01:57:31 +03:00
DEBUG ( 0 , ( " traverse failed \n " ) ) ;
goto cancel ;
}
2012-06-14 22:30:16 +04:00
status = dbwrap_store_int32_bystring (
share_db , vstring , SHARE_DATABASE_VERSION_V3 ) ;
2011-10-06 23:24:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " dbwrap_store_int32 failed: %s \n " ,
nt_errstr ( status ) ) ) ;
2010-03-23 01:57:31 +03:00
goto cancel ;
}
2011-08-17 12:46:22 +04:00
if ( dbwrap_transaction_commit ( share_db ) ! = 0 ) {
2008-03-28 01:10:57 +03:00
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 :
2011-08-17 12:46:22 +04:00
if ( dbwrap_transaction_cancel ( share_db ) ) {
2008-03-28 01:10:57 +03:00
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-04-25 05:22:21 +03:00
struct security_descriptor * get_share_security_default ( TALLOC_CTX * ctx , size_t * psize , uint32_t 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 ;
2015-04-25 05:22:21 +03:00
uint32_t spec_access = def_access ;
2006-02-04 01:19:41 +03:00
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 ) ;
2011-08-24 15:08:13 +04:00
status = dbwrap_fetch_bystring ( share_db , talloc_tos ( ) , key , & data ) ;
2007-10-07 16:56:43 +04:00
TALLOC_FREE ( key ) ;
2011-08-24 15:08:13 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 16:56:43 +04:00
return get_share_security_default ( ctx , psize ,
2011-07-26 15:43:14 +04:00
SEC_RIGHTS_DIR_ALL ) ;
2007-10-07 16:56:43 +04:00
}
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 ) ) {
2010-03-23 01:57:31 +03:00
return get_share_security_default ( ctx , psize ,
2011-07-26 15:43:14 +04:00
SEC_RIGHTS_DIR_ALL ) ;
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 ,
2011-07-26 15:43:14 +04:00
SEC_RIGHTS_DIR_ALL ) ;
2010-03-23 01:57:31 +03:00
}
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 ?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-07-04 19:02:34 +04:00
bool share_access_check ( const struct security_token * token ,
const char * sharename ,
2015-04-25 05:22:21 +03:00
uint32_t desired_access ,
2011-07-04 19:02:34 +04:00
uint32_t * pgranted )
2006-07-17 23:53:15 +04:00
{
2015-04-25 05:22:21 +03:00
uint32_t granted ;
2006-07-17 23:53:15 +04:00
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 ) {
2011-07-05 18:59:41 +04:00
if ( pgranted ! = NULL ) {
* pgranted = desired_access ;
}
2011-07-06 14:31:41 +04:00
return false ;
2006-07-17 23:53:15 +04:00
}
2012-08-28 03:07:32 +04:00
status = se_file_access_check ( psd , token , true , desired_access , & granted ) ;
2006-07-17 23:53:15 +04:00
2008-01-06 16:17:15 +03:00
TALLOC_FREE ( psd ) ;
2011-07-04 19:02:34 +04:00
if ( pgranted ! = NULL ) {
* pgranted = granted ;
}
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 , ' , ' ) ;
2011-06-07 05:30:12 +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 ;
2015-04-25 05:22:21 +03:00
uint32_t g_access ;
uint32_t 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 ;
}