summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorGordon Ross <gwr@racktopsystems.com>2022-05-19 11:20:28 -0400
committerToomas Soome <tsoome@me.com>2022-10-12 22:41:25 +0300
commit53312454eef37dec3667cb0a7ab5b73cdda84862 (patch)
treead9feecd92e7c6f346a11962356e2c620e66b8b0 /usr/src/lib
parentde00d88e2173bf36f19125d522e5590c0f53cff0 (diff)
downloadillumos-joyent-53312454eef37dec3667cb0a7ab5b73cdda84862.tar.gz
15026 libsec mistakenly assumes a SID is a group SID
Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed-by: Jerry Jelinek <gjelinek@racktopsystems.com> Reviewed by: Matt Barden <mbarden@tintri.com> Approved by: Dan McDonald <danmcd@mnx.io>
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libsec/common/acl.y81
-rw-r--r--usr/src/lib/libsec/common/acl_lex.l91
-rw-r--r--usr/src/lib/libsec/common/aclutils.c52
-rw-r--r--usr/src/lib/libsec/common/aclutils.h3
4 files changed, 151 insertions, 76 deletions
diff --git a/usr/src/lib/libsec/common/acl.y b/usr/src/lib/libsec/common/acl.y
index fe3a141605..20299c5a29 100644
--- a/usr/src/lib/libsec/common/acl.y
+++ b/usr/src/lib/libsec/common/acl.y
@@ -21,6 +21,8 @@
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2022 RackTop Systems, Inc.
*/
#include <acl_common.h>
@@ -39,9 +41,9 @@ extern acl_t *yyacl;
acl_t *acl;
}
-
+%token BARE_SID_TOK
%token USER_TOK USER_SID_TOK GROUP_TOK GROUP_SID_TOK MASK_TOK OTHER_TOK
-%token OWNERAT_TOK GROUPAT_TOK EVERYONEAT_TOK DEFAULT_USER_TOK
+%token OWNERAT_TOK GROUPAT_TOK EVERYONEAT_TOK DEFAULT_USER_TOK
%token DEFAULT_GROUP_TOK DEFAULT_MASK_TOK DEFAULT_OTHER_TOK
%token COLON COMMA NL SLASH
%token <str> ID IDNAME PERM_TOK INHERIT_TOK SID
@@ -50,7 +52,7 @@ extern acl_t *yyacl;
%type <str> idname id
%type <acl_perm> perms perm aclent_perm ace_perms
%type <acl> acl_entry
-%type <ace> ace
+%type <ace> ace
%type <aclent> aclent
%type <val> iflags verbose_iflag compact_iflag access_type entry_type
@@ -58,25 +60,25 @@ extern acl_t *yyacl;
%%
-acl: acl_entry NL
- {
+acl: acl_entry NL
+ {
yyacl = $1;
return (0);
- }
+ }
/* This seems illegal, but the old aclfromtext() allows it */
- | acl_entry COMMA NL
+ | acl_entry COMMA NL
{
yyacl = $1;
return (0);
}
- | acl_entry COMMA acl
- {
+ | acl_entry COMMA acl
+ {
yyacl = $1;
return (0);
}
-
-acl_entry: ace
+
+acl_entry: ace
{
ace_t *acep;
@@ -86,7 +88,7 @@ acl_entry: ace
yycleanup();
return (EACL_MEM_ERROR);
}
- }
+ }
$$ = yyacl;
if ($$->acl_type == ACLENT_T) {
@@ -98,13 +100,13 @@ acl_entry: ace
yycleanup();
return (EACL_DIFF_TYPE);
}
-
+
$$->acl_aclp = realloc($$->acl_aclp,
($$->acl_entry_size * ($$->acl_cnt + 1)));
if ($$->acl_aclp == NULL) {
free (yyacl);
yycleanup();
- return (EACL_MEM_ERROR);
+ return (EACL_MEM_ERROR);
}
acep = $$->acl_aclp;
acep[$$->acl_cnt] = $1;
@@ -121,7 +123,7 @@ acl_entry: ace
yycleanup();
return (EACL_MEM_ERROR);
}
- }
+ }
$$ = yyacl;
if ($$->acl_type == ACE_T) {
@@ -139,7 +141,7 @@ acl_entry: ace
if ($$->acl_aclp == NULL) {
free (yyacl);
yycleanup();
- return (EACL_MEM_ERROR);
+ return (EACL_MEM_ERROR);
}
aclent = $$->acl_aclp;
aclent[$$->acl_cnt] = $1;
@@ -159,7 +161,7 @@ ace: entry_type idname ace_perms access_type
yycleanup();
return (EACL_INVALID_USER_GROUP);
}
-
+
$$.a_who = id;
$$.a_flags = ace_entry_type($1);
error = ace_perm_mask(&$3, &$$.a_access_mask);
@@ -196,7 +198,7 @@ ace: entry_type idname ace_perms access_type
}
$$.a_type = $4;
}
- | entry_type idname ace_perms iflags access_type
+ | entry_type idname ace_perms iflags access_type
{
int error;
uid_t id;
@@ -207,7 +209,7 @@ ace: entry_type idname ace_perms access_type
yycleanup();
return (EACL_INVALID_USER_GROUP);
}
-
+
$$.a_who = id;
$$.a_flags = ace_entry_type($1);
error = ace_perm_mask(&$3, &$$.a_access_mask);
@@ -248,7 +250,7 @@ ace: entry_type idname ace_perms access_type
$$.a_flags |= $4;
}
| entry_type ace_perms access_type
- {
+ {
int error;
$$.a_who = -1;
@@ -259,7 +261,7 @@ ace: entry_type idname ace_perms access_type
return (error);
}
$$.a_type = $3;
- }
+ }
| entry_type ace_perms access_type COLON id
{
yycleanup();
@@ -272,7 +274,7 @@ ace: entry_type idname ace_perms access_type
return (EACL_ENTRY_ERROR);
}
- | entry_type ace_perms iflags access_type
+ | entry_type ace_perms iflags access_type
{
int error;
@@ -352,7 +354,7 @@ aclent: entry_type idname aclent_perm /* user or group */
}
}
| entry_type COLON aclent_perm COLON id
- {
+ {
yycleanup();
if (yyinteractive) {
acl_error(dgettext(TEXT_DOMAIN,
@@ -361,8 +363,8 @@ aclent: entry_type idname aclent_perm /* user or group */
}
return (EACL_ENTRY_ERROR);
}
- | entry_type idname aclent_perm COLON id /* user or group */
- {
+ | entry_type idname aclent_perm COLON id /* user or group */
+ {
int error;
uid_t id;
@@ -383,7 +385,7 @@ aclent: entry_type idname aclent_perm /* user or group */
error = get_id($1, $2, &id);
if (error) {
$$.a_id = get_id_nofail($1, $5);
- } else
+ } else
$$.a_id = id;
error = aclent_entry_type($1, 0, &$$.a_type);
@@ -478,14 +480,14 @@ verbose_iflag: ACE_INHERIT {$$ |= $1;}
yycleanup();
return ($3);
}
-
+
aclent_perm: PERM_TOK
{
$$.perm_style = PERM_TYPE_UNKNOWN;
$$.perm_str = $1;
$$.perm_val = 0;
}
- | PERM_TOK ERROR
+ | PERM_TOK ERROR
{
acl_error(dgettext(TEXT_DOMAIN,
"ACL entry permissions are incorrectly specified.\n"));
@@ -493,7 +495,7 @@ aclent_perm: PERM_TOK
return ($2);
}
-access_type: ACCESS_TYPE {$$ = $1;}
+access_type: ACCESS_TYPE {$$ = $1;}
| ERROR
{
yycleanup();
@@ -502,11 +504,11 @@ access_type: ACCESS_TYPE {$$ = $1;}
id: ID {$$ = $1;}
| SID {$$ = $1;}
- | COLON
+ | COLON
{
acl_error(dgettext(TEXT_DOMAIN,
"Invalid uid/gid specified.\nThe field"
- " should be a numeric value.\n"));
+ " should be a numeric value.\n"));
yycleanup();
return (EACL_UNKNOWN_DATA);
}
@@ -525,10 +527,10 @@ ace_perms: perm {$$ = $1;}
}
perm: perms COLON {$$ = $1;}
- | COLON {$$.perm_style = PERM_TYPE_EMPTY;}
+ | COLON {$$.perm_style = PERM_TYPE_EMPTY;}
-perms: ACE_PERM
- {
+perms: ACE_PERM
+ {
$$.perm_style = PERM_TYPE_ACE;
$$.perm_val |= $1;
}
@@ -552,7 +554,7 @@ perms: ACE_PERM
yycleanup();
return ($3);
}
-
+
idname: IDNAME {$$ = $1;}
@@ -579,7 +581,7 @@ bad_entry_type(int toketype, char *str)
acl_error(dgettext(TEXT_DOMAIN,
"Invalid group %s specified.\n"), str);
break;
-
+
case USER_SID_TOK:
acl_error(dgettext(TEXT_DOMAIN,
"Invalid user SID %s specified.\n"), str);
@@ -588,6 +590,11 @@ bad_entry_type(int toketype, char *str)
case GROUP_SID_TOK:
acl_error(dgettext(TEXT_DOMAIN,
"Invalid group SID %s specified.\n"), str);
- }
+ break;
+ case BARE_SID_TOK:
+ acl_error(dgettext(TEXT_DOMAIN,
+ "Invalid SID %s specified.\n"), str);
+ break;
+ }
}
diff --git a/usr/src/lib/libsec/common/acl_lex.l b/usr/src/lib/libsec/common/acl_lex.l
index ab61d5bf0e..20c9be5b53 100644
--- a/usr/src/lib/libsec/common/acl_lex.l
+++ b/usr/src/lib/libsec/common/acl_lex.l
@@ -20,6 +20,8 @@
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2022 RackTop Systems, Inc.
*/
%{
@@ -41,7 +43,7 @@ int grab_string(char *terminators);
static int input();
static void unput(int);
-int
+int
yyerror(const char *s)
{
return (0);
@@ -127,7 +129,7 @@ INHERIT_STR [fdinFSI-]+
}
<TS>sid: {
BEGIN NS;
- yylval.val = GROUP_SID_TOK;
+ yylval.val = BARE_SID_TOK;
return (ENTRY_TYPE);
}
<TS>mask: {
@@ -150,7 +152,7 @@ INHERIT_STR [fdinFSI-]+
yylval.val = OTHER_TOK;
return (ENTRY_TYPE);
}
-<TS>defaultuser: {
+<TS>defaultuser: {
BEGIN NS;
yylval.val = DEFAULT_USER_TOK;
return (ENTRY_TYPE);
@@ -160,7 +162,7 @@ INHERIT_STR [fdinFSI-]+
yylval.val = DEFAULT_USER_TOK;
return (ENTRY_TYPE);
}
-<TS>defaultgroup: {
+<TS>defaultgroup: {
BEGIN NS;
yylval.val = DEFAULT_GROUP_TOK;
return (ENTRY_TYPE);
@@ -170,12 +172,12 @@ INHERIT_STR [fdinFSI-]+
yylval.val = DEFAULT_GROUP_TOK;
return (ENTRY_TYPE);
}
-<TS>defaultother: {
+<TS>defaultother: {
BEGIN PS;
yylval.val = DEFAULT_OTHER_TOK;
return (ENTRY_TYPE);
}
-<TS>defaultother:: {
+<TS>defaultother:: {
BEGIN PS;
yylval.val = DEFAULT_OTHER_TOK;
return (ENTRY_TYPE);
@@ -185,12 +187,12 @@ INHERIT_STR [fdinFSI-]+
yylval.val = DEFAULT_OTHER_TOK;
return (ENTRY_TYPE);
}
-<TS>defaultmask: {
+<TS>defaultmask: {
BEGIN PS;
yylval.val = DEFAULT_MASK_TOK;
return (ENTRY_TYPE);
}
-<TS>defaultmask:: {
+<TS>defaultmask:: {
BEGIN PS;
yylval.val = DEFAULT_MASK_TOK;
return (ENTRY_TYPE);
@@ -242,7 +244,7 @@ INHERIT_STR [fdinFSI-]+
}
<NS>. {
int error;
-
+
error = grab_string(":,\n");
if (error != 0) {
acl_error(dgettext(TEXT_DOMAIN,
@@ -265,7 +267,7 @@ INHERIT_STR [fdinFSI-]+
}
<PS>list_directory/[:/,] {
yylval.val = ACE_LIST_DIRECTORY;
- return (ACE_PERM);
+ return (ACE_PERM);
}
<PS>write_data/[:/,] {
yylval.val = ACE_WRITE_DATA;
@@ -305,7 +307,7 @@ INHERIT_STR [fdinFSI-]+
}
<PS>write_attributes/[:/,] {
yylval.val = ACE_WRITE_ATTRIBUTES;
- return (ACE_PERM);
+ return (ACE_PERM);
}
<PS>delete/[:/,] {
yylval.val = ACE_DELETE;
@@ -362,8 +364,8 @@ INHERIT_STR [fdinFSI-]+
BEGIN US;
else if (c != ':')
BEGIN ES;
-
- return (PERM_TOK);
+
+ return (PERM_TOK);
}
<PS>"/:" {
acl_error(dgettext(TEXT_DOMAIN,
@@ -402,7 +404,7 @@ INHERIT_STR [fdinFSI-]+
yylval.val = EACL_PERM_MASK_ERROR;
return (ERROR);
}
-<PS>. {
+<PS>. {
if (grab_string("/:,\n") != 0) {
acl_error(dgettext(TEXT_DOMAIN,
"Failed to retrieve"
@@ -412,7 +414,7 @@ INHERIT_STR [fdinFSI-]+
}
acl_error(dgettext(TEXT_DOMAIN,
"Invalid permission(s) '%s' "
- "specified.\n"), yylval.str);
+ "specified.\n"), yylval.str);
free(yylval.str);
yylval.val = EACL_PERM_MASK_ERROR;
return (ERROR);
@@ -420,7 +422,7 @@ INHERIT_STR [fdinFSI-]+
<AS>allow/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -433,7 +435,7 @@ INHERIT_STR [fdinFSI-]+
<AS>deny/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -446,7 +448,7 @@ INHERIT_STR [fdinFSI-]+
}
<AS>audit/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -459,7 +461,7 @@ INHERIT_STR [fdinFSI-]+
}
<AS>alarm/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -471,7 +473,7 @@ INHERIT_STR [fdinFSI-]+
return (ACCESS_TYPE);
}
<AS>: {
-
+
acl_error(dgettext(TEXT_DOMAIN,
"Invalid Access type "
"specified.\nThe field is blank, when"
@@ -514,7 +516,7 @@ INHERIT_STR [fdinFSI-]+
<AIS>allow/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -527,7 +529,7 @@ INHERIT_STR [fdinFSI-]+
<AIS>deny/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -540,7 +542,7 @@ INHERIT_STR [fdinFSI-]+
}
<AIS>audit/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -554,7 +556,7 @@ INHERIT_STR [fdinFSI-]+
<AIS>alarm/[:,\n] {
int c;
-
+
c = input();
unput(c);
if (c == ',' || c == '\n')
@@ -648,8 +650,8 @@ INHERIT_STR [fdinFSI-]+
acl_error(
dgettext(TEXT_DOMAIN,
"Invalid inheritance or"
- " access type '%s' specified.\n"),
- yylval.str);
+ " access type '%s' specified.\n"),
+ yylval.str);
} else {
acl_error(
dgettext(TEXT_DOMAIN,
@@ -697,17 +699,17 @@ INHERIT_STR [fdinFSI-]+
yylval.val = EACL_ENTRY_ERROR;
return (ERROR);
}
-<US>. {
+<US>. {
if (grab_string(",\n") != 0) {
acl_error(dgettext(TEXT_DOMAIN,
"Failed to retrieve"
- " error string.\n"));
+ " error string.\n"));
yylval.val = EACL_MEM_ERROR;
return (ERROR);
}
acl_error(
dgettext(TEXT_DOMAIN,
- "Invalid data ':%s' specified"
+ "Invalid data ':%s' specified"
" on end of ACL.\n"), yylval.str);
free(yylval.str);
yylval.val = EACL_ENTRY_ERROR;
@@ -730,14 +732,14 @@ INHERIT_STR [fdinFSI-]+
acl_error(
dgettext(TEXT_DOMAIN,
"Failed to retrieve error"
- " string.\n"));
+ " string.\n"));
yylval.val = EACL_MEM_ERROR;
return (ERROR);
}
acl_error(
dgettext(TEXT_DOMAIN,
"Unrecognized data '%s' found"
- " in ACL specification.\n"), yylval.str);
+ " in ACL specification.\n"), yylval.str);
free(yylval.str);
yylval.val = EACL_UNKNOWN_DATA;
return (ERROR);
@@ -766,7 +768,7 @@ grab_string(char *terminators)
int alloced;
int error = 0;
char *ptr;
-
+
cnt = strlen(yytext);
yylval.str = calloc(cnt + 1, sizeof (char));
if (yylval.str == NULL) {
@@ -777,7 +779,7 @@ grab_string(char *terminators)
do {
c = input();
- if (c == EOF)
+ if (c == EOF)
break;
for (ptr = terminators; *ptr; ptr++) {
@@ -786,10 +788,10 @@ grab_string(char *terminators)
break;
}
}
-
+
if (done)
break;
-
+
if (cnt + 1 >= alloced) {
yylval.str = realloc(yylval.str,
alloced + 80);
@@ -817,7 +819,7 @@ input(void)
return (EOF);
}
- return (c);
+ return (c);
}
static void
@@ -832,6 +834,8 @@ unput(int c)
}
}
+static int sid_isuser = 0;
+
/*
* return ACE entry type
*/
@@ -840,6 +844,12 @@ ace_entry_type(int type)
{
int ret = -1;
switch (type) {
+ case BARE_SID_TOK:
+ if (sid_isuser == 0)
+ ret = ACE_IDENTIFIER_GROUP;
+ else
+ ret = 0;
+ break;
case USER_TOK:
case USER_SID_TOK:
ret = 0;
@@ -942,7 +952,7 @@ get_id(int entry_type, char *name, uid_t *id)
if (pw) {
*id = pw->pw_uid;
error = 0;
- }
+ }
break;
case GROUP_TOK:
@@ -953,7 +963,7 @@ get_id(int entry_type, char *name, uid_t *id)
if (gr) {
*id = gr->gr_gid;
error = 0;
- }
+ }
break;
case USER_SID_TOK:
if (sid_to_id(name, B_TRUE, id))
@@ -964,6 +974,11 @@ get_id(int entry_type, char *name, uid_t *id)
if (sid_to_id(name, B_FALSE, id))
error = EACL_INVALID_USER_GROUP;
break;
+
+ case BARE_SID_TOK:
+ if (sid_to_xid(name, &sid_isuser, id))
+ error = EACL_INVALID_USER_GROUP;
+ break;
}
return (error);
diff --git a/usr/src/lib/libsec/common/aclutils.c b/usr/src/lib/libsec/common/aclutils.c
index f104687b44..ea91ddb96e 100644
--- a/usr/src/lib/libsec/common/aclutils.c
+++ b/usr/src/lib/libsec/common/aclutils.c
@@ -21,6 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ *
+ * Copyright 2022 RackTop Systems, Inc.
*/
@@ -53,7 +55,7 @@ typedef union {
/*
* Determine whether a file has a trivial ACL
- * returns: 0 = trivial
+ * returns: 0 = trivial
* 1 = nontrivial
* <0 some other system failure, such as ENOENT or EPERM
*/
@@ -806,3 +808,51 @@ sid_to_id(char *sid, boolean_t user, uid_t *id)
return (error);
}
+
+/*
+ * Variant of sid_to_id() called when we don't know whether the SID
+ * is a user or group. 2nd arg gets the type (0:group, 1:user)
+ * Returns zero for success, 1 for errors.
+ */
+int
+sid_to_xid(char *sid, int *is_user, uid_t *id)
+{
+ idmap_get_handle_t *get_hdl = NULL;
+ char *rid_start = NULL;
+ char *end;
+ idmap_stat status;
+ idmap_rid_t rid;
+ int error = 1;
+
+ if ((strchr(sid, '@')) != NULL)
+ return (1);
+
+ if ((rid_start = strrchr(sid, '-')) == NULL)
+ return (1);
+ *rid_start++ = '\0';
+ errno = 0;
+ rid = strtoul(rid_start--, &end, 10);
+ if (errno == 0 && *end == '\0') {
+ if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) {
+ error = idmap_get_pidbysid(get_hdl,
+ sid, rid, IDMAP_REQ_FLG_USE_CACHE,
+ id, is_user, &status);
+ if (error == IDMAP_SUCCESS) {
+ error = idmap_get_mappings(get_hdl);
+ if (error == IDMAP_SUCCESS &&
+ status != IDMAP_SUCCESS)
+ error = 1;
+ else
+ error = 0;
+ }
+ } else {
+ error = 1;
+ }
+ if (get_hdl)
+ idmap_get_destroy(get_hdl);
+ }
+
+ *rid_start = '-'; /* putback character removed earlier */
+
+ return (error);
+}
diff --git a/usr/src/lib/libsec/common/aclutils.h b/usr/src/lib/libsec/common/aclutils.h
index ff040973e9..e3e6d130f6 100644
--- a/usr/src/lib/libsec/common/aclutils.h
+++ b/usr/src/lib/libsec/common/aclutils.h
@@ -21,6 +21,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2022 RackTop Systems, Inc.
*/
#ifndef _ACLUTILS_H
@@ -141,6 +143,7 @@ extern void yyreset(void);
extern void yycleanup(void);
extern acl_t *acl_to_aclp(enum acl_type, void *, int);
extern int sid_to_id(char *, boolean_t, uid_t *);
+extern int sid_to_xid(char *, int *, uid_t *);
#ifdef __cplusplus
}