~ubuntu-branches/ubuntu/raring/openafs/raring

« back to all changes in this revision

Viewing changes to .pc/3.8-compat/src/afs/LINUX/osi_groups.c

  • Committer: Package Import Robot
  • Author(s): Luke Faraone
  • Date: 2013-03-05 01:01:49 UTC
  • mfrom: (44.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130305010149-3ui1dhq9a2fw9abp
Tags: 1.6.2-1+ubuntu2
Explicitly include -pthread in UAFS_XLIBS to fix build failure

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 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
/*
 
11
 * Implements:
 
12
 * setgroups (syscall)
 
13
 * setpag
 
14
 *
 
15
 */
 
16
#include <afsconfig.h>
 
17
#include "afs/param.h"
 
18
#ifdef LINUX_KEYRING_SUPPORT
 
19
#include <linux/seq_file.h>
 
20
#endif
 
21
 
 
22
 
 
23
#include "afs/sysincludes.h"
 
24
#include "afsincludes.h"
 
25
#include "afs/afs_stats.h"      /* statistics */
 
26
#include "afs/nfsclient.h"
 
27
#include "osi_compat.h"
 
28
 
 
29
#ifdef AFS_LINUX26_ONEGROUP_ENV
 
30
# define NUMPAGGROUPS 1
 
31
 
 
32
static afs_uint32
 
33
afs_linux_pag_from_groups(struct group_info *group_info) {
 
34
    afs_uint32 g0 = 0;
 
35
    afs_uint32 i;
 
36
 
 
37
    if (group_info->ngroups < NUMPAGGROUPS)
 
38
        return NOPAG;
 
39
 
 
40
    for (i = 0; (i < group_info->ngroups &&
 
41
                 (g0 = GROUP_AT(group_info, i)) != (gid_t) NOGROUP); i++) {
 
42
        if (((g0 >> 24) & 0xff) == 'A')
 
43
            return g0;
 
44
    }
 
45
    return NOPAG;
 
46
}
 
47
 
 
48
static inline void
 
49
afs_linux_pag_to_groups(afs_uint32 newpag,
 
50
                        struct group_info *old, struct group_info **new) {
 
51
    int need_space = 0;
 
52
    int i;
 
53
    int j;
 
54
 
 
55
    if (afs_linux_pag_from_groups(old) == NOPAG)
 
56
        need_space = NUMPAGGROUPS;
 
57
 
 
58
    *new = groups_alloc(old->ngroups + need_space);
 
59
 
 
60
    for (i = 0, j = 0; i < old->ngroups; ++i) {
 
61
        int ths = GROUP_AT(old, i);
 
62
        int last = i > 0 ? GROUP_AT(old, i-1) : 0;
 
63
        if ((ths >> 24) == 'A')
 
64
            continue;
 
65
        if (last <= newpag && ths > newpag) {
 
66
           GROUP_AT(*new, j) = newpag;
 
67
           j++;
 
68
        }
 
69
        GROUP_AT(*new, j) = ths;
 
70
        j++;
 
71
    }
 
72
    if (j != i + need_space)
 
73
        GROUP_AT(*new, j) = newpag;
 
74
}
 
75
 
 
76
#else
 
77
# define NUMPAGGROUPS 2
 
78
 
 
79
static inline afs_uint32
 
80
afs_linux_pag_from_groups(struct group_info *group_info) {
 
81
 
 
82
    if (group_info->ngroups < NUMPAGGROUPS)
 
83
        return NOPAG;
 
84
 
 
85
    return afs_get_pag_from_groups(GROUP_AT(group_info, 0), GROUP_AT(group_info, 1));
 
86
}
 
87
 
 
88
static inline void
 
89
afs_linux_pag_to_groups(afs_uint32 newpag,
 
90
                        struct group_info *old, struct group_info **new) {
 
91
    int need_space = 0;
 
92
    int i;
 
93
    gid_t g0;
 
94
    gid_t g1;
 
95
 
 
96
    if (afs_linux_pag_from_groups(old) == NOPAG)
 
97
        need_space = NUMPAGGGROUPS;
 
98
 
 
99
    *new = groups_alloc(old->ngroups + need_space);
 
100
 
 
101
    for (i = 0; i < old->ngroups; ++i)
 
102
          GROUP_AT(new, i + need_space) = GROUP_AT(old, i);
 
103
 
 
104
    afs_get_groups_from_pag(newpag, &g0, g1);
 
105
    GROUP_AT(new, 0) = g0;
 
106
    GROUP_AT(new, 1) = g1;
 
107
}
 
108
#endif
 
109
 
 
110
afs_int32
 
111
osi_get_group_pag(afs_ucred_t *cred) {
 
112
    return afs_linux_pag_from_groups(afs_cr_group_info(cred));
 
113
}
 
114
 
 
115
 
 
116
static int
 
117
afs_setgroups(cred_t **cr, struct group_info *group_info, int change_parent)
 
118
{
 
119
    struct group_info *old_info;
 
120
 
 
121
    AFS_STATCNT(afs_setgroups);
 
122
 
 
123
    old_info = afs_cr_group_info(*cr);
 
124
    get_group_info(group_info);
 
125
    afs_set_cr_group_info(*cr, group_info);
 
126
    put_group_info(old_info);
 
127
 
 
128
    crset(*cr);
 
129
 
 
130
#if defined(STRUCT_TASK_STRUCT_HAS_PARENT) && !defined(STRUCT_TASK_STRUCT_HAS_CRED)
 
131
    if (change_parent) {
 
132
        old_info = current->parent->group_info;
 
133
        get_group_info(group_info);
 
134
        current->parent->group_info = group_info;
 
135
        put_group_info(old_info);
 
136
    }
 
137
#endif
 
138
 
 
139
    return (0);
 
140
}
 
141
 
 
142
int
 
143
__setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag,
 
144
         int change_parent, struct group_info **old_groups)
 
