1 #
   2 # Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
   3 # Use is subject to license terms.
   4 #
   5 # CDDL HEADER START
   6 #
   7 # The contents of this file are subject to the terms of the
   8 # Common Development and Distribution License, Version 1.0 only
   9 # (the "License").  You may not use this file except in compliance
  10 # with the License.
  11 #
  12 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  13 # or http://www.opensolaris.org/os/licensing.
  14 # See the License for the specific language governing permissions
  15 # and limitations under the License.
  16 #
  17 # When distributing Covered Code, include this CDDL HEADER in each
  18 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  19 # If applicable, add the following below this CDDL HEADER, with the
  20 # fields enclosed by brackets "[]" replaced with your own identifying
  21 # information: Portions Copyright [yyyy] [name of copyright owner]
  22 #
  23 # CDDL HEADER END
  24 #
  25 #ident  "%Z%%M% %I%     %E% SMI"
  26 #
  27 # This file generates three different C files:
  28 #
  29 #       <sys/priv_const.h>
  30 #               An implementation private set of manifest integer constant
  31 #               for privileges and privilege sets and manifest constants for
  32 #               set size, number of sets, number of privileges
  33 #
  34 #       os/priv_const.c
  35 #               A C source file containing the set names, privilege names
  36 #               arrays for the name <-> number mappings
  37 #
  38 #       <sys/priv_names.h>
  39 #               A public header file containing the PRIV_* defines
  40 #               that map to strings; these are for convenience.
  41 #               (it's easy to misspell a string, harder to misspell a
  42 #               manifest constant)
  43 #
  44 #       /etc/security/priv_names
  45 #               A privilege name to explanation mapping.
  46 #
  47 #
  48 # The files are output on the awk variable privhfile, pubhfile, cfile,
  49 # and pnamesfile respectively
  50 #
  51 # The input file should contain a standard Sun comment and ident string
  52 # which is copied verbatim and lines of
  53 #
  54 #       [keyword] privilege     PRIV_<privilege>
  55 #       set                     PRIV_<set>
  56 #
  57 # Which are converted to privileges and privilege sets
  58 #
  59 
  60 
  61 BEGIN   {
  62         # Number of privileges read
  63         npriv = 0
  64 
  65         # Number of privilege sets
  66         nset = 0
  67 
  68         # Length of all strings concatenated, including \0
  69         privbytes = 0
  70         setbytes = 0
  71 
  72         # Number of reserved privilege slots
  73         slack = 10
  74 
  75         privhcmt = \
  76         " * Privilege constant definitions; these constants are subject to\n" \
  77         " * change, including renumbering, without notice and should not be\n" \
  78         " * used in any code.  Privilege names must be used instead.\n" \
  79         " * Privileges and privilege sets must not be stored in binary\n" \
  80         " * form; privileges and privileges sets must be converted to\n" \
  81         " * textual representation before being committed to persistent store."
  82 
  83         ccmt = \
  84         " * Privilege name table and size definitions."
  85 
  86         pubhcmt = \
  87         " * Privilege constant definitions.  Privileges and privilege sets\n" \
  88         " * are only known by name and should be mapped at runtime."
  89 
  90         pnamescmt = \
  91         "#\n" \
  92         "# Privilege name explanation file\n" \
  93         "# The format of entries is a privilege name starting at the\n" \
  94         "# beginning of a line directly folowed by a new line followed\n" \
  95         "# by several lines of texts starting with white space terminated\n" \
  96         "# by a line with a single newline or not starting with white space\n" \
  97         "#\n"
  98 }
  99 
 100 #
 101 # Privilege strings are represented as lower case strings;
 102 # PRIV_ is stripped from the strings.
 103 #
 104 /^([A-Za-z]* )?privilege / {
 105         if (NF == 3) {
 106                 key = toupper($1)
 107                 priv = toupper($3)
 108                 if (set[key] != "")
 109                         set[key] = set[key] ";"
 110                 set[key] = set[key] "\\\n\t\tPRIV_ASSERT((set), " priv ")"
 111         } else {
 112                 priv = toupper($2);
 113         }
 114         privs[npriv] = tolower(substr(priv, 6));
 115         inset = 0
 116         inpriv = 1
 117 
 118         privind[npriv] = privbytes;
 119 
 120         tabs = (32 - length(priv) - 1)/8
 121         # length + \0 - PRIV_
 122         privbytes += length(priv) - 4
 123         pdef[npriv] = "#define\t" priv substr("\t\t\t\t\t", 1, tabs)
 124 
 125         npriv++
 126         next
 127 }
 128 
 129 #
 130 # Set strings are represented as strings with an initial cap;
 131 # PRIV_ is stripped from the strings.
 132 #
 133 /^set / {
 134         $2 = toupper($2)
 135         sets[nset] = toupper(substr($2, 6, 1)) tolower(substr($2, 7));
 136         inset = 1
 137         inpriv = 0
 138 
 139         setind[nset] = setbytes
 140 
 141         # length + \0 - PRIV_
 142         setbytes += length($2) - 4
 143         tabs = (32 - length($2) - 1)/8
 144         sdef[nset] = "#define\t" $2 substr("\t\t\t\t\t", 1, tabs)
 145 
 146         nset++
 147         next
 148 }
 149 
 150 /INSERT COMMENT/ {
 151         acmt = " *\n * THIS FILE WAS GENERATED; DO NOT EDIT"
 152         if (cfile) {
 153                 print ccmt > cfile
 154                 print acmt > cfile
 155         }
 156         if (privhfile) {
 157                 print privhcmt > privhfile
 158                 print acmt > privhfile
 159         }
 160         if (pubhfile) {
 161                 print pubhcmt > pubhfile
 162                 print acmt > pubhfile
 163         }
 164         next
 165 }
 166 /^#pragma/ {
 167         pragma = $0;
 168         if (pnamesfile) {
 169                 print "#" substr($0, 9) > pnamesfile
 170         }
 171         next;
 172 }
 173 
 174 /^#/ && ! /^#pragma/{
 175         # Comments, ignore
 176         next
 177 }
 178 
 179 {
 180         #
 181         # Comments describing privileges and sets follow the definitions.
 182         #
 183         if (inset || inpriv) {
 184                 sub("^[         ]*", "")
 185                 sub("[  ]*$", "")
 186                 if (/^$/) next;
 187         }
 188         if (inset) {
 189                 setcmt[nset - 1] = setcmt[nset - 1] " * " $0 "\n"
 190                 next
 191         } else if (inpriv) {
 192                 sub("^[         ]*", "")
 193                 privcmt[npriv - 1] = privcmt[npriv - 1] " * " $0 "\n"
 194                 privncmt[npriv - 1] = privncmt[npriv - 1] "\t" $0 "\n"
 195                 next
 196         }
 197 
 198         if (cfile)
 199                 print > cfile
 200         if (privhfile)
 201                 print > privhfile
 202         if (pubhfile)
 203                 print > pubhfile
 204         if (pnamesfile) {
 205                 sub("^/\\*", "#")
 206                 sub("^ \\*/", "")
 207                 sub("^ \\*", "#")
 208                 if (/^$/) next;
 209                 print > pnamesfile
 210         }
 211 }
 212 
 213 END     {
 214 
 215         if (!pubhfile && !privhfile && !cfile && !pnamesfile) {
 216                 print "Output file parameter not set" > "/dev/stderr"
 217                 exit 1
 218         }
 219 
 220         setsize = int((npriv + slack)/(8 * 4)) + 1
 221         maxnpriv = setsize * 8 * 4
 222         # Assume allocated privileges are on average "NSDQ" bytes larger.
 223         maxprivbytes = int((privbytes / npriv + 5.5)) * (maxnpriv - npriv)
 224         maxprivbytes += privbytes
 225 
 226         if (cfile) {
 227                 print "\n" > cfile
 228                 print pragma "\n"> cfile
 229                 print "#include <sys/types.h>" > cfile
 230                 print "#include <sys/priv_const.h>" > cfile
 231                 print "#include <sys/priv_impl.h>" > cfile
 232                 print "#include <sys/priv.h>" > cfile
 233                 print "#include <sys/sysmacros.h>" > cfile
 234                 print "\n" > cfile
 235                 #
 236                 # Create the entire priv info structure here.
 237                 # When adding privileges, the kernel needs to update
 238                 # too many fields as the number of privileges is kept in
 239                 # many places.
 240                 #
 241                 print \
 242                     "static struct _info {\n" \
 243                     "   priv_impl_info_t        impl_info;\n" \
 244                     "   priv_info_t             settype;\n" \
 245                     "   int                     nsets;\n" \
 246                     "   const char              sets[" setbytes "];\n" \
 247                     "   priv_info_t             privtype;\n" \
 248                     "   int                     nprivs;\n" \
 249                     "   char                    privs[" maxprivbytes "];\n" \
 250                     "   priv_info_t             sysset;\n" \
 251                     "   priv_set_t              basicset;\n" \
 252                     "} info = {\n" \
 253                     "   { sizeof (priv_impl_info_t), 0, PRIV_NSET, " \
 254                         "PRIV_SETSIZE, " npriv ",\n" \
 255                         "\t\tsizeof (priv_info_uint_t),\n" \
 256                         "\t\tsizeof (info) - sizeof (info.impl_info)},\n" \
 257                     "   { PRIV_INFO_SETNAMES,\n" \
 258                     "       offsetof(struct _info, privtype) - " \
 259                     "offsetof(struct _info, settype)},\n\tPRIV_NSET," > cfile
 260 
 261                 sep = "\t\""
 262                 len = 9;
 263                 for (i = 0; i < nset; i++) {
 264                         if (len + length(sets[i]) > 80) {
 265                                 sep = "\\0\"\n\t\""
 266                                 len = 9
 267                         }
 268                         printf sep sets[i]  > cfile
 269                         len += length(sets[i]) + length(sep);
 270                         sep = "\\0"
 271                 }
 272                 print "\\0\"," > cfile
 273 
 274                 print "\t{ PRIV_INFO_PRIVNAMES,\n\t    " \
 275                         "offsetof(struct _info, sysset) - " \
 276                         "offsetof(struct _info, privtype)},\n\t" npriv "," \
 277                         > cfile
 278 
 279                 sep = "\t\""
 280                 len = 9;
 281                 for (i = 0; i < npriv; i++) {
 282                         if (len + length(privs[i]) > 80) {
 283                                 sep = "\\0\"\n\t\""
 284                                 len = 9
 285                         }
 286                         printf sep privs[i]  > cfile
 287                         len += length(privs[i]) + length(sep);
 288                         sep = "\\0"
 289                 }
 290                 print "\\0\"," > cfile
 291 
 292                 print "\t{ PRIV_INFO_BASICPRIVS, sizeof (info) - " \
 293                         "offsetof(struct _info, sysset)},"  > cfile
 294 
 295                 print "};\n" > cfile
 296 
 297                 print "\nconst char *priv_names[" maxnpriv "] =\n{" > cfile
 298                 for (i = 0; i < npriv; i++)
 299                         print "\t&info.privs[" privind[i] "]," > cfile
 300 
 301                 print "};\n" > cfile
 302 
 303                 print "\nconst char *priv_setnames[" nset "] =\n{" > cfile
 304                 for (i = 0; i < nset; i++)
 305                         print "\t&info.sets[" setind[i] "]," > cfile
 306 
 307                 print "};\n" > cfile
 308 
 309                 print "int nprivs = " npriv ";" > cfile
 310                 print "int privbytes = " privbytes ";" > cfile
 311                 print "int maxprivbytes = " maxprivbytes ";" > cfile
 312                 print "size_t privinfosize = sizeof (info);" > cfile
 313                 print "char *priv_str = info.privs;" > cfile
 314                 print "priv_set_t *priv_basic = &info.basicset;" > cfile
 315                 print "priv_impl_info_t *priv_info = &info.impl_info;" > cfile
 316                 print "priv_info_names_t *priv_ninfo = " \
 317                         "(priv_info_names_t *)&info.privtype;" > cfile
 318                 close(cfile)
 319         }
 320 
 321         # Kernel private
 322         if (privhfile) {
 323                 print "#ifndef _SYS_PRIV_CONST_H" > privhfile
 324                 print "#define\t_SYS_PRIV_CONST_H\n" > privhfile
 325                 print pragma "\n"> privhfile
 326                 print "\n#include <sys/types.h>\n\n" > privhfile
 327                 print "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" > privhfile
 328 
 329                 print "#if defined(_KERNEL) || defined(_KMEMUSER)" > privhfile
 330                 print "#define\tPRIV_NSET\t\t\t  " nset > privhfile
 331                 print "#define\tPRIV_SETSIZE\t\t\t  " setsize > privhfile
 332                 print "#endif\n\n#ifdef _KERNEL" > privhfile
 333                 print "#define\t__PRIV_CONST_IMPL\n" > privhfile
 334                 print "extern const char *priv_names[];" > privhfile
 335                 print "extern const char *priv_setnames[];" > privhfile
 336 
 337                 print "extern int nprivs;" > privhfile
 338                 print "extern int privbytes;" > privhfile
 339                 print "extern int maxprivbytes;" > privhfile
 340                 print "extern size_t privinfosize;" > privhfile
 341                 print "extern char *priv_str;" > privhfile
 342                 print "extern struct priv_set *priv_basic;" > privhfile
 343                 print "extern struct priv_impl_info *priv_info;" > privhfile
 344                 print "extern struct priv_info_names *priv_ninfo;" > privhfile
 345 
 346                 print "\n/* Privileges */" > privhfile
 347                  
 348                 for (i = 0; i < npriv; i++)
 349                         print pdef[i] sprintf("%3d", i) > privhfile
 350 
 351                 print "\n/* Privilege sets */" > privhfile
 352                 for (i = 0; i < nset; i++)
 353                         print sdef[i] sprintf("%3d", i) > privhfile
 354 
 355                 print "\n#define\tMAX_PRIVILEGE\t\t\t "  setsize * 32 \
 356                         > privhfile
 357 
 358                 # Special privilege categories.
 359                 for (s in set)
 360                         print "\n#define\tPRIV_" s "_ASSERT(set)" set[s] \
 361                                 > privhfile
 362 
 363                 print "\n#endif /* _KERNEL */" > privhfile
 364                 print "\n#ifdef __cplusplus\n}\n#endif" > privhfile
 365                 print "\n#endif /* _SYS_PRIV_CONST_H */" > privhfile
 366                 close(privhfile)
 367         }
 368 
 369         if (pubhfile) {
 370                 cast="((const char *)"
 371                 print "#ifndef _SYS_PRIV_NAMES_H" > pubhfile
 372                 print "#define\t_SYS_PRIV_NAMES_H\n" > pubhfile
 373 
 374                 print pragma "\n" > pubhfile
 375                 print "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" > pubhfile
 376 
 377                 print "#ifndef __PRIV_CONST_IMPL" > pubhfile
 378                 print "/*\n * Privilege names\n */" > pubhfile
 379                 for (i = 0; i < npriv; i++) {
 380                         print "/*\n" privcmt[i] " */" > pubhfile
 381                         print pdef[i] cast "\"" privs[i] "\")\n" > pubhfile
 382                 }
 383 
 384                 print "" > pubhfile
 385 
 386                 print "/*\n * Privilege set names\n */" > pubhfile
 387                 for (i = 0; i < nset; i++) {
 388                         print "/*\n" setcmt[i] " */" > pubhfile
 389                         print sdef[i] cast "\"" sets[i] "\")\n" > pubhfile
 390                 }
 391 
 392                 print "\n#endif /* __PRIV_CONST_IMPL */" > pubhfile
 393                 print "\n#ifdef __cplusplus\n}\n#endif" > pubhfile
 394                 print "\n#endif /* _SYS_PRIV_NAMES_H */" > pubhfile
 395                 close(pubhfile)
 396         }
 397 
 398         if (pnamesfile) {
 399                 print pnamescmt > pnamesfile
 400                 for (i = 0; i < npriv; i++) {
 401                         print privs[i] > pnamesfile
 402                         print privncmt[i] > pnamesfile
 403                 }
 404         }
 405 
 406 }