2005-12-02 06:16:42 +03:00
/*
Unix SMB / CIFS implementation .
security descriptor description language functions
Copyright ( C ) Andrew Tridgell 2005
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-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-12-02 06:16:42 +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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-12-02 06:16:42 +03:00
*/
# include "includes.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2006-04-29 21:34:49 +04:00
# include "librpc/gen_ndr/ndr_misc.h"
2006-05-13 23:14:12 +04:00
# include "system/locale.h"
2005-12-02 06:16:42 +03:00
struct flag_map {
const char * name ;
uint32_t flag ;
} ;
/*
map a series of letter codes into a uint32_t
*/
static BOOL sddl_map_flags ( const struct flag_map * map , const char * str ,
uint32_t * flags , size_t * len )
{
2005-12-02 07:26:51 +03:00
const char * str0 = str ;
2005-12-02 06:16:42 +03:00
if ( len ) * len = 0 ;
* flags = 0 ;
while ( str [ 0 ] & & isupper ( str [ 0 ] ) ) {
int i ;
for ( i = 0 ; map [ i ] . name ; i + + ) {
size_t l = strlen ( map [ i ] . name ) ;
if ( strncmp ( map [ i ] . name , str , l ) = = 0 ) {
* flags | = map [ i ] . flag ;
str + = l ;
if ( len ) * len + = l ;
break ;
}
}
if ( map [ i ] . name = = NULL ) {
2005-12-02 07:26:51 +03:00
DEBUG ( 1 , ( " Unknown flag - %s in %s \n " , str , str0 ) ) ;
2005-12-02 06:16:42 +03:00
return False ;
}
}
return True ;
}
/*
a mapping between the 2 letter SID codes and sid strings
*/
static const struct {
const char * code ;
const char * sid ;
2005-12-02 07:26:51 +03:00
uint32_t rid ;
2005-12-02 06:16:42 +03:00
} sid_codes [ ] = {
{ " AO " , SID_BUILTIN_ACCOUNT_OPERATORS } ,
2005-12-02 07:26:51 +03:00
{ " BA " , SID_BUILTIN_ADMINISTRATORS } ,
{ " RU " , SID_BUILTIN_PREW2K } ,
{ " PO " , SID_BUILTIN_PRINT_OPERATORS } ,
{ " RS " , SID_BUILTIN_RAS_SERVERS } ,
{ " AU " , SID_NT_AUTHENTICATED_USERS } ,
{ " SY " , SID_NT_SYSTEM } ,
{ " PS " , SID_NT_SELF } ,
{ " WD " , SID_WORLD } ,
{ " ED " , SID_NT_ENTERPRISE_DCS } ,
{ " CO " , SID_CREATOR_OWNER } ,
{ " CG " , SID_CREATOR_GROUP } ,
{ " DA " , NULL , DOMAIN_RID_ADMINS } ,
{ " EA " , NULL , DOMAIN_RID_ENTERPRISE_ADMINS } ,
{ " DD " , NULL , DOMAIN_RID_DCS } ,
{ " DU " , NULL , DOMAIN_RID_USERS } ,
{ " CA " , NULL , DOMAIN_RID_CERT_ADMINS } ,
2005-12-02 06:16:42 +03:00
} ;
/*
decode a SID
It can either be a special 2 letter code , or in S - * format
*/
2005-12-02 07:26:51 +03:00
static struct dom_sid * sddl_decode_sid ( TALLOC_CTX * mem_ctx , const char * * sddlp ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-02 06:16:42 +03:00
{
const char * sddl = ( * sddlp ) ;
int i ;
/* see if its in the numeric format */
if ( strncmp ( sddl , " S- " , 2 ) = = 0 ) {
2007-01-15 12:02:58 +03:00
struct dom_sid * sid ;
char * sid_str ;
2005-12-02 06:16:42 +03:00
size_t len = strspn ( sddl + 2 , " -0123456789 " ) ;
2007-01-15 12:02:58 +03:00
sid_str = talloc_strndup ( mem_ctx , sddl , len + 2 ) ;
if ( ! sid_str ) {
return NULL ;
}
2005-12-02 06:16:42 +03:00
( * sddlp ) + = len + 2 ;
2007-01-15 12:02:58 +03:00
sid = dom_sid_parse_talloc ( mem_ctx , sid_str ) ;
talloc_free ( sid_str ) ;
return sid ;
2005-12-02 06:16:42 +03:00
}
/* now check for one of the special codes */
for ( i = 0 ; i < ARRAY_SIZE ( sid_codes ) ; i + + ) {
2005-12-02 07:26:51 +03:00
if ( strncmp ( sid_codes [ i ] . code , sddl , 2 ) = = 0 ) break ;
2005-12-02 06:16:42 +03:00
}
if ( i = = ARRAY_SIZE ( sid_codes ) ) {
2005-12-02 07:26:51 +03:00
DEBUG ( 1 , ( " Unknown sddl sid code '%2.2s' \n " , sddl ) ) ;
2005-12-02 06:16:42 +03:00
return NULL ;
}
( * sddlp ) + = 2 ;
2005-12-02 07:26:51 +03:00
if ( sid_codes [ i ] . sid = = NULL ) {
return dom_sid_add_rid ( mem_ctx , domain_sid , sid_codes [ i ] . rid ) ;
}
2005-12-02 06:16:42 +03:00
return dom_sid_parse_talloc ( mem_ctx , sid_codes [ i ] . sid ) ;
}
static const struct flag_map ace_types [ ] = {
{ " AU " , SEC_ACE_TYPE_SYSTEM_AUDIT } ,
{ " AL " , SEC_ACE_TYPE_SYSTEM_ALARM } ,
{ " OA " , SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT } ,
{ " OD " , SEC_ACE_TYPE_ACCESS_DENIED_OBJECT } ,
{ " OU " , SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT } ,
{ " OL " , SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT } ,
2005-12-02 07:26:51 +03:00
{ " A " , SEC_ACE_TYPE_ACCESS_ALLOWED } ,
{ " D " , SEC_ACE_TYPE_ACCESS_DENIED } ,
2005-12-02 06:16:42 +03:00
{ NULL , 0 }
} ;
static const struct flag_map ace_flags [ ] = {
{ " OI " , SEC_ACE_FLAG_OBJECT_INHERIT } ,
{ " CI " , SEC_ACE_FLAG_CONTAINER_INHERIT } ,
{ " NP " , SEC_ACE_FLAG_NO_PROPAGATE_INHERIT } ,
{ " IO " , SEC_ACE_FLAG_INHERIT_ONLY } ,
{ " ID " , SEC_ACE_FLAG_INHERITED_ACE } ,
{ " SA " , SEC_ACE_FLAG_SUCCESSFUL_ACCESS } ,
{ " FA " , SEC_ACE_FLAG_FAILED_ACCESS } ,
{ NULL , 0 } ,
} ;
static const struct flag_map ace_access_mask [ ] = {
{ " RP " , SEC_ADS_READ_PROP } ,
{ " WP " , SEC_ADS_WRITE_PROP } ,
{ " CR " , SEC_ADS_CONTROL_ACCESS } ,
{ " CC " , SEC_ADS_CREATE_CHILD } ,
{ " DC " , SEC_ADS_DELETE_CHILD } ,
{ " LC " , SEC_ADS_LIST } ,
{ " LO " , SEC_ADS_LIST_OBJECT } ,
2005-12-09 08:21:47 +03:00
{ " RC " , SEC_STD_READ_CONTROL } ,
2005-12-02 06:16:42 +03:00
{ " WO " , SEC_STD_WRITE_OWNER } ,
{ " WD " , SEC_STD_WRITE_DAC } ,
{ " SD " , SEC_STD_DELETE } ,
{ " DT " , SEC_ADS_DELETE_TREE } ,
{ " SW " , SEC_ADS_SELF_WRITE } ,
2005-12-02 07:26:51 +03:00
{ " GA " , SEC_GENERIC_ALL } ,
{ " GR " , SEC_GENERIC_READ } ,
{ " GW " , SEC_GENERIC_WRITE } ,
{ " GX " , SEC_GENERIC_EXECUTE } ,
2005-12-02 06:16:42 +03:00
{ NULL , 0 }
} ;
/*
decode an ACE
return True on success , False on failure
note that this routine modifies the string
*/
2005-12-02 07:26:51 +03:00
static BOOL sddl_decode_ace ( TALLOC_CTX * mem_ctx , struct security_ace * ace , char * str ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-02 06:16:42 +03:00
{
const char * tok [ 6 ] ;
const char * s ;
int i ;
uint32_t v ;
struct dom_sid * sid ;
2005-12-02 07:26:51 +03:00
ZERO_STRUCTP ( ace ) ;
2005-12-02 06:16:42 +03:00
/* parse out the 6 tokens */
tok [ 0 ] = str ;
for ( i = 0 ; i < 5 ; i + + ) {
char * ptr = strchr ( str , ' ; ' ) ;
if ( ptr = = NULL ) return False ;
* ptr = 0 ;
str = ptr + 1 ;
tok [ i + 1 ] = str ;
}
/* parse ace type */
if ( ! sddl_map_flags ( ace_types , tok [ 0 ] , & v , NULL ) ) {
return False ;
}
ace - > type = v ;
/* ace flags */
if ( ! sddl_map_flags ( ace_flags , tok [ 1 ] , & v , NULL ) ) {
return False ;
}
ace - > flags = v ;
/* access mask */
if ( strncmp ( tok [ 2 ] , " 0x " , 2 ) = = 0 ) {
ace - > access_mask = strtol ( tok [ 2 ] , NULL , 16 ) ;
} else {
if ( ! sddl_map_flags ( ace_access_mask , tok [ 2 ] , & v , NULL ) ) {
return False ;
}
ace - > access_mask = v ;
}
/* object */
if ( tok [ 3 ] [ 0 ] ! = 0 ) {
2005-12-02 07:26:51 +03:00
NTSTATUS status = GUID_from_string ( tok [ 3 ] ,
& ace - > object . object . type . type ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return False ;
}
2005-12-09 09:22:09 +03:00
ace - > object . object . flags | = SEC_ACE_OBJECT_TYPE_PRESENT ;
2005-12-02 06:16:42 +03:00
}
/* inherit object */
if ( tok [ 4 ] [ 0 ] ! = 0 ) {
2005-12-02 07:26:51 +03:00
NTSTATUS status = GUID_from_string ( tok [ 4 ] ,
& ace - > object . object . inherited_type . inherited_type ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return False ;
}
2005-12-09 09:22:09 +03:00
ace - > object . object . flags | = SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT ;
2005-12-02 06:16:42 +03:00
}
/* trustee */
s = tok [ 5 ] ;
2005-12-02 07:26:51 +03:00
sid = sddl_decode_sid ( mem_ctx , & s , domain_sid ) ;
2005-12-02 06:16:42 +03:00
if ( sid = = NULL ) {
return False ;
}
ace - > trustee = * sid ;
talloc_steal ( mem_ctx , sid - > sub_auths ) ;
talloc_free ( sid ) ;
return True ;
}
static const struct flag_map acl_flags [ ] = {
{ " P " , SEC_DESC_DACL_PROTECTED } ,
{ " AR " , SEC_DESC_DACL_AUTO_INHERIT_REQ } ,
{ " AI " , SEC_DESC_DACL_AUTO_INHERITED } ,
{ NULL , 0 }
} ;
/*
decode an ACL
*/
static struct security_acl * sddl_decode_acl ( struct security_descriptor * sd ,
2005-12-02 07:26:51 +03:00
const char * * sddlp , uint32_t * flags ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-02 06:16:42 +03:00
{
const char * sddl = * sddlp ;
struct security_acl * acl ;
size_t len ;
2005-12-09 07:54:30 +03:00
* flags = 0 ;
2005-12-02 06:16:42 +03:00
acl = talloc_zero ( sd , struct security_acl ) ;
if ( acl = = NULL ) return NULL ;
acl - > revision = SECURITY_ACL_REVISION_NT4 ;
2005-12-02 07:26:51 +03:00
if ( isupper ( sddl [ 0 ] ) & & sddl [ 1 ] = = ' : ' ) {
/* its an empty ACL */
return acl ;
}
2005-12-02 06:16:42 +03:00
/* work out the ACL flags */
if ( ! sddl_map_flags ( acl_flags , sddl , flags , & len ) ) {
talloc_free ( acl ) ;
return NULL ;
}
sddl + = len ;
/* now the ACEs */
while ( * sddl = = ' ( ' ) {
2005-12-02 08:29:13 +03:00
char * astr ;
2005-12-02 06:16:42 +03:00
len = strcspn ( sddl + 1 , " ) " ) ;
2005-12-02 08:29:13 +03:00
astr = talloc_strndup ( acl , sddl + 1 , len ) ;
2005-12-02 06:16:42 +03:00
if ( astr = = NULL | | sddl [ len + 1 ] ! = ' ) ' ) {
talloc_free ( acl ) ;
return NULL ;
}
acl - > aces = talloc_realloc ( acl , acl - > aces , struct security_ace ,
acl - > num_aces + 1 ) ;
if ( acl - > aces = = NULL ) {
talloc_free ( acl ) ;
return NULL ;
}
2005-12-02 07:26:51 +03:00
if ( ! sddl_decode_ace ( acl - > aces , & acl - > aces [ acl - > num_aces ] ,
astr , domain_sid ) ) {
2005-12-02 06:16:42 +03:00
talloc_free ( acl ) ;
return NULL ;
}
2007-01-15 13:10:15 +03:00
switch ( acl - > aces [ acl - > num_aces ] . type ) {
case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT :
case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT :
case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT :
case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT :
acl - > revision = SECURITY_ACL_REVISION_ADS ;
break ;
2007-01-15 13:39:17 +03:00
default :
break ;
2007-01-15 13:10:15 +03:00
}
2005-12-02 06:16:42 +03:00
talloc_free ( astr ) ;
sddl + = len + 2 ;
acl - > num_aces + + ;
}
( * sddlp ) = sddl ;
return acl ;
}
/*
decode a security descriptor in SDDL format
*/
2005-12-02 07:26:51 +03:00
struct security_descriptor * sddl_decode ( TALLOC_CTX * mem_ctx , const char * sddl ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-02 06:16:42 +03:00
{
struct security_descriptor * sd ;
sd = talloc_zero ( mem_ctx , struct security_descriptor ) ;
sd - > revision = SECURITY_DESCRIPTOR_REVISION_1 ;
sd - > type = SEC_DESC_SELF_RELATIVE ;
while ( * sddl ) {
uint32_t flags ;
char c = sddl [ 0 ] ;
if ( sddl [ 1 ] ! = ' : ' ) goto failed ;
sddl + = 2 ;
switch ( c ) {
case ' D ' :
if ( sd - > dacl ! = NULL ) goto failed ;
2005-12-02 07:26:51 +03:00
sd - > dacl = sddl_decode_acl ( sd , & sddl , & flags , domain_sid ) ;
2005-12-02 06:16:42 +03:00
if ( sd - > dacl = = NULL ) goto failed ;
sd - > type | = flags | SEC_DESC_DACL_PRESENT ;
break ;
case ' S ' :
if ( sd - > sacl ! = NULL ) goto failed ;
2005-12-02 07:26:51 +03:00
sd - > sacl = sddl_decode_acl ( sd , & sddl , & flags , domain_sid ) ;
2005-12-02 06:16:42 +03:00
if ( sd - > sacl = = NULL ) goto failed ;
/* this relies on the SEC_DESC_SACL_* flags being
1 bit shifted from the SEC_DESC_DACL_ * flags */
sd - > type | = ( flags < < 1 ) | SEC_DESC_SACL_PRESENT ;
break ;
case ' O ' :
if ( sd - > owner_sid ! = NULL ) goto failed ;
2005-12-02 07:26:51 +03:00
sd - > owner_sid = sddl_decode_sid ( sd , & sddl , domain_sid ) ;
2005-12-02 06:16:42 +03:00
if ( sd - > owner_sid = = NULL ) goto failed ;
break ;
case ' G ' :
if ( sd - > group_sid ! = NULL ) goto failed ;
2005-12-02 07:26:51 +03:00
sd - > group_sid = sddl_decode_sid ( sd , & sddl , domain_sid ) ;
2005-12-02 06:16:42 +03:00
if ( sd - > group_sid = = NULL ) goto failed ;
break ;
}
}
return sd ;
failed :
DEBUG ( 2 , ( " Badly formatted SDDL '%s' \n " , sddl ) ) ;
talloc_free ( sd ) ;
return NULL ;
}
2005-12-09 07:54:30 +03:00
/*
turn a set of flags into a string
*/
static char * sddl_flags_to_string ( TALLOC_CTX * mem_ctx , const struct flag_map * map ,
uint32_t flags , BOOL check_all )
{
int i ;
char * s ;
/* try to find an exact match */
for ( i = 0 ; map [ i ] . name ; i + + ) {
if ( map [ i ] . flag = = flags ) {
return talloc_strdup ( mem_ctx , map [ i ] . name ) ;
}
}
s = talloc_strdup ( mem_ctx , " " ) ;
/* now by bits */
for ( i = 0 ; map [ i ] . name ; i + + ) {
if ( ( flags & map [ i ] . flag ) ! = 0 ) {
2007-09-15 03:21:00 +04:00
s = talloc_asprintf_append_buffer ( s , " %s " , map [ i ] . name ) ;
2005-12-09 07:54:30 +03:00
if ( s = = NULL ) goto failed ;
flags & = ~ map [ i ] . flag ;
}
}
if ( check_all & & flags ! = 0 ) {
goto failed ;
}
return s ;
failed :
talloc_free ( s ) ;
return NULL ;
}
/*
encode a sid in SDDL format
*/
static char * sddl_encode_sid ( TALLOC_CTX * mem_ctx , const struct dom_sid * sid ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-09 07:54:30 +03:00
{
2005-12-09 08:21:47 +03:00
int i ;
char * sidstr ;
sidstr = dom_sid_string ( mem_ctx , sid ) ;
if ( sidstr = = NULL ) return NULL ;
/* seen if its a well known sid */
for ( i = 0 ; sid_codes [ i ] . sid ; i + + ) {
if ( strcmp ( sidstr , sid_codes [ i ] . sid ) = = 0 ) {
talloc_free ( sidstr ) ;
return talloc_strdup ( mem_ctx , sid_codes [ i ] . code ) ;
}
}
/* or a well known rid in our domain */
if ( dom_sid_in_domain ( domain_sid , sid ) ) {
uint32_t rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
for ( ; i < ARRAY_SIZE ( sid_codes ) ; i + + ) {
if ( rid = = sid_codes [ i ] . rid ) {
talloc_free ( sidstr ) ;
return talloc_strdup ( mem_ctx , sid_codes [ i ] . code ) ;
}
}
}
talloc_free ( sidstr ) ;
2005-12-09 07:54:30 +03:00
/* TODO: encode well known sids as two letter codes */
return dom_sid_string ( mem_ctx , sid ) ;
}
/*
encode an ACE in SDDL format
*/
static char * sddl_encode_ace ( TALLOC_CTX * mem_ctx , const struct security_ace * ace ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-09 07:54:30 +03:00
{
2005-12-10 12:18:03 +03:00
char * sddl = NULL ;
2005-12-09 07:54:30 +03:00
TALLOC_CTX * tmp_ctx ;
const char * s_type = " " , * s_flags = " " , * s_mask = " " ,
* s_object = " " , * s_iobject = " " , * s_trustee = " " ;
tmp_ctx = talloc_new ( mem_ctx ) ;
2005-12-10 12:18:03 +03:00
if ( tmp_ctx = = NULL ) {
DEBUG ( 0 , ( " talloc_new failed \n " ) ) ;
return NULL ;
}
2005-12-09 07:54:30 +03:00
s_type = sddl_flags_to_string ( tmp_ctx , ace_types , ace - > type , True ) ;
if ( s_type = = NULL ) goto failed ;
s_flags = sddl_flags_to_string ( tmp_ctx , ace_flags , ace - > flags , True ) ;
if ( s_flags = = NULL ) goto failed ;
s_mask = sddl_flags_to_string ( tmp_ctx , ace_access_mask , ace - > access_mask , True ) ;
2005-12-09 09:22:09 +03:00
if ( s_mask = = NULL ) {
s_mask = talloc_asprintf ( tmp_ctx , " 0x%08x " , ace - > access_mask ) ;
if ( s_mask = = NULL ) goto failed ;
}
2005-12-09 07:54:30 +03:00
2005-12-09 08:21:47 +03:00
if ( ace - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT | |
ace - > type = = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT | |
ace - > type = = SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT | |
ace - > type = = SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ) {
2005-12-09 09:22:09 +03:00
if ( ace - > object . object . flags & SEC_ACE_OBJECT_TYPE_PRESENT ) {
2005-12-09 08:21:47 +03:00
s_object = GUID_string ( tmp_ctx , & ace - > object . object . type . type ) ;
if ( s_object = = NULL ) goto failed ;
}
2005-12-09 07:54:30 +03:00
2005-12-09 09:22:09 +03:00
if ( ace - > object . object . flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT ) {
2005-12-09 08:21:47 +03:00
s_iobject = GUID_string ( tmp_ctx , & ace - > object . object . inherited_type . inherited_type ) ;
if ( s_iobject = = NULL ) goto failed ;
}
}
2005-12-09 07:54:30 +03:00
s_trustee = sddl_encode_sid ( tmp_ctx , & ace - > trustee , domain_sid ) ;
2005-12-09 08:21:47 +03:00
if ( s_trustee = = NULL ) goto failed ;
2005-12-09 07:54:30 +03:00
sddl = talloc_asprintf ( mem_ctx , " %s;%s;%s;%s;%s;%s " ,
s_type , s_flags , s_mask , s_object , s_iobject , s_trustee ) ;
failed :
talloc_free ( tmp_ctx ) ;
return sddl ;
}
/*
encode an ACL in SDDL format
*/
static char * sddl_encode_acl ( TALLOC_CTX * mem_ctx , const struct security_acl * acl ,
2005-12-10 02:43:02 +03:00
uint32_t flags , const struct dom_sid * domain_sid )
2005-12-09 07:54:30 +03:00
{
char * sddl ;
int i ;
/* add any ACL flags */
sddl = sddl_flags_to_string ( mem_ctx , acl_flags , flags , False ) ;
if ( sddl = = NULL ) goto failed ;
/* now the ACEs, encoded in braces */
for ( i = 0 ; i < acl - > num_aces ; i + + ) {
char * ace = sddl_encode_ace ( sddl , & acl - > aces [ i ] , domain_sid ) ;
if ( ace = = NULL ) goto failed ;
2007-09-15 03:21:00 +04:00
sddl = talloc_asprintf_append_buffer ( sddl , " (%s) " , ace ) ;
2005-12-09 07:54:30 +03:00
if ( sddl = = NULL ) goto failed ;
talloc_free ( ace ) ;
}
return sddl ;
failed :
talloc_free ( sddl ) ;
return NULL ;
}
/*
encode a security descriptor to SDDL format
*/
char * sddl_encode ( TALLOC_CTX * mem_ctx , const struct security_descriptor * sd ,
2005-12-10 02:43:02 +03:00
const struct dom_sid * domain_sid )
2005-12-09 07:54:30 +03:00
{
char * sddl ;
TALLOC_CTX * tmp_ctx ;
/* start with a blank string */
sddl = talloc_strdup ( mem_ctx , " " ) ;
if ( sddl = = NULL ) goto failed ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( sd - > owner_sid ! = NULL ) {
char * sid = sddl_encode_sid ( tmp_ctx , sd - > owner_sid , domain_sid ) ;
if ( sid = = NULL ) goto failed ;
2007-09-15 03:21:00 +04:00
sddl = talloc_asprintf_append_buffer ( sddl , " O:%s " , sid ) ;
2005-12-09 07:54:30 +03:00
if ( sddl = = NULL ) goto failed ;
}
if ( sd - > group_sid ! = NULL ) {
char * sid = sddl_encode_sid ( tmp_ctx , sd - > group_sid , domain_sid ) ;
if ( sid = = NULL ) goto failed ;
2007-09-15 03:21:00 +04:00
sddl = talloc_asprintf_append_buffer ( sddl , " G:%s " , sid ) ;
2005-12-09 07:54:30 +03:00
if ( sddl = = NULL ) goto failed ;
}
if ( ( sd - > type & SEC_DESC_DACL_PRESENT ) & & sd - > dacl ! = NULL ) {
char * acl = sddl_encode_acl ( tmp_ctx , sd - > dacl , sd - > type , domain_sid ) ;
if ( acl = = NULL ) goto failed ;
2007-09-15 03:21:00 +04:00
sddl = talloc_asprintf_append_buffer ( sddl , " D:%s " , acl ) ;
2005-12-09 07:54:30 +03:00
if ( sddl = = NULL ) goto failed ;
}
if ( ( sd - > type & SEC_DESC_SACL_PRESENT ) & & sd - > sacl ! = NULL ) {
char * acl = sddl_encode_acl ( tmp_ctx , sd - > sacl , sd - > type > > 1 , domain_sid ) ;
if ( acl = = NULL ) goto failed ;
2007-09-15 03:21:00 +04:00
sddl = talloc_asprintf_append_buffer ( sddl , " S:%s " , acl ) ;
2005-12-09 07:54:30 +03:00
if ( sddl = = NULL ) goto failed ;
}
talloc_free ( tmp_ctx ) ;
return sddl ;
failed :
talloc_free ( sddl ) ;
return NULL ;
}