145
{
 
146
    struct group_info *group_info;
 
147
    struct group_info *tmp;
 
148
 
 
149
    get_group_info(afs_cr_group_info(*cr));
 
150
    group_info = afs_cr_group_info(*cr);
 
151
 
 
152
    *newpag = (pagvalue == -1 ? genpag() : pagvalue);
 
153
    afs_linux_pag_to_groups(*newpag, group_info, &tmp);
 
154
 
 
155
    if (old_groups) {
 
156
        *old_groups = group_info;
 
157
    } else {
 
158
        put_group_info(group_info);
 
159
        group_info = NULL;
 
160
    }
 
161
 
 
162
    afs_setgroups(cr, tmp, change_parent);
 
163
 
 
164
    put_group_info(tmp);
 
165
 
 
166
    return 0;
 
167
}
 
168
 
 
169
#ifdef LINUX_KEYRING_SUPPORT
 
170
extern struct key_type key_type_keyring __attribute__((weak));
 
171
static struct key_type *__key_type_keyring = &key_type_keyring;
 
172
 
 
173
/* install_session_keyring returns negative error values */
 
174
static int
 
175
install_session_keyring(struct key *keyring)
 
176
{
 
177
    struct key *old;
 
178
    char desc[20];
 
179
    int code = -EINVAL;
 
180
    unsigned long flags;
 
181
 
 
182
    if (!__key_type_keyring)
 
183
        return code;
 
184
 
 
185
    if (!keyring) {
 
186
 
 
187
        /* create an empty session keyring */
 
188
        sprintf(desc, "_ses.%u", current->tgid);
 
189
 
 
190
        /* if we're root, don't count the keyring against our quota. This
 
191
         * avoids starvation issues when dealing with PAM modules that always
 
192
         * setpag() as root */
 
193
        if (current_uid() == 0)
 
194
            flags = KEY_ALLOC_NOT_IN_QUOTA;
 
195
        else
 
196
            flags = KEY_ALLOC_IN_QUOTA;
 
197
 
 
198
        keyring = afs_linux_key_alloc(
 
199
                            __key_type_keyring, desc,
 
200
                            current_uid(), current_gid(),
 
201
                            (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
 
202
                            flags);
 
203
 
 
204
        if (IS_ERR(keyring)) {
 
205
            code = PTR_ERR(keyring);
 
206
            goto out;
 
207
        }
 
208
    }
 
209
 
 
210
    code = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
 
211
    if (code < 0) {
 
212
        key_put(keyring);
 
213
        goto out;
 
214
    }
 
215
 
 
216
    /* install the keyring */
 
217
    spin_lock_irq(&current->sighand->siglock);
 
218
    old = task_session_keyring(current);
 
219
    smp_wmb();
 
220
    task_session_keyring(current) = keyring;
 
221
    spin_unlock_irq(&current->sighand->siglock);
 
222
 
 
223
    if (old)
 
224
            key_put(old);
 
225
 
 
226
out:
 
227
    return code;
 
228
}
 
229
#endif /* LINUX_KEYRING_SUPPORT */
 
230
 
 
231
/* Error codes from setpag must be positive, otherwise they don't
 
232
 * make it back into userspace properly. Error codes from the
 
233
 * Linux keyring utilities, and from install_session_keyring()
 
234
 * are negative. So we need to be careful to convert them correctly
 
235
 * here
 
236
 */
 
237
int
 
238
setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag,
 
239
       int change_parent)
 
