diff options
author | Gordon Ross <gwr@racktopsystems.com> | 2022-05-19 11:20:28 -0400 |
---|---|---|
committer | Toomas Soome <tsoome@me.com> | 2022-10-12 22:41:25 +0300 |
commit | 53312454eef37dec3667cb0a7ab5b73cdda84862 (patch) | |
tree | ad9feecd92e7c6f346a11962356e2c620e66b8b0 /usr/src/lib | |
parent | de00d88e2173bf36f19125d522e5590c0f53cff0 (diff) | |
download | illumos-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.y | 81 | ||||
-rw-r--r-- | usr/src/lib/libsec/common/acl_lex.l | 91 | ||||
-rw-r--r-- | usr/src/lib/libsec/common/aclutils.c | 52 | ||||
-rw-r--r-- | usr/src/lib/libsec/common/aclutils.h | 3 |
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 } |