Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 257075 | Differences between
and this patch

Collapse All | Expand All

(-)a/api-auth.c (+31 lines)
Lines 494-499 pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) Link Here
494
    if (reinit) {
494
    if (reinit) {
495
        const char *name, *k5name;
495
        const char *name, *k5name;
496
496
497
        /*
498
         * Solaris su calls pam_setcred as root with PAM_REINITIALIZE_CREDS,
499
         * preserving the user-supplied environment.  An xlock program may
500
         * also do this if it's setuid root and doesn't drop credentials
501
         * before calling pam_setcred.
502
         *
503
         * There isn't any safe way of reinitializing the exiting ticket cache
504
         * for the user if we're setuid without calling setreuid().  Calling
505
         * setreuid() is possible, but if the calling application is threaded,
506
         * it will change credentials for the whole application, with possibly
507
         * bizarre and unintended (and insecure) results.  Trying to verify
508
         * ownership of the existing ticket cache before using it fails under
509
         * various race conditions (for example, having one of the elements of
510
         * the path be a symlink and changing the target of that symlink
511
         * between our check and the call to krb5_cc_resolve.  Without calling
512
         * setreuid(), we run the risk of replacing a file owned by another
513
         * user with a credential cache.
514
         *
515
         * We could fail with an error in the setuid case, which would be
516
         * maximally safe, but it would prevent use of the module for
517
         * authentication with programs such as Solaris su.  Failure to
518
         * reinitialize the cache is normally not a serious problem, just a
519
         * missing feature.  We therefore log an error and exit with
520
         * PAM_SUCCESS for the setuid case.
521
         */
522
        if (pamk5_compat_issetugid()) {
523
            pamk5_error(args, "credential reinitialization in a setuid"
524
                        " context ignored");
525
            pamret = PAM_SUCCESS;
526
            goto done;
527
        }
497
        name = pamk5_get_krb5ccname(args, "KRB5CCNAME");
528
        name = pamk5_get_krb5ccname(args, "KRB5CCNAME");
498
        if (name == NULL)
529
        if (name == NULL)
499
            name = krb5_cc_default_name(ctx->context);
530
            name = krb5_cc_default_name(ctx->context);
(-)a/compat.c (-8 / +47 lines)
Lines 24-29 Link Here
24
# include <security/pam_modutil.h>
24
# include <security/pam_modutil.h>
25
#endif
25
#endif
26
#include <stdlib.h>
26
#include <stdlib.h>
27
#include <unistd.h>
27
28
28
#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT)
29
#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT)
29
# if !defined(HAVE_KRB5_GET_ERROR_STRING)
30
# if !defined(HAVE_KRB5_GET_ERROR_STRING)
Lines 146-151 pamk5_compat_free_error(krb5_context ctx, const char *msg) Link Here
146
147
147
148
148
/*
149
/*
150
 * AIX's NAS Kerberos implementation mysteriously provides the struct and the
151
 * krb5_verify_init_creds function but not this function.
152
 */
153
#ifndef HAVE_KRB5_VERIFY_INIT_CREDS_OPT_INIT
154
void
155
krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt *opt)
156
{
157
    opt->flags = 0;
158
    opt->ap_req_nofail = 0;
159
}
160
#endif
161
162
163
/*
164
 * MIT provides a krb5_init_secure_context that ignores all the environment
165
 * variables that may otherwise influence context creation.  We call that
166
 * function if we detect that we're setuid.  Heimdal doesn't have this
167
 * function, but instead automatically ignores the environment variables if it
168
 * detects we're setuid.  This means that we should be able to fall back
169
 * safely to krb5_init_context if krb5_init_secure_context isn't available.
170
 */
171
krb5_error_code
172
pamk5_compat_secure_context(krb5_context *ctx)
173
{
174
#ifdef HAVE_KRB5_INIT_SECURE_CONTEXT
175
    return krb5_init_secure_context(ctx);
176
#else
177
    return krb5_init_context(ctx);
178
#endif
179
}
180
181
182
/*
149
 * Linux PAM provides a thread-safe version of getpwnam that we want to use if
183
 * Linux PAM provides a thread-safe version of getpwnam that we want to use if
150
 * available.  If it's not, fall back on getpwnam.  (Ideally, we should check
184
 * available.  If it's not, fall back on getpwnam.  (Ideally, we should check
151
 * for getpwnam_r and use it, but I haven't written that routine.)
185
 * for getpwnam_r and use it, but I haven't written that routine.)
Lines 162-175 pamk5_compat_getpwnam(struct pam_args *args UNUSED, const char *user) Link Here
162
196
163
197
164
/*
198
/*
165
 * AIX's NAS Kerberos implementation mysteriously provides the struct and the
199
 * Call the Solaris issetugid function if available.  If not, check whether
166
 * krb5_verify_init_creds function but not this function.
200
 * the real and effective UIDs and GIDs match.
167
 */
201
 */
168
#ifndef HAVE_KRB5_VERIFY_INIT_CREDS_OPT_INIT
202
int
169
void
203
pamk5_compat_issetugid(void)
170
krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt *opt)
171
{
204
{
172
    opt->flags = 0;
205
#ifdef HAVE_ISSETUGID
173
    opt->ap_req_nofail = 0;
206
    return issetugid();
174
}
207
#else
208
    if (getuid() != geteuid())
209
        return 1;
210
    if (getgid() != getegid())
211
        return 1;
212
    return 0;
175
#endif
213
#endif
214
}
(-)a/configure.ac (+5 lines)
Lines 21-26 AC_PROG_MAKE_SET Link Here
21
AC_CANONICAL_HOST
22
AC_CANONICAL_HOST
22
AC_AIX
23
AC_AIX
23
24
25
dnl Check for the Solaris issetugid function, which is nicer than comparing
26
dnl real and effective UIDs and GIDs.
27
AC_CHECK_FUNCS([issetugid])
28
24
dnl Probe for the functionality of the PAM libraries and their include file
29
dnl Probe for the functionality of the PAM libraries and their include file
25
dnl naming.  Mac OS X puts them in pam/* instead of security/*.
30
dnl naming.  Mac OS X puts them in pam/* instead of security/*.
26
AC_SEARCH_LIBS([pam_set_data], [pam])
31
AC_SEARCH_LIBS([pam_set_data], [pam])
Lines 46-51 AC_CHECK_FUNCS([krb5_appdefault_string \ Link Here
46
    krb5_get_init_creds_opt_set_change_password_prompt \
51
    krb5_get_init_creds_opt_set_change_password_prompt \
47
    krb5_get_init_creds_opt_set_default_flags \
52
    krb5_get_init_creds_opt_set_default_flags \
48
    krb5_get_init_creds_opt_set_pa \
53
    krb5_get_init_creds_opt_set_pa \
54
    krb5_init_secure_context \
49
    krb5_verify_init_creds_opt_init])
55
    krb5_verify_init_creds_opt_init])
50
AC_CHECK_FUNCS([krb5_get_init_creds_opt_set_pkinit],
56
AC_CHECK_FUNCS([krb5_get_init_creds_opt_set_pkinit],
51
    [RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT_ARGS])
57
    [RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT_ARGS])
(-)a/context.c (-1 / +4 lines)
Lines 66-72 pamk5_context_new(struct pam_args *args) Link Here
66
        goto done;
66
        goto done;
67
    }
67
    }
68
    ctx->name = strdup(name);
68
    ctx->name = strdup(name);
69
    retval = krb5_init_context(&ctx->context);
69
    if (pamk5_compat_issetugid())
70
        retval = pamk5_compat_secure_context(&ctx->context);
71
    else
72
        retval = krb5_init_context(&ctx->context);
70
    if (retval != 0) {
73
    if (retval != 0) {
71
        pamk5_error_krb5(args, "krb5_init_context", retval);
74
        pamk5_error_krb5(args, "krb5_init_context", retval);
72
        retval = PAM_SERVICE_ERR;
75
        retval = PAM_SERVICE_ERR;
(-)a/internal.h (+6 lines)
Lines 247-252 krb5_error_code pamk5_compat_set_realm(struct pam_args *, const char *) Link Here
247
    __attribute__((__visibility__("hidden")));
247
    __attribute__((__visibility__("hidden")));
248
void pamk5_compat_free_realm(struct pam_args *)
248
void pamk5_compat_free_realm(struct pam_args *)
249
    __attribute__((__visibility__("hidden")));
249
    __attribute__((__visibility__("hidden")));
250
krb5_error_code pamk5_compat_secure_context(krb5_context *)
251
    __attribute__((__visibility__("hidden")));
252
253
/* Calls issetugid if available, otherwise checks effective IDs. */
254
int pamk5_compat_issetugid(void)
255
    __attribute__((__visibility__("hidden")));
250
256
251
/* Calls pam_modutil_getpwnam if available, otherwise getpwnam. */
257
/* Calls pam_modutil_getpwnam if available, otherwise getpwnam. */
252
struct passwd *pamk5_compat_getpwnam(struct pam_args *, const char *)
258
struct passwd *pamk5_compat_getpwnam(struct pam_args *, const char *)
(-)a/options.c (-1 / +4 lines)
Lines 276-282 pamk5_args_parse(pam_handle_t *pamh, int flags, int argc, const char **argv) Link Here
276
     * proceed; we'll die soon enough later and this way we'll die after we
276
     * proceed; we'll die soon enough later and this way we'll die after we
277
     * know whether to debug things.
277
     * know whether to debug things.
278
     */
278
     */
279
    retval = krb5_init_context(&c);
279
    if (pamk5_compat_issetugid())
280
        retval = pamk5_compat_secure_context(&c);
281
    else
282
        retval = krb5_init_context(&c);
280
    if (retval != 0)
283
    if (retval != 0)
281
        c = NULL;
284
        c = NULL;
282
    if (c != NULL) {
285
    if (c != NULL) {

Return to bug 257075