240
{
 
241
    int code;
 
242
    struct group_info *old_groups = NULL;
 
243
 
 
244
    AFS_STATCNT(setpag);
 
245
 
 
246
    code = __setpag(cr, pagvalue, newpag, change_parent, &old_groups);
 
247
 
 
248
#ifdef LINUX_KEYRING_SUPPORT
 
249
    if (code == 0 && afs_cr_rgid(*cr) != NFSXLATOR_CRED) {
 
250
        code = install_session_keyring(NULL);
 
251
        if (code == 0 && current_session_keyring()) {
 
252
            struct key *key;
 
253
            key_perm_t perm;
 
254
 
 
255
            perm = KEY_POS_VIEW | KEY_POS_SEARCH;
 
256
            perm |= KEY_USR_VIEW | KEY_USR_SEARCH;
 
257
 
 
258
            key = afs_linux_key_alloc(&key_type_afs_pag, "_pag", 0, 0, perm, KEY_ALLOC_NOT_IN_QUOTA);
 
259
 
 
260
            if (!IS_ERR(key)) {
 
261
                key_instantiate_and_link(key, (void *) newpag, sizeof(afs_uint32),
 
262
                                         current_session_keyring(), NULL);
 
263
                key_put(key);
 
264
            } else {
 
265
                code = PTR_ERR(key);
 
266
            }
 
267
        }
 
268
        if (code)
 
269
            code = -code;
 
270
    }
 
271
#endif /* LINUX_KEYRING_SUPPORT */
 
272
 
 
273
    if (code) {
 
274
        if (old_groups) {
 
275
            afs_setgroups(cr, old_groups, change_parent);
 
276
            put_group_info(old_groups);
 
277
            old_groups = NULL;
 
278
        }
 
279
        if (*newpag > -1) {
 
280
            afs_MarkUserExpired(*newpag);
 
281
            *newpag = -1;
 
282
        }
 
283
    }
 
284
 
 
285
    return code;
 
286
}
 
287
 
 
288
 
 
289
/* Intercept the standard system call. */
 
290
extern asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist);
 
291
asmlinkage long
 
292
afs_xsetgroups(int gidsetsize, gid_t * grouplist)
 
293
{
 
294
    long code;
 
295
    cred_t *cr = crref();
 
296
    afs_uint32 junk;
 
297
    int old_pag;
 
298
 
 
299
    old_pag = PagInCred(cr);
 
300
    crfree(cr);
 
301
 
 
302
    code = (*sys_setgroupsp) (gidsetsize, grouplist);
 
303
    if (code) {
 
304
        return code;
 
305
    }
 
306
 
 
307
    cr = crref();
 
308
    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
 
309
        /* re-install old pag if there's room. */
 
310
        code = __setpag(&cr, old_pag, &junk, 0, NULL);
 
311
    }
 
312
    crfree(cr);
 
313
 
 
314
    /* Linux syscall ABI returns errno as negative */
 
315
    return (-code);
 
316
}
 
317
 
 
318
/* Intercept the standard uid32 system call. */
 
