xref: /onnv-gate/usr/src/cmd/perl/contrib/Sun/Solaris/Privilege/Privilege.xs (revision 12388:1bc8d55b0dfd)
1 /*
2  * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 /* Solaris includes. */
6 #include <priv.h>
7 #include <ctype.h>
8 
9 /* Perl includes. */
10 #include "EXTERN.h"
11 #include "perl.h"
12 #include "XSUB.h"
13 
14 #define	IVCONST(s, c)	newCONSTSUB(s, #c, newSViv((int)c));
15 #define	POFF		(sizeof ("PRIV_") - 1)
16 
17 #define	RETPRIVSET(set)		\
18 	ST(0) = sv_newmortal();						\
19 	sv_setref_pv(ST(0), "Sun::Solaris::Privilege::PrivsetPtr",	\
20 	    (void*)(set));						\
21 	SvREADONLY_on(SvRV(ST(0)))
22 
23 typedef int sysret;
24 
25 typedef priv_set_t Sun__Solaris__Privilege__Privset;
26 
27 static priv_set_t *
dupset(const priv_set_t * s)28 dupset(const priv_set_t *s)
29 {
30 	priv_set_t *new = priv_allocset();
31 	if (new == NULL)
32 		return (NULL);
33 
34 	priv_copyset(s, new);
35 	return (new);
36 }
37 
38 /*
39  * Automatically derive the #define constant from the constant value.
40  * This is the uppercase value of the constant with "PRIV_" prepended.
41  * The (name, value) pair computed in that way is stored twice:
42  * 	once as constant subroutine in the module's hash table.
43  *	once as (key, value) in a hash table.
44  */
45 
46 static void
PRIVconst(HV * sym,HV * var,const char * name)47 PRIVconst(HV *sym, HV *var, const char *name)
48 {
49 	char upname[128];
50 	ssize_t len;
51 	int i;
52 
53 	len = snprintf(upname, sizeof (upname), "PRIV_%s", name);
54 	if (len >= sizeof (upname))
55 		return;
56 
57 	for (i = POFF; i < len; i++)
58 		upname[i] = toupper(upname[i]);
59 	newCONSTSUB(sym, upname, newSVpv(name, len - POFF));
60 	hv_store(var, upname, len, newSVpv(name, len - POFF), 0);
61 }
62 
63 /*
64  * The XS code exported to perl is below here.  Note that the XS preprocessor
65  * has its own commenting syntax, so all comments from this point on are in
66  * that form.
67  *
68  * Inside perl, privilege sets are represented as expanded strings;
69  * privileges and privilege sets are only known by name.
70  */
71 
72 MODULE = Sun::Solaris::Privilege PACKAGE = Sun::Solaris::Privilege
73 PROTOTYPES: ENABLE
74 
75  #
76  # Define any constants that need to be exported.  By doing it this way we can
77  # avoid the overhead of using the DynaLoader package, and in addition constants
78  # defined using this mechanism are eligible for inlining by the perl
79  # interpreter at compile time.
80  #
81 BOOT:
82 {
83 	HV *stash;
84 	HV *privs;
85 	HV *privsets;
86 	const char *p;
87 	int i;
88 
89 	stash = gv_stashpv("Sun::Solaris::Privilege", TRUE);
90 
91 	/*
92 	 * Global constants
93 	 */
94 	IVCONST(stash, PRIV_STR_PORT);
95 	IVCONST(stash, PRIV_STR_LIT);
96 	IVCONST(stash, PRIV_STR_SHORT);
97 	IVCONST(stash, PRIV_ALLSETS);
98 	IVCONST(stash, PRIV_DEBUG);
99 	IVCONST(stash, PRIV_AWARE);
100 	IVCONST(stash, PRIV_ON);
101 	IVCONST(stash, PRIV_OFF);
102 	IVCONST(stash, PRIV_SET);
103 
104 	/*
105 	 * %PRIVILEGES hash and the privilege constants
106 	 */
107 	privs = perl_get_hv("Sun::Solaris::Privilege::PRIVILEGES", TRUE);
108 	for (i = 0; (p = priv_getbynum(i++)) != NULL; )
109 		PRIVconst(stash, privs, p);
110 
111 	/*
112 	 * %PRIVSETS hash and the privset constants
113 	 */
114 	privsets = perl_get_hv("Sun::Solaris::Privilege::PRIVSETS", TRUE);
115 	for (i = 0; (p = priv_getsetbynum(i++)) != NULL; )
116 		PRIVconst(stash, privsets, p);
117 }
118 
119 
120 Sun::Solaris::Privilege::Privset *
121 getppriv(which)
122 	const char *which;
123 CODE:
124 	RETVAL = priv_allocset();
125 	if (getppriv(which, RETVAL) != 0) {
126 		priv_freeset(RETVAL);
127 		XSRETURN_UNDEF;
128 	} else {
129 		RETPRIVSET(RETVAL);
130 	}
131 
132 sysret
133 setppriv(op, which, set)
134 	int op;
135 	const char *which;
136 	Sun::Solaris::Privilege::Privset *set;
137 
138 Sun::Solaris::Privilege::Privset *
139 priv_emptyset()
140 CODE:
141 	RETVAL = priv_allocset();
142 	if (RETVAL == NULL) {
143 		XSRETURN_UNDEF;
144 	}
145 	priv_emptyset(RETVAL);
146 	RETPRIVSET(RETVAL);
147 
148 Sun::Solaris::Privilege::Privset *
149 priv_fillset()
150 CODE:
151 	RETVAL = priv_allocset();
152 	if (RETVAL == NULL) {
153 		XSRETURN_UNDEF;
154 	}
155 	priv_fillset(RETVAL);
156 	RETPRIVSET(RETVAL);
157 
158 boolean_t
159 priv_isemptyset(set)
160 	Sun::Solaris::Privilege::Privset *set;
161 
162 boolean_t
163 priv_isfullset(set)
164 	Sun::Solaris::Privilege::Privset *set;
165 
166 boolean_t
167 priv_isequalset(set1, set2)
168 	Sun::Solaris::Privilege::Privset *set1;
169 	Sun::Solaris::Privilege::Privset *set2;
170 
171 boolean_t
172 priv_issubset(set1, set2)
173 	Sun::Solaris::Privilege::Privset *set1;
174 	Sun::Solaris::Privilege::Privset *set2;
175 
176 boolean_t
177 priv_ismember(set, priv)
178 	Sun::Solaris::Privilege::Privset *set;
179 	const char *priv;
180 
181 boolean_t
182 priv_ineffect(priv)
183 	const char *priv;
184 
185 Sun::Solaris::Privilege::Privset *
186 priv_intersect(set1, set2)
187 	Sun::Solaris::Privilege::Privset *set1;
188 	Sun::Solaris::Privilege::Privset *set2;
189 CODE:
190 	RETVAL = dupset(set2);
191 	if (RETVAL == NULL) {
192 		XSRETURN_UNDEF;
193 	}
194 	priv_intersect(set1, RETVAL);
195 	RETPRIVSET(RETVAL);
196 
197 Sun::Solaris::Privilege::Privset *
198 priv_union(set1, set2)
199 	Sun::Solaris::Privilege::Privset *set1;
200 	Sun::Solaris::Privilege::Privset *set2;
201 CODE:
202 	RETVAL = dupset(set2);
203 	if (RETVAL == NULL) {
204 		XSRETURN_UNDEF;
205 	}
206 	priv_union(set1, RETVAL);
207 	RETPRIVSET(RETVAL);
208 
209 Sun::Solaris::Privilege::Privset *
210 priv_inverse(set1)
211 	Sun::Solaris::Privilege::Privset *set1;
212 CODE:
213 	RETVAL = dupset(set1);
214 	if (RETVAL == NULL) {
215 		XSRETURN_UNDEF;
216 	}
217 	priv_inverse(RETVAL);
218 	RETPRIVSET(RETVAL);
219 
220 
221 sysret
222 priv_addset(set, priv)
223 	Sun::Solaris::Privilege::Privset *set;
224 	const char *priv;
225 
226 Sun::Solaris::Privilege::Privset *
227 priv_copyset(set1)
228 	Sun::Solaris::Privilege::Privset *set1;
229 CODE:
230 	RETVAL = dupset(set1);
231 	if (RETVAL == NULL) {
232 		XSRETURN_UNDEF;
233 	}
234 	RETPRIVSET(RETVAL);
235 
236 
237 sysret
238 priv_delset(set, priv)
239 	Sun::Solaris::Privilege::Privset *set;
240 	const char *priv;
241 
242 const char *
243 priv_getbynum(i)
244 	int i;
245 
246 const char *
247 priv_getsetbynum(i)
248 	int i;
249 
250 char *
251 priv_set_to_str(s, c, f)
252 	Sun::Solaris::Privilege::Privset *s;
253 	char c;
254 	int f;
255 CLEANUP:
256 	free(RETVAL);
257 
258 Sun::Solaris::Privilege::Privset *
259 priv_str_to_set(buf, sep);
260 	const char *buf;
261 	const char *sep;
262 CODE:
263 	RETVAL = priv_str_to_set(buf, sep, NULL);
264 	if (RETVAL == NULL) {
265 		XSRETURN_UNDEF;
266 	}
267 	RETPRIVSET(RETVAL);
268 
269 char *
270 priv_gettext(priv)
271 	const char *priv
272 CLEANUP:
273 	free(RETVAL);
274 
275 sysret
276 setpflags(flag, val)
277 	uint_t flag;
278 	uint_t val;
279 
280 sysret
281 getpflags(flag)
282 	uint_t flag;
283 
284 MODULE = Sun::Solaris::Privilege PACKAGE = Sun::Solaris::Privilege::PrivsetPtr PREFIX = Privilege_
285 
286 void
287 Privilege_DESTROY(ps)
288 	Sun::Solaris::Privilege::Privset *ps;
289 CODE:
290 	priv_freeset(ps);
291 
292