10Sstevel@tonic-gate /*
2*12388SJohn.Sonnenschein@Sun.COM * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
30Sstevel@tonic-gate */
40Sstevel@tonic-gate
50Sstevel@tonic-gate /* Solaris includes. */
60Sstevel@tonic-gate #include <priv.h>
70Sstevel@tonic-gate #include <ctype.h>
80Sstevel@tonic-gate
90Sstevel@tonic-gate /* Perl includes. */
100Sstevel@tonic-gate #include "EXTERN.h"
110Sstevel@tonic-gate #include "perl.h"
120Sstevel@tonic-gate #include "XSUB.h"
130Sstevel@tonic-gate
140Sstevel@tonic-gate #define IVCONST(s, c) newCONSTSUB(s, #c, newSViv((int)c));
150Sstevel@tonic-gate #define POFF (sizeof ("PRIV_") - 1)
160Sstevel@tonic-gate
170Sstevel@tonic-gate #define RETPRIVSET(set) \
180Sstevel@tonic-gate ST(0) = sv_newmortal(); \
190Sstevel@tonic-gate sv_setref_pv(ST(0), "Sun::Solaris::Privilege::PrivsetPtr", \
200Sstevel@tonic-gate (void*)(set)); \
210Sstevel@tonic-gate SvREADONLY_on(SvRV(ST(0)))
220Sstevel@tonic-gate
230Sstevel@tonic-gate typedef int sysret;
240Sstevel@tonic-gate
250Sstevel@tonic-gate typedef priv_set_t Sun__Solaris__Privilege__Privset;
260Sstevel@tonic-gate
270Sstevel@tonic-gate static priv_set_t *
dupset(const priv_set_t * s)280Sstevel@tonic-gate dupset(const priv_set_t *s)
290Sstevel@tonic-gate {
300Sstevel@tonic-gate priv_set_t *new = priv_allocset();
310Sstevel@tonic-gate if (new == NULL)
320Sstevel@tonic-gate return (NULL);
330Sstevel@tonic-gate
340Sstevel@tonic-gate priv_copyset(s, new);
350Sstevel@tonic-gate return (new);
360Sstevel@tonic-gate }
370Sstevel@tonic-gate
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate * Automatically derive the #define constant from the constant value.
400Sstevel@tonic-gate * This is the uppercase value of the constant with "PRIV_" prepended.
410Sstevel@tonic-gate * The (name, value) pair computed in that way is stored twice:
420Sstevel@tonic-gate * once as constant subroutine in the module's hash table.
430Sstevel@tonic-gate * once as (key, value) in a hash table.
440Sstevel@tonic-gate */
450Sstevel@tonic-gate
460Sstevel@tonic-gate static void
PRIVconst(HV * sym,HV * var,const char * name)470Sstevel@tonic-gate PRIVconst(HV *sym, HV *var, const char *name)
480Sstevel@tonic-gate {
490Sstevel@tonic-gate char upname[128];
500Sstevel@tonic-gate ssize_t len;
510Sstevel@tonic-gate int i;
520Sstevel@tonic-gate
530Sstevel@tonic-gate len = snprintf(upname, sizeof (upname), "PRIV_%s", name);
540Sstevel@tonic-gate if (len >= sizeof (upname))
550Sstevel@tonic-gate return;
560Sstevel@tonic-gate
570Sstevel@tonic-gate for (i = POFF; i < len; i++)
580Sstevel@tonic-gate upname[i] = toupper(upname[i]);
590Sstevel@tonic-gate newCONSTSUB(sym, upname, newSVpv(name, len - POFF));
600Sstevel@tonic-gate hv_store(var, upname, len, newSVpv(name, len - POFF), 0);
610Sstevel@tonic-gate }
620Sstevel@tonic-gate
630Sstevel@tonic-gate /*
640Sstevel@tonic-gate * The XS code exported to perl is below here. Note that the XS preprocessor
650Sstevel@tonic-gate * has its own commenting syntax, so all comments from this point on are in
660Sstevel@tonic-gate * that form.
670Sstevel@tonic-gate *
680Sstevel@tonic-gate * Inside perl, privilege sets are represented as expanded strings;
690Sstevel@tonic-gate * privileges and privilege sets are only known by name.
700Sstevel@tonic-gate */
710Sstevel@tonic-gate
720Sstevel@tonic-gate MODULE = Sun::Solaris::Privilege PACKAGE = Sun::Solaris::Privilege
730Sstevel@tonic-gate PROTOTYPES: ENABLE
740Sstevel@tonic-gate
750Sstevel@tonic-gate #
760Sstevel@tonic-gate # Define any constants that need to be exported. By doing it this way we can
770Sstevel@tonic-gate # avoid the overhead of using the DynaLoader package, and in addition constants
780Sstevel@tonic-gate # defined using this mechanism are eligible for inlining by the perl
790Sstevel@tonic-gate # interpreter at compile time.
800Sstevel@tonic-gate #
810Sstevel@tonic-gate BOOT:
820Sstevel@tonic-gate {
830Sstevel@tonic-gate HV *stash;
840Sstevel@tonic-gate HV *privs;
850Sstevel@tonic-gate HV *privsets;
860Sstevel@tonic-gate const char *p;
870Sstevel@tonic-gate int i;
880Sstevel@tonic-gate
890Sstevel@tonic-gate stash = gv_stashpv("Sun::Solaris::Privilege", TRUE);
900Sstevel@tonic-gate
910Sstevel@tonic-gate /*
920Sstevel@tonic-gate * Global constants
930Sstevel@tonic-gate */
940Sstevel@tonic-gate IVCONST(stash, PRIV_STR_PORT);
950Sstevel@tonic-gate IVCONST(stash, PRIV_STR_LIT);
960Sstevel@tonic-gate IVCONST(stash, PRIV_STR_SHORT);
970Sstevel@tonic-gate IVCONST(stash, PRIV_ALLSETS);
980Sstevel@tonic-gate IVCONST(stash, PRIV_DEBUG);
990Sstevel@tonic-gate IVCONST(stash, PRIV_AWARE);
1000Sstevel@tonic-gate IVCONST(stash, PRIV_ON);
1010Sstevel@tonic-gate IVCONST(stash, PRIV_OFF);
1020Sstevel@tonic-gate IVCONST(stash, PRIV_SET);
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate /*
1050Sstevel@tonic-gate * %PRIVILEGES hash and the privilege constants
1060Sstevel@tonic-gate */
1070Sstevel@tonic-gate privs = perl_get_hv("Sun::Solaris::Privilege::PRIVILEGES", TRUE);
1080Sstevel@tonic-gate for (i = 0; (p = priv_getbynum(i++)) != NULL; )
1090Sstevel@tonic-gate PRIVconst(stash, privs, p);
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate /*
1120Sstevel@tonic-gate * %PRIVSETS hash and the privset constants
1130Sstevel@tonic-gate */
1140Sstevel@tonic-gate privsets = perl_get_hv("Sun::Solaris::Privilege::PRIVSETS", TRUE);
1150Sstevel@tonic-gate for (i = 0; (p = priv_getsetbynum(i++)) != NULL; )
1160Sstevel@tonic-gate PRIVconst(stash, privsets, p);
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
1210Sstevel@tonic-gate getppriv(which)
1220Sstevel@tonic-gate const char *which;
1230Sstevel@tonic-gate CODE:
1240Sstevel@tonic-gate RETVAL = priv_allocset();
1250Sstevel@tonic-gate if (getppriv(which, RETVAL) != 0) {
1260Sstevel@tonic-gate priv_freeset(RETVAL);
1270Sstevel@tonic-gate XSRETURN_UNDEF;
1280Sstevel@tonic-gate } else {
1290Sstevel@tonic-gate RETPRIVSET(RETVAL);
1300Sstevel@tonic-gate }
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate sysret
1330Sstevel@tonic-gate setppriv(op, which, set)
1340Sstevel@tonic-gate int op;
1350Sstevel@tonic-gate const char *which;
1360Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set;
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
1390Sstevel@tonic-gate priv_emptyset()
1400Sstevel@tonic-gate CODE:
1410Sstevel@tonic-gate RETVAL = priv_allocset();
1420Sstevel@tonic-gate if (RETVAL == NULL) {
1430Sstevel@tonic-gate XSRETURN_UNDEF;
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate priv_emptyset(RETVAL);
1460Sstevel@tonic-gate RETPRIVSET(RETVAL);
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
1490Sstevel@tonic-gate priv_fillset()
1500Sstevel@tonic-gate CODE:
1510Sstevel@tonic-gate RETVAL = priv_allocset();
1520Sstevel@tonic-gate if (RETVAL == NULL) {
1530Sstevel@tonic-gate XSRETURN_UNDEF;
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate priv_fillset(RETVAL);
1560Sstevel@tonic-gate RETPRIVSET(RETVAL);
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate boolean_t
1590Sstevel@tonic-gate priv_isemptyset(set)
1600Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set;
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate boolean_t
1630Sstevel@tonic-gate priv_isfullset(set)
1640Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set;
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate boolean_t
1670Sstevel@tonic-gate priv_isequalset(set1, set2)
1680Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set1;
1690Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set2;
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate boolean_t
1720Sstevel@tonic-gate priv_issubset(set1, set2)
1730Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set1;
1740Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set2;
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate boolean_t
1770Sstevel@tonic-gate priv_ismember(set, priv)
1780Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set;
1790Sstevel@tonic-gate const char *priv;
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate boolean_t
1820Sstevel@tonic-gate priv_ineffect(priv)
1830Sstevel@tonic-gate const char *priv;
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
1860Sstevel@tonic-gate priv_intersect(set1, set2)
1870Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set1;
1880Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set2;
1890Sstevel@tonic-gate CODE:
1900Sstevel@tonic-gate RETVAL = dupset(set2);
1910Sstevel@tonic-gate if (RETVAL == NULL) {
1920Sstevel@tonic-gate XSRETURN_UNDEF;
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate priv_intersect(set1, RETVAL);
1950Sstevel@tonic-gate RETPRIVSET(RETVAL);
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
1980Sstevel@tonic-gate priv_union(set1, set2)
1990Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set1;
2000Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set2;
2010Sstevel@tonic-gate CODE:
2020Sstevel@tonic-gate RETVAL = dupset(set2);
2030Sstevel@tonic-gate if (RETVAL == NULL) {
2040Sstevel@tonic-gate XSRETURN_UNDEF;
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate priv_union(set1, RETVAL);
2070Sstevel@tonic-gate RETPRIVSET(RETVAL);
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
2100Sstevel@tonic-gate priv_inverse(set1)
2110Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set1;
2120Sstevel@tonic-gate CODE:
2130Sstevel@tonic-gate RETVAL = dupset(set1);
2140Sstevel@tonic-gate if (RETVAL == NULL) {
2150Sstevel@tonic-gate XSRETURN_UNDEF;
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate priv_inverse(RETVAL);
2180Sstevel@tonic-gate RETPRIVSET(RETVAL);
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate sysret
2220Sstevel@tonic-gate priv_addset(set, priv)
2230Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set;
2240Sstevel@tonic-gate const char *priv;
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
2270Sstevel@tonic-gate priv_copyset(set1)
2280Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set1;
2290Sstevel@tonic-gate CODE:
2300Sstevel@tonic-gate RETVAL = dupset(set1);
2310Sstevel@tonic-gate if (RETVAL == NULL) {
2320Sstevel@tonic-gate XSRETURN_UNDEF;
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate RETPRIVSET(RETVAL);
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate sysret
2380Sstevel@tonic-gate priv_delset(set, priv)
2390Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *set;
2400Sstevel@tonic-gate const char *priv;
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate const char *
2430Sstevel@tonic-gate priv_getbynum(i)
2440Sstevel@tonic-gate int i;
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate const char *
2470Sstevel@tonic-gate priv_getsetbynum(i)
2480Sstevel@tonic-gate int i;
2490Sstevel@tonic-gate
2500Sstevel@tonic-gate char *
2510Sstevel@tonic-gate priv_set_to_str(s, c, f)
2520Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *s;
2530Sstevel@tonic-gate char c;
2540Sstevel@tonic-gate int f;
2550Sstevel@tonic-gate CLEANUP:
2560Sstevel@tonic-gate free(RETVAL);
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *
2590Sstevel@tonic-gate priv_str_to_set(buf, sep);
2600Sstevel@tonic-gate const char *buf;
2610Sstevel@tonic-gate const char *sep;
2620Sstevel@tonic-gate CODE:
2630Sstevel@tonic-gate RETVAL = priv_str_to_set(buf, sep, NULL);
2640Sstevel@tonic-gate if (RETVAL == NULL) {
2650Sstevel@tonic-gate XSRETURN_UNDEF;
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate RETPRIVSET(RETVAL);
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate char *
2700Sstevel@tonic-gate priv_gettext(priv)
2710Sstevel@tonic-gate const char *priv
2720Sstevel@tonic-gate CLEANUP:
2730Sstevel@tonic-gate free(RETVAL);
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate sysret
2760Sstevel@tonic-gate setpflags(flag, val)
2770Sstevel@tonic-gate uint_t flag;
2780Sstevel@tonic-gate uint_t val;
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate sysret
2810Sstevel@tonic-gate getpflags(flag)
2820Sstevel@tonic-gate uint_t flag;
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate MODULE = Sun::Solaris::Privilege PACKAGE = Sun::Solaris::Privilege::PrivsetPtr PREFIX = Privilege_
2850Sstevel@tonic-gate
2860Sstevel@tonic-gate void
2870Sstevel@tonic-gate Privilege_DESTROY(ps)
2880Sstevel@tonic-gate Sun::Solaris::Privilege::Privset *ps;
2890Sstevel@tonic-gate CODE:
2900Sstevel@tonic-gate priv_freeset(ps);
2910Sstevel@tonic-gate
292