319
extern asmlinkage int (*sys_setgroups32p) (int gidsetsize,
 
320
                                           __kernel_gid32_t * grouplist);
 
321
asmlinkage long
 
322
afs_xsetgroups32(int gidsetsize, gid_t * grouplist)
 
323
{
 
324
    long code;
 
325
    cred_t *cr = crref();
 
326
    afs_uint32 junk;
 
327
    int old_pag;
 
328
 
 
329
    old_pag = PagInCred(cr);
 
330
    crfree(cr);
 
331
 
 
332
    code = (*sys_setgroups32p) (gidsetsize, grouplist);
 
333
 
 
334
    if (code) {
 
335
        return code;
 
336
    }
 
337
 
 
338
    cr = crref();
 
339
    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
 
340
        /* re-install old pag if there's room. */
 
341
        code = __setpag(&cr, old_pag, &junk, 0, NULL);
 
342
    }
 
343
    crfree(cr);
 
344
 
 
345
    /* Linux syscall ABI returns errno as negative */
 
346
    return (-code);
 
347
}
 
348
 
 
349
#if defined(AFS_PPC64_LINUX20_ENV)
 
350
/* Intercept the uid16 system call as used by 32bit programs. */
 
351
extern asmlinkage long (*sys32_setgroupsp)(int gidsetsize, gid_t *grouplist);
 
352
asmlinkage long afs32_xsetgroups(int gidsetsize, gid_t *grouplist)
 
353
{
 
354
    long code;
 
355
    cred_t *cr = crref();
 
356
    afs_uint32 junk;
 
357
    int old_pag;
 
358
    
 
359
    old_pag = PagInCred(cr);
 
360
    crfree(cr);
 
361
    
 
362
    code = (*sys32_setgroupsp)(gidsetsize, grouplist);
 
363
    if (code) {
 
364
        return code;
 
365
    }
 
366
    
 
367
    cr = crref();
 
368
    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
 
369
        /* re-install old pag if there's room. */
 
370
        code = __setpag(&cr, old_pag, &junk, 0, NULL);
 
371
    }
 
372
    crfree(cr);
 
373
    
 
374
    /* Linux syscall ABI returns errno as negative */
 
375
    return (-code);
 
376
}
 
377
#endif
 
378
 
 
379
#if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_AMD64_LINUX20_ENV)
 
380
/* Intercept the uid16 system call as used by 32bit programs. */
 
381
#ifdef AFS_AMD64_LINUX20_ENV
 
382
extern asmlinkage long (*sys32_setgroupsp) (int gidsetsize, u16 * grouplist);
 
383
#endif /* AFS_AMD64_LINUX20_ENV */
 
384
#ifdef AFS_SPARC64_LINUX26_ENV
 
385
extern asmlinkage int (*sys32_setgroupsp) (int gidsetsize,
 
386
                                           __kernel_gid32_t * grouplist);
 
387
#endif /* AFS_SPARC64_LINUX26_ENV */
 
388
asmlinkage long
 
389
afs32_xsetgroups(int gidsetsize, u16 * grouplist)
 
390
{
 
391
    long code;
 
392
    cred_t *cr = crref();
 
393
    afs_uint32 junk;
 
394
    int old_pag;
 
395
    
 
396
    old_pag = PagInCred(cr);
 
397
    crfree(cr);
 
398
    
 
399
    code = (*sys32_setgroupsp) (gidsetsize, grouplist);
 
400
    if (code) {
 
401
        return code;
 
402
    }
 
403
    
 
404
    cr = crref();
 
405
    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
 
406
        /* re-install old pag if there's room. */
 
407
        code = __setpag(&cr, old_pag, &junk, 0, NULL);
 
408
    }
 
409
    crfree(cr);
 
410
    
 
411
    /* Linux syscall ABI returns errno as negative */
 
412
    return (-code);
 
413
}
 
414
 
 
415
/* Intercept the uid32 system call as used by 32bit programs. */
 
416
#ifdef AFS_AMD64_LINUX20_ENV
 
417
extern asmlinkage long (*sys32_setgroups32p) (int gidsetsize, gid_t * grouplist);
 
418
#endif /* AFS_AMD64_LINUX20_ENV */
 
