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