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