419
#ifdef AFS_SPARC64_LINUX26_ENV
 
420
extern asmlinkage int (*sys32_setgroups32p) (int gidsetsize,
 
421
                                             __kernel_gid32_t * grouplist);
 
422
#endif /* AFS_SPARC64_LINUX26_ENV */
 
423
asmlinkage long
 
424
afs32_xsetgroups32(int gidsetsize, gid_t * grouplist)
 
425
{
 
426
    long code;
 
427
    cred_t *cr = crref();
 
428
    afs_uint32 junk;
 
429
    int old_pag;
 
430
 
 
431
    old_pag = PagInCred(cr);
 
432
    crfree(cr);
 
433
 
 
434
    code = (*sys32_setgroups32p) (gidsetsize, grouplist);
 
435
    if (code) {
 
436
        return code;
 
437
    }
 
438
 
 
439
    cr = crref();
 
440
    if (old_pag != NOPAG && PagInCred(cr) == NOPAG) {
 
441
        /* re-install old pag if there's room. */
 
442
        code = __setpag(&cr, old_pag, &junk, 0, NULL);
 
443
    }
 
444
    crfree(cr);
 
445
 
 
446
    /* Linux syscall ABI returns errno as negative */
 
447
    return (-code);
 
448
}
 
449
#endif
 
450
 
 
451
 
 
452
#ifdef LINUX_KEYRING_SUPPORT
 
453
static void afs_pag_describe(const struct key *key, struct seq_file *m)
 
454
{
 
455
    seq_puts(m, key->description);
 
456
 
 
457
    seq_printf(m, ": %u", key->datalen);
 
458
}
 
459
 
 
460
#if defined(STRUCT_KEY_TYPE_HAS_PREPARSE)
 
461
static int afs_pag_instantiate(struct key *key, struct key_preparsed_payload *prep)
 
462
#else
 
463
static int afs_pag_instantiate(struct key *key, const void *data, size_t datalen)
 
464
#endif
 
465
{
 
466
    int code;
 
467
    afs_uint32 *userpag, pag = NOPAG;
 
468
 
 
469
    if (key->uid != 0 || key->gid != 0)
 
470
        return -EPERM;
 
471
 
 
472
    code = -EINVAL;
 
473
    get_group_info(current_group_info());
 
474
 
 
475
#if defined(STRUCT_KEY_TYPE_HAS_PREPARSE)
 
476
    if (prep->datalen != sizeof(afs_uint32) || !prep->data)
 
477
#else
 
478
    if (datalen != sizeof(afs_uint32) || !data)
 
479
#endif
 
480
        goto error;
 
481
 
 
482
    /* ensure key being set matches current pag */
 
483
    pag = afs_linux_pag_from_groups(current_group_info());
 
484
 
 
485
    if (pag == NOPAG)
 
486
        goto error;
 
487
 
 
488
#if defined(STRUCT_KEY_TYPE_HAS_PREPARSE)
 
489
    userpag = (afs_uint32 *)prep->data;
 
490
#else
 
491
    userpag = (afs_uint32 *)data;
 
492
#endif
 
493
    if (*userpag != pag)
 
494
        goto error;
 
495
 
 
496
    key->payload.value = (unsigned long) *userpag;
 
497
    key->datalen = sizeof(afs_uint32);
 
498
    code = 0;
 
499
 
 
500
error:
 
501
    put_group_info(current_group_info());
 
502
    return code;
 
503
}
 
504
 
 
505
static int afs_pag_match(const struct key *key, const void *description)
 
506
{
 
507
        return strcmp(key->description, description) == 0;
 
508
}
 
509
 
 
510
static void afs_pag_destroy(struct key *key)
 
511
{
 
512
    afs_uint32 pag = key->payload.value;
 
513
    int locked = ISAFS_GLOCK();
 
514
 
 
515
    if (!locked)
 
516
        AFS_GLOCK();
 
517
 
 
518
    afs_MarkUserExpired(pag);
 
519
 
 
520
    if (!locked)
 
521
        AFS_GUNLOCK();
 
522
}
 
523
 
 
524
struct key_type key_type_afs_pag =
 
