Print this page
NEX-1767 ls is unable to display SIDs
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
SUP-795 IDMAP: idmap_getwinnamebyuid() and idmap_getwinnamebygid() fails for empty domains
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*LINTLIBRARY*/
  27 
  28 #include <grp.h>
  29 #include <pwd.h>
  30 #include <string.h>
  31 #include <limits.h>
  32 #include <stdlib.h>
  33 #include <errno.h>
  34 #include <sys/param.h>
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <sys/acl.h>
  38 #include <aclutils.h>
  39 #include <idmap.h>
  40 #include <synch.h>
  41 
  42 #define ID_STR_MAX      20      /* digits in LONG_MAX */
  43 


 155                             idmap_get_mappings(get_hdl) == 0) {
 156                                 if (status == IDMAP_SUCCESS) {
 157                                         len = snprintf(NULL, 0,
 158                                             "%s-%d", domain, rid);
 159                                         if (*sidp = malloc(len + 1)) {
 160                                                 (void) snprintf(*sidp, len + 1,
 161                                                     "%s-%d", domain, rid);
 162                                         }
 163                                 }
 164                         }
 165                 }
 166                 if (get_hdl)
 167                         idmap_get_destroy(get_hdl);
 168         }
 169 
 170         free(domain);
 171 
 172         return (*sidp ? 0 : 1);
 173 }
 174 









 175 static void
 176 aclent_printacl(acl_t *aclp)
 177 {
 178         aclent_t *tp;
 179         int aclcnt;
 180         int mask;
 181         int slot = 0;
 182         char perm[4];
 183         char uidp[ID_STR_MAX];
 184         char gidp[ID_STR_MAX];
 185 
 186         /* display ACL: assume it is sorted. */
 187         aclcnt = aclp->acl_cnt;
 188         for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
 189                 if (tp->a_type == CLASS_OBJ)
 190                         mask = tp->a_perm;
 191         }
 192         aclcnt = aclp->acl_cnt;
 193         for (tp = aclp->acl_aclp; aclcnt--; tp++) {
 194                 (void) printf("     %d:", slot++);


 399                                 break;
 400                         if (error = getsidname(acep->a_who, B_FALSE,
 401                             &sidp, flags & ACL_NORESOLVE))
 402                                 break;
 403                         error = str_append(dynstr, sidp);
 404                 } else {
 405                         if (error = str_append(dynstr, GROUP_TXT))
 406                                 break;
 407                         error = str_append(dynstr, prgname(acep->a_who, idp,
 408                             sizeof (idp), flags & ACL_NORESOLVE));
 409                 }
 410                 if (error == 0)
 411                         error = str_append(dynstr, ":");
 412                 break;
 413 
 414         case ACE_EVERYONE:
 415                 error = str_append(dynstr, EVERYONEAT_TXT);
 416                 break;
 417 
 418         case 0:
 419                 if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {

 420                         if (error = str_append(dynstr, USERSID_TXT))
 421                                 break;
 422                         if (error = getsidname(acep->a_who, B_TRUE,
 423                             &sidp, flags & ACL_NORESOLVE))
 424                                 break;
 425                         error = str_append(dynstr, sidp);
 426                 } else {

 427                         if (error = str_append(dynstr, USER_TXT))
 428                                 break;
 429                         error = str_append(dynstr, pruname(acep->a_who, idp,
 430                             sizeof (idp), flags & ACL_NORESOLVE));
 431                 }
 432                 if (error == 0)
 433                         error = str_append(dynstr, ":");
 434                 break;
 435         default:
 436                 error = 0;
 437                 break;
 438         }
 439 
 440         if (sidp)
 441                 free(sidp);
 442         return (error);
 443 }
 444 
 445 /*
 446  * compute string of permissions, such as read_data/write_data or


1011                 }
1012                 yyacl = NULL;
1013         }
1014         (void) mutex_unlock(&yymutex);
1015 
1016         return (error);
1017 }
1018 
1019 int
1020 acl_parse(const char *acltextp, acl_t **aclp)
1021 {
1022         int error;
1023 
1024         yyinteractive = 1;
1025         error = acl_fromtext(acltextp, aclp);
1026         yyinteractive = 0;
1027         return (error);
1028 }
1029 
1030 static void
1031 ace_compact_printacl(acl_t *aclp)
1032 {
1033         int cnt;
1034         ace_t *acep;
1035         dynaclstr_t *dstr;
1036         int len;
1037 
1038         if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
1039                 return;
1040         dstr->d_bufsize = ACE_ENTRY_SIZE;
1041         if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
1042                 free(dstr);
1043                 return;
1044         }
1045         *dstr->d_aclexport = '\0';
1046 
1047         dstr->d_pos = 0;
1048         for (cnt = 0, acep = aclp->acl_aclp;
1049             cnt != aclp->acl_cnt; cnt++, acep++) {
1050                 dstr->d_aclexport[0] = '\0';
1051                 dstr->d_pos = 0;
1052 
1053                 if (ace_type_txt(dstr, acep, 0))
1054                         break;
1055                 len = strlen(&dstr->d_aclexport[0]);
1056                 if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
1057                     aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
1058                         break;
1059                 if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
1060                         break;
1061                 if (ace_access_txt(dstr, acep->a_type) == -1)
1062                         break;
1063                 (void) printf("    %20.*s%s\n", len, dstr->d_aclexport,
1064                     &dstr->d_aclexport[len]);
1065         }
1066 
1067         if (dstr->d_aclexport)
1068                 free(dstr->d_aclexport);
1069         free(dstr);
1070 }
1071 
1072 static void
1073 ace_printacl(acl_t *aclp, int cols, int compact)
1074 {
1075         int  slot = 0;
1076         char *token;
1077         char *acltext;
1078 
1079         if (compact) {
1080                 ace_compact_printacl(aclp);
1081                 return;
1082         }
1083 
1084         acltext = acl_totext(aclp, 0);
1085 
1086         if (acltext == NULL)
1087                 return;
1088 
1089         token = strtok(acltext, ",");
1090         if (token == NULL) {
1091                 free(acltext);
1092                 return;
1093         }
1094 
1095         do {
1096                 (void) printf("     %d:", slot++);
1097                 split_line(token, cols - 5);
1098         } while (token = strtok(NULL, ","));
1099         free(acltext);
1100 }
1101 
1102 /*
1103  * pretty print an ACL.
1104  * For aclent_t ACL's the format is
1105  * similar to the old format used by getfacl,
1106  * with the addition of adding a "slot" number
1107  * before each entry.
1108  *
1109  * for ace_t ACL's the cols variable will break up
1110  * the long lines into multiple lines and will also
1111  * print a "slot" number.
1112  */
1113 void
1114 acl_printacl(acl_t *aclp, int cols, int compact)
1115 {
1116 
1117         switch (aclp->acl_type) {
1118         case ACLENT_T:
1119                 aclent_printacl(aclp);
1120                 break;
1121         case ACE_T:
1122                 ace_printacl(aclp, cols, compact);
1123                 break;
1124         }
1125 }
1126 
1127 typedef struct value_table {
1128         char            p_letter; /* perm letter such as 'r' */
1129         uint32_t        p_value; /* value for perm when pletter found */
1130 } value_table_t;
1131 
1132 /*
1133  * The permission tables are laid out in positional order
1134  * a '-' character will indicate a permission at a given
1135  * position is not specified.  The '-' is not part of the
1136  * table, but will be checked for in the permission computation
1137  * routine.
1138  */
1139 value_table_t ace_perm_table[] = {
1140         { 'r', ACE_READ_DATA},
1141         { 'w', ACE_WRITE_DATA},
1142         { 'x', ACE_EXECUTE},




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*LINTLIBRARY*/
  27 
  28 #include <grp.h>
  29 #include <pwd.h>
  30 #include <string.h>
  31 #include <limits.h>
  32 #include <stdlib.h>
  33 #include <errno.h>
  34 #include <sys/param.h>
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <sys/acl.h>
  38 #include <aclutils.h>
  39 #include <idmap.h>
  40 #include <synch.h>
  41 
  42 #define ID_STR_MAX      20      /* digits in LONG_MAX */
  43 


 155                             idmap_get_mappings(get_hdl) == 0) {
 156                                 if (status == IDMAP_SUCCESS) {
 157                                         len = snprintf(NULL, 0,
 158                                             "%s-%d", domain, rid);
 159                                         if (*sidp = malloc(len + 1)) {
 160                                                 (void) snprintf(*sidp, len + 1,
 161                                                     "%s-%d", domain, rid);
 162                                         }
 163                                 }
 164                         }
 165                 }
 166                 if (get_hdl)
 167                         idmap_get_destroy(get_hdl);
 168         }
 169 
 170         free(domain);
 171 
 172         return (*sidp ? 0 : 1);
 173 }
 174 
 175 /*
 176  * sid_string_by_id() is an exposed interface via -lsec
 177  */
 178 int
 179 sid_string_by_id(uid_t who, boolean_t user, char **sidp, boolean_t noresolve)
 180 {
 181         return (getsidname(who, user, sidp, noresolve));
 182 }
 183 
 184 static void
 185 aclent_printacl(acl_t *aclp)
 186 {
 187         aclent_t *tp;
 188         int aclcnt;
 189         int mask;
 190         int slot = 0;
 191         char perm[4];
 192         char uidp[ID_STR_MAX];
 193         char gidp[ID_STR_MAX];
 194 
 195         /* display ACL: assume it is sorted. */
 196         aclcnt = aclp->acl_cnt;
 197         for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
 198                 if (tp->a_type == CLASS_OBJ)
 199                         mask = tp->a_perm;
 200         }
 201         aclcnt = aclp->acl_cnt;
 202         for (tp = aclp->acl_aclp; aclcnt--; tp++) {
 203                 (void) printf("     %d:", slot++);


 408                                 break;
 409                         if (error = getsidname(acep->a_who, B_FALSE,
 410                             &sidp, flags & ACL_NORESOLVE))
 411                                 break;
 412                         error = str_append(dynstr, sidp);
 413                 } else {
 414                         if (error = str_append(dynstr, GROUP_TXT))
 415                                 break;
 416                         error = str_append(dynstr, prgname(acep->a_who, idp,
 417                             sizeof (idp), flags & ACL_NORESOLVE));
 418                 }
 419                 if (error == 0)
 420                         error = str_append(dynstr, ":");
 421                 break;
 422 
 423         case ACE_EVERYONE:
 424                 error = str_append(dynstr, EVERYONEAT_TXT);
 425                 break;
 426 
 427         case 0:
 428                 if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID &&
 429                     (flags & ACL_EPHEMERAL) == 0) {
 430                         if (error = str_append(dynstr, USERSID_TXT))
 431                                 break;
 432                         if (error = getsidname(acep->a_who, B_TRUE,
 433                             &sidp, flags & ACL_NORESOLVE))
 434                                 break;
 435                         error = str_append(dynstr, sidp);
 436                 } else {
 437                         flags &= ~ACL_NORESOLVE;
 438                         if (error = str_append(dynstr, USER_TXT))
 439                                 break;
 440                         error = str_append(dynstr, pruname(acep->a_who, idp,
 441                             sizeof (idp), flags & ACL_NORESOLVE));
 442                 }
 443                 if (error == 0)
 444                         error = str_append(dynstr, ":");
 445                 break;
 446         default:
 447                 error = 0;
 448                 break;
 449         }
 450 
 451         if (sidp)
 452                 free(sidp);
 453         return (error);
 454 }
 455 
 456 /*
 457  * compute string of permissions, such as read_data/write_data or


1022                 }
1023                 yyacl = NULL;
1024         }
1025         (void) mutex_unlock(&yymutex);
1026 
1027         return (error);
1028 }
1029 
1030 int
1031 acl_parse(const char *acltextp, acl_t **aclp)
1032 {
1033         int error;
1034 
1035         yyinteractive = 1;
1036         error = acl_fromtext(acltextp, aclp);
1037         yyinteractive = 0;
1038         return (error);
1039 }
1040 
1041 static void
1042 ace_compact_printacl(acl_t *aclp, int flgs)
1043 {
1044         int cnt;
1045         ace_t *acep;
1046         dynaclstr_t *dstr;
1047         int len;
1048 
1049         if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
1050                 return;
1051         dstr->d_bufsize = ACE_ENTRY_SIZE;
1052         if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
1053                 free(dstr);
1054                 return;
1055         }
1056         *dstr->d_aclexport = '\0';
1057 
1058         dstr->d_pos = 0;
1059         for (cnt = 0, acep = aclp->acl_aclp;
1060             cnt != aclp->acl_cnt; cnt++, acep++) {
1061                 dstr->d_aclexport[0] = '\0';
1062                 dstr->d_pos = 0;
1063 
1064                 if (ace_type_txt(dstr, acep, flgs))
1065                         break;
1066                 len = strlen(&dstr->d_aclexport[0]);
1067                 if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
1068                     aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
1069                         break;
1070                 if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
1071                         break;
1072                 if (ace_access_txt(dstr, acep->a_type) == -1)
1073                         break;
1074                 (void) printf("    %20.*s%s\n", len, dstr->d_aclexport,
1075                     &dstr->d_aclexport[len]);
1076         }
1077 
1078         if (dstr->d_aclexport)
1079                 free(dstr->d_aclexport);
1080         free(dstr);
1081 }
1082 
1083 static void
1084 ace_printacl(acl_t *aclp, int cols, int flgs)
1085 {
1086         int  slot = 0;
1087         char *token;
1088         char *acltext;
1089 
1090         if (flgs & ACL_COMPACT_FMT) {
1091                 ace_compact_printacl(aclp, flgs);
1092                 return;
1093         }
1094 
1095         acltext = acl_totext(aclp, flgs);
1096 
1097         if (acltext == NULL)
1098                 return;
1099 
1100         token = strtok(acltext, ",");
1101         if (token == NULL) {
1102                 free(acltext);
1103                 return;
1104         }
1105 
1106         do {
1107                 (void) printf("     %d:", slot++);
1108                 split_line(token, cols - 5);
1109         } while (token = strtok(NULL, ","));
1110         free(acltext);
1111 }
1112 
1113 /*
1114  * pretty print an ACL.
1115  * For aclent_t ACL's the format is
1116  * similar to the old format used by getfacl,
1117  * with the addition of adding a "slot" number
1118  * before each entry.
1119  *
1120  * for ace_t ACL's the cols variable will break up
1121  * the long lines into multiple lines and will also
1122  * print a "slot" number.
1123  */
1124 void
1125 acl_printacl(acl_t *aclp, int cols, int flgs)
1126 {
1127 
1128         switch (aclp->acl_type) {
1129         case ACLENT_T:
1130                 aclent_printacl(aclp);
1131                 break;
1132         case ACE_T:
1133                 ace_printacl(aclp, cols, flgs);
1134                 break;
1135         }
1136 }
1137 
1138 typedef struct value_table {
1139         char            p_letter; /* perm letter such as 'r' */
1140         uint32_t        p_value; /* value for perm when pletter found */
1141 } value_table_t;
1142 
1143 /*
1144  * The permission tables are laid out in positional order
1145  * a '-' character will indicate a permission at a given
1146  * position is not specified.  The '-' is not part of the
1147  * table, but will be checked for in the permission computation
1148  * routine.
1149  */
1150 value_table_t ace_perm_table[] = {
1151         { 'r', ACE_READ_DATA},
1152         { 'w', ACE_WRITE_DATA},
1153         { 'x', ACE_EXECUTE},