Unix client: wrappers for credentials structure access
[openafs.git] / src / afs / afs_osi.c
1 /*
2  * Copyrigh 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include "afs/param.h"
12
13
14 #include "afs/sysincludes.h"    /* Standard vendor system headers */
15 #include "afsincludes.h"        /* Afs-based standard headers */
16 #include "afs/afs_stats.h"      /* afs statistics */
17 #ifdef AFS_AIX_ENV
18 #include <sys/adspace.h>        /* for vm_att(), vm_det() */
19 #endif
20
21 /* osi_Init -- do once per kernel installation initialization.
22  *     -- On Solaris this is called from modload initialization.
23  *     -- On AIX called from afs_config.
24  *     -- On HP called from afsc_link.
25  *     -- On SGI called from afs_init. */
26
27 afs_lock_t afs_ftf;             /* flush text lock */
28
29 #ifdef AFS_SGI53_ENV
30 lock_t afs_event_lock;
31 #endif
32
33 #ifdef AFS_SGI64_ENV
34 flid_t osi_flid;
35 #endif
36
37 afs_ucred_t *afs_osi_credp;
38
39 #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
40 kmutex_t afs_global_lock;
41 kmutex_t afs_rxglobal_lock;
42 #endif
43
44 #if defined(AFS_SGI_ENV) && !defined(AFS_SGI64_ENV)
45 long afs_global_owner;
46 #endif
47
48 #if defined(AFS_DARWIN_ENV) 
49 #ifdef AFS_DARWIN80_ENV
50 lck_mtx_t  *afs_global_lock;
51 #else
52 struct lock__bsd__ afs_global_lock;
53 #endif
54 #endif
55
56 #if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD50_ENV)
57 struct lock afs_global_lock;
58 afs_proc_t *afs_global_owner;
59 #endif
60 #ifdef AFS_FBSD50_ENV
61 struct mtx afs_global_mtx;
62 #endif
63
64 #if defined(AFS_DARWIN_ENV)
65 thread_t afs_global_owner;
66 #endif /* AFS_DARWIN_ENV */
67
68 #if defined(AFS_AIX41_ENV)
69 simple_lock_data afs_global_lock;
70 #endif
71
72 void
73 osi_Init(void)
74 {
75     static int once = 0;
76     if (once++ > 0)             /* just in case */
77         return;
78 #if     defined(AFS_HPUX_ENV)
79     osi_InitGlock();
80 #else /* AFS_HPUX_ENV */
81 #if defined(AFS_GLOBAL_SUNLOCK)
82 #if defined(AFS_SGI62_ENV)
83     mutex_init(&afs_global_lock, MUTEX_DEFAULT, "afs_global_lock");
84 #elif defined(AFS_FBSD50_ENV)
85 #if defined(AFS_FBSD80_ENV) && defined(WITNESS)
86     /* "lock_initalized" (sic) can panic, checks a flag bit
87      * is unset _before_ init */
88     memset(&afs_global_mtx, 0, sizeof(struct mtx));
89 #endif
90     mtx_init(&afs_global_mtx, "AFS global lock", NULL, MTX_DEF);
91 #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
92 #if !defined(AFS_DARWIN80_ENV)
93     lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0);
94 #endif
95     afs_global_owner = 0;
96 #elif defined(AFS_AIX41_ENV)
97     lock_alloc((void *)&afs_global_lock, LOCK_ALLOC_PIN, 1, 1);
98     simple_lock_init((void *)&afs_global_lock);
99 #elif !defined(AFS_LINUX22_ENV)
100     /* Linux initialization in osi directory. Should move the others. */
101     mutex_init(&afs_global_lock, "afs_global_lock", MUTEX_DEFAULT, NULL);
102 #endif
103 #endif /* AFS_GLOBAL_SUNLOCK */
104 #endif /* AFS_HPUX_ENV */
105
106     if (!afs_osicred_initialized) {
107 #if defined(AFS_DARWIN80_ENV)
108         afs_osi_ctxtp_initialized = 0;
109         afs_osi_ctxtp = NULL; /* initialized in afs_Daemon since it has
110                                   a proc reference that cannot be changed */
111 #endif
112 #if defined(AFS_XBSD_ENV)
113         /* Can't just invent one, must use crget() because of mutex */
114         afs_osi_credp = crdup(osi_curcred());
115 #else
116         memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
117 #if defined(AFS_LINUX26_ENV)
118         set_cr_group_info(&afs_osi_cred, groups_alloc(0));
119 #endif
120 #if defined(AFS_DARWIN80_ENV)
121         afs_osi_cred.cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */
122 #else
123         crhold(&afs_osi_cred);  /* don't let it evaporate */
124 #endif
125
126         afs_osi_credp = &afs_osi_cred;
127 #endif
128         afs_osicred_initialized = 1;
129     }
130 #ifdef AFS_SGI64_ENV
131     osi_flid.fl_pid = osi_flid.fl_sysid = 0;
132 #endif
133
134     init_et_to_sys_error();
135 }
136
137 /* mask signals in afsds */
138 void
139 afs_osi_MaskSignals(void)
140 {
141 #ifdef AFS_LINUX22_ENV
142     osi_linux_mask();
143 #endif
144 }
145
146 /* unmask signals in rxk listener */
147 void
148 afs_osi_UnmaskRxkSignals(void)
149 {
150 }
151
152 /* Two hacks to try and fix afsdb */
153 void 
154 afs_osi_MaskUserLoop()
155 {
156 #ifdef AFS_DARWIN_ENV
157     afs_osi_Invisible();
158     afs_osi_fullSigMask();
159 #else
160     afs_osi_MaskSignals();
161 #endif
162 }
163
164 void 
165 afs_osi_UnmaskUserLoop(void)
166 {
167 #ifdef AFS_DARWIN_ENV
168     afs_osi_fullSigRestore();
169 #endif
170 }
171
172 /* register rxk listener proc info */
173 void
174 afs_osi_RxkRegister(void)
175 {
176 }
177
178 /* procedure for making our processes as invisible as we can */
179 void
180 afs_osi_Invisible(void)
181 {
182 #ifdef AFS_LINUX22_ENV
183     afs_osi_MaskSignals();
184 #elif defined(AFS_SUN5_ENV)
185     curproc->p_flag |= SSYS;
186 #elif defined(AFS_HPUX101_ENV) && !defined(AFS_HPUX1123_ENV)
187     set_system_proc(u.u_procp);
188 #elif defined(AFS_DARWIN80_ENV)
189 #elif defined(AFS_DARWIN_ENV)
190     /* maybe call init_process instead? */
191     current_proc()->p_flag |= P_SYSTEM;
192 #elif defined(AFS_XBSD_ENV)
193     curproc->p_flag |= P_SYSTEM;
194 #elif defined(AFS_SGI_ENV)
195     vrelvm();
196 #endif
197
198     AFS_STATCNT(osi_Invisible);
199 }
200
201 void
202 afs_osi_Visible(void)
203 {
204 #if defined(AFS_SUN5_ENV)
205     curproc->p_flag &= ~SSYS;
206 #elif defined(AFS_DARWIN80_ENV)
207 #elif defined(AFS_DARWIN_ENV)
208     /* maybe call init_process instead? */
209     current_proc()->p_flag &= ~P_SYSTEM;
210 #elif defined(AFS_XBSD_ENV)
211     curproc->p_flag &= ~P_SYSTEM;
212 #endif
213 }
214
215 #if !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV)
216 /* set the real time */
217 void
218 afs_osi_SetTime(osi_timeval_t * atv)
219 {
220 #if defined(AFS_AIX32_ENV)
221     struct timestruc_t t;
222
223     t.tv_sec = atv->tv_sec;
224     t.tv_nsec = atv->tv_usec * 1000;
225     ksettimer(&t);              /*  Was -> settimer(TIMEOFDAY, &t); */
226 #elif defined(AFS_SUN55_ENV)
227     stime(atv->tv_sec);
228 #elif defined(AFS_SUN5_ENV)
229     /*
230      * To get more than second resolution we can use adjtime. The problem
231      * is that the usecs from the server are wrong (by now) so it isn't
232      * worth complicating the following code.
233      */
234     struct stimea {
235         time_t time;
236     } sta;
237
238     sta.time = atv->tv_sec;
239
240     stime(&sta, NULL);
241 #elif defined(AFS_SGI_ENV)
242     struct stimea {
243         sysarg_t time;
244     } sta;
245
246     AFS_GUNLOCK();
247     sta.time = atv->tv_sec;
248     stime(&sta);
249     AFS_GLOCK();
250 #elif defined(AFS_DARWIN_ENV)
251 #ifndef AFS_DARWIN80_ENV
252     AFS_GUNLOCK();
253     setthetime(atv);
254     AFS_GLOCK();
255 #endif
256 #else
257     /* stolen from kern_time.c */
258 #ifndef AFS_AUX_ENV
259     boottime.tv_sec += atv->tv_sec - time.tv_sec;
260 #endif
261 #ifdef AFS_HPUX_ENV
262     {
263 #if !defined(AFS_HPUX1122_ENV)
264         /* drop the setting of the clock for now. spl7 is not
265          * known on hpux11.22
266          */
267         register ulong_t s;
268         struct timeval t;
269         t.tv_sec = atv->tv_sec;
270         t.tv_usec = atv->tv_usec;
271         s = spl7();
272         time = t;
273         (void)splx(s);
274         resettodr(atv);
275 #endif
276     }
277 #else
278     {
279         register int s;
280         s = splclock();
281         time = *atv;
282         (void)splx(s);
283     }
284     resettodr();
285 #endif
286 #ifdef  AFS_AUX_ENV
287     logtchg(atv->tv_sec);
288 #endif
289 #endif /* AFS_DARWIN_ENV */
290     AFS_STATCNT(osi_SetTime);
291 }
292 #endif /* AFS_LINUX20_ENV */
293
294
295 void
296 shutdown_osi(void)
297 {
298     AFS_STATCNT(shutdown_osi);
299 #ifdef AFS_DARWIN80_ENV
300     if (afs_osi_ctxtp_initialized && afs_osi_ctxtp) {
301        vfs_context_rele(afs_osi_ctxtp);
302        afs_osi_ctxtp = NULL;
303        afs_osi_ctxtp_initialized = 0;
304     }
305     shutdown_osisleep();
306 #endif
307     if (afs_cold_shutdown) {
308         LOCK_INIT(&afs_ftf, "afs_ftf");
309     }
310 }
311
312 #ifndef AFS_OBSD_ENV
313 int
314 afs_osi_suser(void *cr)
315 {
316 #if defined(AFS_SUN510_ENV)
317     return (priv_policy(cr, PRIV_SYS_SUSER_COMPAT, B_FALSE, EPERM, NULL) == 0);
318 #elif defined(AFS_SUN5_ENV)
319     return afs_suser(cr);
320 #else
321     return afs_suser(NULL);
322 #endif
323 }
324 #endif