525
{
 
526
    .name        = "afs_pag",
 
527
    .describe    = afs_pag_describe,
 
528
    .instantiate = afs_pag_instantiate,
 
529
    .match       = afs_pag_match,
 
530
    .destroy     = afs_pag_destroy,
 
531
};
 
532
 
 
533
#ifdef EXPORTED_TASKLIST_LOCK
 
534
extern rwlock_t tasklist_lock __attribute__((weak));
 
535
#endif
 
536
 
 
537
void osi_keyring_init(void)
 
538
{
 
539
#if !defined(EXPORTED_KEY_TYPE_KEYRING)
 
540
    struct task_struct *p;
 
541
 
 
542
    /* If we can't lock the tasklist, either with its explicit lock,
 
543
     * or by using the RCU lock, then we can't safely work out the 
 
544
     * type of a keyring. So, we have to rely on the weak reference. 
 
545
     * If that's not available, then keyring based PAGs won't work.
 
546
     */
 
547
    
 
548
#if defined(EXPORTED_TASKLIST_LOCK) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) && defined(HAVE_LINUX_RCU_READ_LOCK))
 
549
    if (__key_type_keyring == NULL) {
 
550
# ifdef EXPORTED_TASKLIST_LOCK
 
551
        if (&tasklist_lock)
 
552
            read_lock(&tasklist_lock);
 
553
# endif
 
554
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) && defined(HAVE_LINUX_RCU_READ_LOCK))
 
555
#  ifdef EXPORTED_TASKLIST_LOCK
 
556
        else
 
557
#  endif
 
558
            rcu_read_lock();
 
559
# endif
 
560
#if defined(HAVE_LINUX_FIND_TASK_BY_PID)
 
561
        p = find_task_by_pid(1);
 
562
#else
 
563
        p = find_task_by_vpid(1);
 
564
#endif
 
565
        if (p && task_user(p)->session_keyring)
 
566
            __key_type_keyring = task_user(p)->session_keyring->type;
 
567
# ifdef EXPORTED_TASKLIST_LOCK
 
568
        if (&tasklist_lock)
 
569
            read_unlock(&tasklist_lock);
 
570
# endif
 
571
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) && defined(HAVE_LINUX_RCU_READ_LOCK))
 
572
#  ifdef EXPORTED_TASKLIST_LOCK
 
573
        else
 
574
#  endif
 
575
            rcu_read_unlock();
 
576
# endif
 
577
    }
 
578
#endif
 
579
#endif
 
580
 
 
581
    register_key_type(&key_type_afs_pag);
 
582
}
 
583
 
 
584
void osi_keyring_shutdown(void)
 
585
{
 
586
    unregister_key_type(&key_type_afs_pag);
 
587
}
 
588
 
 
589
afs_int32
 
590
osi_get_keyring_pag(afs_ucred_t *cred)
 
591
{
 
592
    struct key *key;
 
593
    afs_uint32 newpag;
 
594
    afs_int32 keyring_pag = NOPAG;
 
595
 
 
596
    if (afs_cr_rgid(cred) != NFSXLATOR_CRED) {
 
597
        key = afs_linux_search_keyring(cred, &key_type_afs_pag);
 
598
 
 
599
        if (!IS_ERR(key)) {
 
600
            if (key_validate(key) == 0 && key->uid == 0) {      /* also verify in the session keyring? */
 
601
                keyring_pag = key->payload.value;
 
602
                /* Only set PAG in groups if needed,
 
603
                 * and the creds are from the current process */
 
604
                if (afs_linux_cred_is_current(cred) &&
 
605
                    ((keyring_pag >> 24) & 0xff) == 'A' &&
 
606
                    keyring_pag != afs_linux_pag_from_groups(current_group_info())) {
 
607
                        __setpag(&cred, keyring_pag, &newpag, 0, NULL);
 
608
                }
 
609
            }
 
610
            key_put(key);
 
611
        }
 
612
    }
 
613
    return keyring_pag;
 
614
}
 
615
 
 
616
#else
 
617
void osi_keyring_init(void)
 
618
{
 
619
        return;
 
620
}
 
621
 
 
622
void osi_keyring_shutdown(void)
 
623
{
 
624
        return;
 
625
}
 
626
#endif