summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/security/sddl.c87
1 files changed, 67 insertions, 20 deletions
diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c
index 17df393de4..1a15d8853a 100644
--- a/source4/libcli/security/sddl.c
+++ b/source4/libcli/security/sddl.c
@@ -35,6 +35,7 @@ struct flag_map {
static BOOL sddl_map_flags(const struct flag_map *map, const char *str,
uint32_t *flags, size_t *len)
{
+ const char *str0 = str;
if (len) *len = 0;
*flags = 0;
while (str[0] && isupper(str[0])) {
@@ -49,7 +50,7 @@ static BOOL sddl_map_flags(const struct flag_map *map, const char *str,
}
}
if (map[i].name == NULL) {
- DEBUG(2, ("Unknown flag - %s\n", str));
+ DEBUG(1, ("Unknown flag - %s in %s\n", str, str0));
return False;
}
}
@@ -62,15 +63,36 @@ static BOOL sddl_map_flags(const struct flag_map *map, const char *str,
static const struct {
const char *code;
const char *sid;
+ uint32_t rid;
} sid_codes[] = {
{ "AO", SID_BUILTIN_ACCOUNT_OPERATORS },
+ { "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 },
};
/*
decode a SID
It can either be a special 2 letter code, or in S-* format
*/
-static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp)
+static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp,
+ struct dom_sid *domain_sid)
{
const char *sddl = (*sddlp);
int i;
@@ -84,26 +106,31 @@ static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp)
/* now check for one of the special codes */
for (i=0;i<ARRAY_SIZE(sid_codes);i++) {
- if (strncmp(sid_codes[i].code, sddl, 2)) break;
+ if (strncmp(sid_codes[i].code, sddl, 2) == 0) break;
}
if (i == ARRAY_SIZE(sid_codes)) {
- DEBUG(2,("Unknown sddl sid code '%2.2s'\n", sddl));
+ DEBUG(1,("Unknown sddl sid code '%2.2s'\n", sddl));
return NULL;
}
(*sddlp) += 2;
+
+ if (sid_codes[i].sid == NULL) {
+ return dom_sid_add_rid(mem_ctx, domain_sid, sid_codes[i].rid);
+ }
+
return dom_sid_parse_talloc(mem_ctx, sid_codes[i].sid);
}
static const struct flag_map ace_types[] = {
- { "A", SEC_ACE_TYPE_ACCESS_ALLOWED },
- { "D", SEC_ACE_TYPE_ACCESS_DENIED },
{ "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 },
+ { "A", SEC_ACE_TYPE_ACCESS_ALLOWED },
+ { "D", SEC_ACE_TYPE_ACCESS_DENIED },
{ NULL, 0 }
};
@@ -132,6 +159,10 @@ static const struct flag_map ace_access_mask[] = {
{ "SD", SEC_STD_DELETE },
{ "DT", SEC_ADS_DELETE_TREE },
{ "SW", SEC_ADS_SELF_WRITE },
+ { "GA", SEC_GENERIC_ALL },
+ { "GR", SEC_GENERIC_READ },
+ { "GW", SEC_GENERIC_WRITE },
+ { "GX", SEC_GENERIC_EXECUTE },
{ NULL, 0 }
};
@@ -140,15 +171,17 @@ static const struct flag_map ace_access_mask[] = {
return True on success, False on failure
note that this routine modifies the string
*/
-static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str)
+static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str,
+ struct dom_sid *domain_sid)
{
- ZERO_STRUCTP(ace);
const char *tok[6];
const char *s;
int i;
uint32_t v;
struct dom_sid *sid;
+ ZERO_STRUCTP(ace);
+
/* parse out the 6 tokens */
tok[0] = str;
for (i=0;i<5;i++) {
@@ -183,19 +216,25 @@ static BOOL sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char
/* object */
if (tok[3][0] != 0) {
- /* TODO: add object parsing ... */
- return False;
+ NTSTATUS status = GUID_from_string(tok[3],
+ &ace->object.object.type.type);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
}
/* inherit object */
if (tok[4][0] != 0) {
- /* TODO: add object parsing ... */
- return False;
+ NTSTATUS status = GUID_from_string(tok[4],
+ &ace->object.object.inherited_type.inherited_type);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
}
/* trustee */
s = tok[5];
- sid = sddl_decode_sid(mem_ctx, &s);
+ sid = sddl_decode_sid(mem_ctx, &s, domain_sid);
if (sid == NULL) {
return False;
}
@@ -217,7 +256,8 @@ static const struct flag_map acl_flags[] = {
decode an ACL
*/
static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
- const char **sddlp, uint32_t *flags)
+ const char **sddlp, uint32_t *flags,
+ struct dom_sid *domain_sid)
{
const char *sddl = *sddlp;
struct security_acl *acl;
@@ -227,6 +267,11 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
if (acl == NULL) return NULL;
acl->revision = SECURITY_ACL_REVISION_NT4;
+ if (isupper(sddl[0]) && sddl[1] == ':') {
+ /* its an empty ACL */
+ return acl;
+ }
+
/* work out the ACL flags */
if (!sddl_map_flags(acl_flags, sddl, flags, &len)) {
talloc_free(acl);
@@ -248,7 +293,8 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
talloc_free(acl);
return NULL;
}
- if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces], astr)) {
+ if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces],
+ astr, domain_sid)) {
talloc_free(acl);
return NULL;
}
@@ -264,7 +310,8 @@ static struct security_acl *sddl_decode_acl(struct security_descriptor *sd,
/*
decode a security descriptor in SDDL format
*/
-struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl)
+struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
+ struct dom_sid *domain_sid)
{
struct security_descriptor *sd;
sd = talloc_zero(mem_ctx, struct security_descriptor);
@@ -281,13 +328,13 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl)
switch (c) {
case 'D':
if (sd->dacl != NULL) goto failed;
- sd->dacl = sddl_decode_acl(sd, &sddl, &flags);
+ sd->dacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid);
if (sd->dacl == NULL) goto failed;
sd->type |= flags | SEC_DESC_DACL_PRESENT;
break;
case 'S':
if (sd->sacl != NULL) goto failed;
- sd->sacl = sddl_decode_acl(sd, &sddl, &flags);
+ sd->sacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid);
if (sd->sacl == NULL) goto failed;
/* this relies on the SEC_DESC_SACL_* flags being
1 bit shifted from the SEC_DESC_DACL_* flags */
@@ -295,12 +342,12 @@ struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl)
break;
case 'O':
if (sd->owner_sid != NULL) goto failed;
- sd->owner_sid = sddl_decode_sid(sd, &sddl);
+ sd->owner_sid = sddl_decode_sid(sd, &sddl, domain_sid);
if (sd->owner_sid == NULL) goto failed;
break;
case 'G':
if (sd->group_sid != NULL) goto failed;
- sd->group_sid = sddl_decode_sid(sd, &sddl);
+ sd->group_sid = sddl_decode_sid(sd, &sddl, domain_sid);
if (sd->group_sid == NULL) goto failed;
break;
}