mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
sharesec: Use common parse_ace function
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237 Signed-off-by: Christof Schmitt <cs@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
cea5045412
commit
e4f2fa2c67
@ -41,179 +41,6 @@ enum acl_mode { SMB_ACL_DELETE,
|
||||
SMB_ACL_VIEW,
|
||||
SMB_ACL_VIEW_ALL };
|
||||
|
||||
struct perm_value {
|
||||
const char *perm;
|
||||
uint32 mask;
|
||||
};
|
||||
|
||||
/* These values discovered by inspection */
|
||||
|
||||
static const struct perm_value special_values[] = {
|
||||
{ "R", SEC_RIGHTS_FILE_READ },
|
||||
{ "W", SEC_RIGHTS_FILE_WRITE },
|
||||
{ "X", SEC_RIGHTS_FILE_EXECUTE },
|
||||
{ "D", SEC_STD_DELETE },
|
||||
{ "P", SEC_STD_WRITE_DAC },
|
||||
{ "O", SEC_STD_WRITE_OWNER },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
#define SEC_RIGHTS_DIR_CHANGE ( SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
|
||||
SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE )
|
||||
|
||||
static const struct perm_value standard_values[] = {
|
||||
{ "READ", SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
|
||||
{ "CHANGE", SEC_RIGHTS_DIR_CHANGE },
|
||||
{ "FULL", SEC_RIGHTS_DIR_ALL },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
/********************************************************************
|
||||
parse an ACE in the same format as print_ace()
|
||||
********************************************************************/
|
||||
|
||||
static bool parse_ace(struct security_ace *ace, const char *orig_str)
|
||||
{
|
||||
char *p;
|
||||
const char *cp;
|
||||
char *tok;
|
||||
unsigned int atype = 0;
|
||||
unsigned int aflags = 0;
|
||||
unsigned int amask = 0;
|
||||
struct dom_sid sid;
|
||||
uint32_t mask;
|
||||
const struct perm_value *v;
|
||||
char *str = SMB_STRDUP(orig_str);
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
|
||||
if (!str) {
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
ZERO_STRUCTP(ace);
|
||||
p = strchr_m(str,':');
|
||||
if (!p) {
|
||||
fprintf(stderr, "ACE '%s': missing ':'.\n", orig_str);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
*p = '\0';
|
||||
p++;
|
||||
/* Try to parse numeric form */
|
||||
|
||||
if (sscanf(p, "%u/%u/%u", &atype, &aflags, &amask) == 3 &&
|
||||
string_to_sid(&sid, str)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Try to parse text form */
|
||||
|
||||
if (!string_to_sid(&sid, str)) {
|
||||
fprintf(stderr, "ACE '%s': failed to convert '%s' to SID\n",
|
||||
orig_str, str);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
cp = p;
|
||||
if (!next_token_talloc(frame, &cp, &tok, "/")) {
|
||||
fprintf(stderr, "ACE '%s': failed to find '/' character.\n",
|
||||
orig_str);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
|
||||
atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
|
||||
} else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
|
||||
atype = SEC_ACE_TYPE_ACCESS_DENIED;
|
||||
} else {
|
||||
fprintf(stderr, "ACE '%s': missing 'ALLOWED' or 'DENIED' "
|
||||
"entry at '%s'\n", orig_str, tok);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Only numeric form accepted for flags at present */
|
||||
/* no flags on share permissions */
|
||||
|
||||
if (!(next_token_talloc(frame, &cp, &tok, "/") &&
|
||||
sscanf(tok, "%u", &aflags) && aflags == 0)) {
|
||||
fprintf(stderr, "ACE '%s': bad integer flags entry at '%s'\n",
|
||||
orig_str, tok);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!next_token_talloc(frame, &cp, &tok, "/")) {
|
||||
fprintf(stderr, "ACE '%s': missing / at '%s'\n",
|
||||
orig_str, tok);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (strncmp(tok, "0x", 2) == 0) {
|
||||
if (sscanf(tok, "%u", &amask) != 1) {
|
||||
fprintf(stderr, "ACE '%s': bad hex number at '%s'\n",
|
||||
orig_str, tok);
|
||||
TALLOC_FREE(frame);
|
||||
SAFE_FREE(str);
|
||||
return False;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (v = standard_values; v->perm; v++) {
|
||||
if (strcmp(tok, v->perm) == 0) {
|
||||
amask = v->mask;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
p = tok;
|
||||
|
||||
while(*p) {
|
||||
bool found = False;
|
||||
|
||||
for (v = special_values; v->perm; v++) {
|
||||
if (v->perm[0] == *p) {
|
||||
amask |= v->mask;
|
||||
found = True;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
fprintf(stderr, "ACE '%s': bad permission value at "
|
||||
"'%s'\n", orig_str, p);
|
||||
TALLOC_FREE(frame);
|
||||
SAFE_FREE(str);
|
||||
return False;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p) {
|
||||
TALLOC_FREE(frame);
|
||||
SAFE_FREE(str);
|
||||
return False;
|
||||
}
|
||||
|
||||
done:
|
||||
mask = amask;
|
||||
init_sec_ace(ace, &sid, atype, mask, aflags);
|
||||
SAFE_FREE(str);
|
||||
TALLOC_FREE(frame);
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
@ -242,7 +69,7 @@ static struct security_descriptor* parse_acl_string(TALLOC_CTX *mem_ctx, const c
|
||||
strncpy( acl_string, pacl, MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1) );
|
||||
acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0';
|
||||
|
||||
if ( !parse_ace( &ace[i], acl_string ) )
|
||||
if ( !parse_ace(NULL, &ace[i], acl_string ) )
|
||||
return NULL;
|
||||
|
||||
pacl = end_acl;
|
||||
|
Loading…
x
Reference in New Issue
Block a user