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_ADDSET((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 " priv_info_t defset;\n" \ 253 " priv_set_t defaultset;\n" \ 254 "} info = {\n" \ 255 " { sizeof (priv_impl_info_t), 0, PRIV_NSET, " \ 256 "PRIV_SETSIZE, " npriv ",\n" \ 257 "\t\tsizeof (priv_info_uint_t),\n" \ 258 "\t\tsizeof (info) - sizeof (info.impl_info)},\n" \ 259 " { PRIV_INFO_SETNAMES,\n" \ 260 " offsetof(struct _info, privtype) - " \ 261 "offsetof(struct _info, settype)},\n\tPRIV_NSET," > cfile 262 263 sep = "\t\"" 264 len = 9; 265 for (i = 0; i < nset; i++) { 266 if (len + length(sets[i]) > 80) { 267 sep = "\\0\"\n\t\"" 268 len = 9 269 } 270 printf sep sets[i] > cfile 271 len += length(sets[i]) + length(sep); 272 sep = "\\0" 273 } 274 print "\\0\"," > cfile 275 276 print "\t{ PRIV_INFO_PRIVNAMES,\n\t " \ 277 "offsetof(struct _info, sysset) - " \ 278 "offsetof(struct _info, privtype)},\n\t" npriv "," \ 279 > cfile 280 281 sep = "\t\"" 282 len = 9; 283 for (i = 0; i < npriv; i++) { 284 if (len + length(privs[i]) > 80) { 285 sep = "\\0\"\n\t\"" 286 len = 9 287 } 288 printf sep privs[i] > cfile 289 len += length(privs[i]) + length(sep); 290 sep = "\\0" 291 } 292 print "\\0\"," > cfile 293 294 print "\t{ PRIV_INFO_BASICPRIVS, offsetof (struct _info, defset) - " \ 295 "offsetof(struct _info, sysset)}," > cfile 296 print "\t{ 0 },\n" > cfile 297 print "\t{ PRIV_INFO_DEFAULTPRIVS, sizeof (info) - " \ 298 "offsetof(struct _info, defset)}" > cfile 299 300 print "};\n" > cfile 301 302 print "\nconst char *priv_names[" maxnpriv "] =\n{" > cfile 303 for (i = 0; i < npriv; i++) 304 print "\t&info.privs[" privind[i] "]," > cfile 305 306 print "};\n" > cfile 307 308 print "\nconst char *priv_setnames[" nset "] =\n{" > cfile 309 for (i = 0; i < nset; i++) 310 print "\t&info.sets[" setind[i] "]," > cfile 311 312 print "};\n" > cfile 313 314 print "int nprivs = " npriv ";" > cfile 315 print "int privbytes = " privbytes ";" > cfile 316 print "int maxprivbytes = " maxprivbytes ";" > cfile 317 print "size_t privinfosize = sizeof (info);" > cfile 318 print "char *priv_str = info.privs;" > cfile 319 print "priv_set_t *priv_basic = &info.basicset;" > cfile 320 print "priv_set_t *priv_default = &info.defaultset;" > cfile 321 print "priv_impl_info_t *priv_info = &info.impl_info;" > cfile 322 print "priv_info_names_t *priv_ninfo = " \ 323 "(priv_info_names_t *)&info.privtype;" > cfile 324 close(cfile) 325 } 326 327 # Kernel private 328 if (privhfile) { 329 print "#ifndef _SYS_PRIV_CONST_H" > privhfile 330 print "#define\t_SYS_PRIV_CONST_H\n" > privhfile 331 print pragma "\n"> privhfile 332 print "\n#include <sys/types.h>\n\n" > privhfile 333 print "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" > privhfile 334 335 print "#if defined(_KERNEL) || defined(_KMEMUSER)" > privhfile 336 print "#define\tPRIV_NSET\t\t\t " nset > privhfile 337 print "#define\tPRIV_SETSIZE\t\t\t " setsize > privhfile 338 print "#endif\n\n#ifdef _KERNEL" > privhfile 339 print "#define\t__PRIV_CONST_IMPL\n" > privhfile 340 print "extern const char *priv_names[];" > privhfile 341 print "extern const char *priv_setnames[];" > privhfile 342 343 print "extern int nprivs;" > privhfile 344 print "extern int privbytes;" > privhfile 345 print "extern int maxprivbytes;" > privhfile 346 print "extern size_t privinfosize;" > privhfile 347 print "extern char *priv_str;" > privhfile 348 print "extern struct priv_set *priv_basic;" > privhfile 349 print "extern struct priv_set *priv_default;" > privhfile 350 print "extern struct priv_impl_info *priv_info;" > privhfile 351 print "extern struct priv_info_names *priv_ninfo;" > privhfile 352 353 print "\n/* Privileges */" > privhfile 354 355 for (i = 0; i < npriv; i++) 356 print pdef[i] sprintf("%3d", i) > privhfile 357 358 print "\n/* Privilege sets */" > privhfile 359 for (i = 0; i < nset; i++) 360 print sdef[i] sprintf("%3d", i) > privhfile 361 362 print "\n#define\tMAX_PRIVILEGE\t\t\t " setsize * 32 \ 363 > privhfile 364 365 # Special privilege categories. 366 for (s in set) 367 print "\n#define\tPRIV_" s "_ADDSET(set)" set[s] \ 368 > privhfile 369 370 print "\n#endif /* _KERNEL */" > privhfile 371 print "\n#ifdef __cplusplus\n}\n#endif" > privhfile 372 print "\n#endif /* _SYS_PRIV_CONST_H */" > privhfile 373 close(privhfile) 374 } 375 376 if (pubhfile) { 377 cast="((const char *)" 378 print "#ifndef _SYS_PRIV_NAMES_H" > pubhfile 379 print "#define\t_SYS_PRIV_NAMES_H\n" > pubhfile 380 381 print pragma "\n" > pubhfile 382 print "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" > pubhfile 383 384 print "#ifndef __PRIV_CONST_IMPL" > pubhfile 385 print "/*\n * Privilege names\n */" > pubhfile 386 for (i = 0; i < npriv; i++) { 387 print "/*\n" privcmt[i] " */" > pubhfile 388 print pdef[i] cast "\"" privs[i] "\")\n" > pubhfile 389 } 390 391 print "" > pubhfile 392 393 print "/*\n * Privilege set names\n */" > pubhfile 394 for (i = 0; i < nset; i++) { 395 print "/*\n" setcmt[i] " */" > pubhfile 396 print sdef[i] cast "\"" sets[i] "\")\n" > pubhfile 397 } 398 399 print "\n#endif /* __PRIV_CONST_IMPL */" > pubhfile 400 print "\n#ifdef __cplusplus\n}\n#endif" > pubhfile 401 print "\n#endif /* _SYS_PRIV_NAMES_H */" > pubhfile 402 close(pubhfile) 403 } 404 405 if (pnamesfile) { 406 print pnamescmt > pnamesfile 407 for (i = 0; i < npriv; i++) { 408 print privs[i] > pnamesfile 409 print privncmt[i] > pnamesfile 410 } 411 } 412 413 }