示例#1
0
文件: pam_gss.c 项目: PADL/pam_gss
static int
pamGssAcquireCred(pam_handle_t *pamh,
                  int confFlags,
                  gss_name_t userName,
                  gss_buffer_t passwordBuf,
                  gss_OID mech,
                  gss_cred_id_t *cred)
{
    int status;
    OM_uint32 major, minor;
    gss_OID_set_desc mechOids;
#ifdef __APPLE__
    CFDictionaryRef attributes = NULL;

    status = pam_get_data(pamh, CREDUI_ATTR_DATA, (const void **)&attributes);
    if (status == PAM_SUCCESS)
        return pamGssAcquireAaplInitialCred(pamh, userName, mech, attributes, cred);
#endif /* __APPLE__ */

    mechOids.count = 1;
    mechOids.elements = mech;

    major = gss_acquire_cred_with_password(&minor, userName, passwordBuf,
                                           GSS_C_INDEFINITE, &mechOids,
                                           GSS_C_INITIATE, cred, NULL, NULL);
    BAIL_ON_GSS_ERROR(major, minor);

    status = PAM_SUCCESS;

cleanup:
    return status;
}
示例#2
0
DWORD
LwKrb5SetThreadDefaultCachePath(
    IN PCSTR pszCachePath,
    OUT PSTR* ppszPreviousCachePath
    )
{
    DWORD dwError       = 0;
    DWORD dwMajorStatus = 0;
    DWORD dwMinorStatus = 0;
    PSTR  pszOrigCachePath = NULL;

    // Set the default for gss
    dwMajorStatus = gss_krb5_ccache_name(
                            (OM_uint32 *)&dwMinorStatus,
                            pszCachePath,
                            (ppszPreviousCachePath) ? (const char**)&pszOrigCachePath : NULL);
    BAIL_ON_GSS_ERROR(dwError, dwMajorStatus, dwMinorStatus);

    LW_LOG_DEBUG("Switched gss krb5 credentials path from %s to %s",
            LW_SAFE_LOG_STRING(pszOrigCachePath),
            LW_SAFE_LOG_STRING(pszCachePath));
    
    if (ppszPreviousCachePath) {
        if (!LW_IS_NULL_OR_EMPTY_STR(pszOrigCachePath)) {
            dwError = LwAllocateString(pszOrigCachePath, ppszPreviousCachePath);
            BAIL_ON_LW_ERROR(dwError);
        } else {
            *ppszPreviousCachePath = NULL;
        }
    }
    
cleanup:

    return dwError;
    
error:

    if (ppszPreviousCachePath) {
        *ppszPreviousCachePath = NULL;
    }

    goto cleanup;
}
示例#3
0
文件: pam_gss.c 项目: PADL/pam_gss
PAM_EXTERN int
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
    int status;
    OM_uint32 major, minor;
    gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
    gss_OID mech = GSS_C_NO_OID;

    if (flags && (flags & PAM_ESTABLISH_CRED) == 0)
        return PAM_SUCCESS;

    status = pam_get_data(pamh, GSS_CRED_DATA, (const void **)&cred);
    BAIL_ON_PAM_ERROR(status);

    status = pam_get_data(pamh, GSS_MECH_DATA, (const void **)&mech);
    BAIL_ON_PAM_ERROR(status);

    major = gss_store_cred(&minor, cred, GSS_C_INITIATE, mech,
                           1, 1, NULL, NULL);
    BAIL_ON_GSS_ERROR(major, minor);

cleanup:
    return status;
}
示例#4
0
文件: pam_gss.c 项目: PADL/pam_gss
int
pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
    int status, confFlags = 0;
    char hostNameBufBuf[5 + MAXHOSTNAMELEN + 1] = "host@";
    int isConvPasswordBuf = 0;

    OM_uint32 major, minor;
    gss_buffer_desc userNameBuf = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc hostNameBuf = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc passwordBuf = GSS_C_EMPTY_BUFFER;
    gss_name_t userName = GSS_C_NO_NAME;
    gss_name_t hostName = GSS_C_NO_NAME;
    gss_cred_id_t initiatorCred = GSS_C_NO_CREDENTIAL;
    gss_cred_id_t acceptorCred = GSS_C_NO_CREDENTIAL;
    gss_OID mech = &gss_spnego_mechanism_oid_desc;
    gss_OID_set_desc mechOids;

    confFlags = readConfFlags(argc, argv);

    status = readConfMechOid(argc, argv, &mech);
    BAIL_ON_PAM_ERROR(status);

    if (flags & PAM_DISALLOW_NULL_AUTHTOK)
        confFlags &= ~(FLAG_NULLOK);

    status = pam_get_user(pamh, (void *)&userNameBuf.value, NULL);
    BAIL_ON_PAM_ERROR(status);

    userNameBuf.length = strlen((char *)userNameBuf.value);

    major = gss_import_name(&minor, &userNameBuf, GSS_C_NT_USER_NAME, &userName);
    BAIL_ON_GSS_ERROR(major, minor);

    if (gethostname(&hostNameBufBuf[5], MAXHOSTNAMELEN) != 0) {
        status = PAM_SYSTEM_ERR;
        goto cleanup;
    }

    hostNameBuf.length = strlen(hostNameBufBuf);
    hostNameBuf.value = hostNameBufBuf;

    major = gss_import_name(&minor, &hostNameBuf, GSS_C_NT_HOSTBASED_SERVICE, &hostName);
    BAIL_ON_GSS_ERROR(major, minor);

    mechOids.count = 1;
    mechOids.elements = mech;

    major = gss_acquire_cred(&minor, hostName, GSS_C_INDEFINITE, &mechOids,
                             GSS_C_ACCEPT, &acceptorCred, NULL, NULL);
    BAIL_ON_GSS_ERROR(major, minor);

    status = PAM_AUTHINFO_UNAVAIL;

    if (confFlags & (FLAG_USE_FIRST_PASS | FLAG_TRY_FIRST_PASS)) {
        status = pam_get_item(pamh, PAM_AUTHTOK, (void *)&passwordBuf.value);
        BAIL_ON_PAM_ERROR(status);

        if (passwordBuf.value != NULL)
            passwordBuf.length = strlen((char *)passwordBuf.value);

        status = pamGssAcquireCred(pamh, confFlags, userName, &passwordBuf,
                                   mech, &initiatorCred);
        if (status == PAM_SUCCESS)
            status = pamGssInitAcceptSecContext(pamh, confFlags, initiatorCred,
                                                acceptorCred, hostName, mech);
        if (confFlags & FLAG_USE_FIRST_PASS)
            BAIL_ON_PAM_ERROR(status);
    }

    if (status != PAM_SUCCESS) {
        isConvPasswordBuf = 1;

        if (flags & PAM_SILENT)
            goto cleanup;

        status = pamGssGetAuthTok(pamh, confFlags, &passwordBuf);
        BAIL_ON_PAM_ERROR(status);

        gss_release_cred(&minor, &initiatorCred);

        status = pamGssAcquireCred(pamh, confFlags, userName, &passwordBuf,
                                   mech, &initiatorCred);
        if (status == PAM_SUCCESS)
            status = pamGssInitAcceptSecContext(pamh, confFlags, initiatorCred,
                                                acceptorCred, hostName, mech);
        BAIL_ON_PAM_ERROR(status);
    }

    status = pam_set_data(pamh, GSS_CRED_DATA, initiatorCred, pamGssCleanupCred);
    BAIL_ON_PAM_ERROR(status);

    initiatorCred = GSS_C_NO_CREDENTIAL;

cleanup:
    gss_release_name(&minor, &userName);
    gss_release_name(&minor, &hostName);
    gss_release_cred(&minor, &initiatorCred);
    gss_release_cred(&minor, &acceptorCred);
#ifdef __APPLE__
    if (mech != &gss_spnego_mechanism_oid_desc)
        gss_release_oid(&minor, &mech);
#endif
    if (isConvPasswordBuf) {
        memset((char *)passwordBuf.value, 0, passwordBuf.length);
        free(passwordBuf.value);
    }

    return status;
}
示例#5
0
文件: pam_gss.c 项目: PADL/pam_gss
static int
pamGssInitAcceptSecContext(pam_handle_t *pamh,
                           int confFlags,
                           gss_cred_id_t cred,
                           gss_cred_id_t acceptorCred,
                           gss_name_t hostName,
                           gss_OID mech)
{
    int status;
    OM_uint32 major, minor;
    gss_buffer_desc initiatorToken = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc acceptorToken = GSS_C_EMPTY_BUFFER;
    gss_ctx_id_t initiatorContext = GSS_C_NO_CONTEXT;
    gss_ctx_id_t acceptorContext = GSS_C_NO_CONTEXT;
    gss_buffer_desc canonUserNameBuf = GSS_C_EMPTY_BUFFER;
    gss_name_t canonUserName = GSS_C_NO_NAME;
    gss_OID canonMech = GSS_C_NO_OID;
    OM_uint32 gssFlags;

    do {
        major = gss_init_sec_context(&minor, cred, &initiatorContext,
                                     hostName, mech, GSS_C_MUTUAL_FLAG,
                                     GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS,
                                     &acceptorToken, NULL, &initiatorToken, &gssFlags, NULL);
        gss_release_buffer(&minor, &acceptorToken);

#ifdef GSS_S_PROMPTING_NEEDED
        if (major == GSS_S_PROMPTING_NEEDED) {
            status = PAM_CRED_INSUFFICIENT;
            goto cleanup;
        }
#endif

        BAIL_ON_GSS_ERROR(major, minor);

        if (initiatorToken.length != 0) {
            major = gss_accept_sec_context(&minor, &acceptorContext, acceptorCred,
                                           &initiatorToken, GSS_C_NO_CHANNEL_BINDINGS,
                                           &canonUserName, &canonMech, &acceptorToken,
                                           NULL, NULL, NULL);
            gss_release_buffer(&minor, &initiatorToken);
        }

        BAIL_ON_GSS_ERROR(major, minor);
    } while (major == GSS_S_CONTINUE_NEEDED);

    BAIL_ON_GSS_ERROR(major, minor);

    if ((gssFlags & GSS_C_MUTUAL_FLAG) == 0) {
        status = PAM_PERM_DENIED;
        goto cleanup;
    }

#ifndef __APPLE__
    major = gss_localname(&minor, canonUserName, GSS_C_NO_OID, &canonUserNameBuf);
    if (major == GSS_S_COMPLETE) {
        status = pam_set_item(pamh, PAM_USER, canonUserNameBuf.value);
        BAIL_ON_PAM_ERROR(status);
    } else if (major != GSS_S_UNAVAILABLE)
        goto cleanup;
#endif

    status = pam_set_data(pamh, GSS_NAME_DATA, canonUserName, pamGssCleanupName);
    BAIL_ON_PAM_ERROR(status);

    canonUserName = GSS_C_NO_NAME;

    status = pam_set_data(pamh, GSS_MECH_DATA, canonMech, pamGssCleanupMech);
    BAIL_ON_PAM_ERROR(status);

    canonMech = GSS_C_NO_OID;

    status = PAM_SUCCESS;

cleanup:
    gss_release_name(&minor, &canonUserName);
    gss_release_buffer(&minor, &initiatorToken);
    gss_release_buffer(&minor, &acceptorToken);
    gss_delete_sec_context(&minor, &initiatorContext, NULL);
    gss_delete_sec_context(&minor, &acceptorContext, NULL);
    gss_release_buffer(&minor, &canonUserNameBuf);

    if (IGNORE_ERR_P(status, confFlags))
        status = PAM_IGNORE;

    return status;
}
示例#6
0
DWORD
LwKrb5CheckInitiatorCreds(
    IN PCSTR pszTargetPrincipalName,
    OUT PBOOLEAN pbNeedCredentials
    )
{
    DWORD dwError = 0;
    BOOLEAN bNeedCredentials = FALSE;
    OM_uint32 majorStatus = 0;
    OM_uint32 minorStatus = 0;
    gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT;
    gss_buffer_desc importName  = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc inputBufferDesc  = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc outputBufferDesc = GSS_C_EMPTY_BUFFER;
    OM_uint32 outputFlags = 0;
    gss_name_t targetName = GSS_C_NO_NAME;

    // discard const
    importName.value = (PSTR) pszTargetPrincipalName;
    importName.length = strlen(pszTargetPrincipalName);

    // discard const from GSS_KRB5_NT_PRINCIPAL_NAME
    majorStatus = gss_import_name(&minorStatus,
                                  &importName,
                                  (gss_OID) GSS_KRB5_NT_PRINCIPAL_NAME,
                                  &targetName);
    LW_GSS_LOG_IF_NOT_COMPLETE("gss_import_name", majorStatus, minorStatus);
    BAIL_ON_GSS_ERROR(dwError, majorStatus, minorStatus);

    // discard const from GSS_KRB5_NT_PRINCIPAL_NAME
    majorStatus = gss_init_sec_context(&minorStatus,
                                       NULL,
                                       &gssContext,
                                       targetName,
                                       (gss_OID) gss_mech_krb5,
                                       GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG,
                                       0,
                                       NULL,
                                       &inputBufferDesc,
                                       NULL,
                                       &outputBufferDesc,
                                       &outputFlags,
                                       NULL);
    LW_GSS_LOG_IF_NOT_COMPLETE_OR_CONTINUE("gss_init_sec_context", majorStatus, minorStatus);

    // Need to cast below for correct comparison.  Note that
    // some compilers do not catch the mismatch.
    if (((majorStatus == GSS_S_FAILURE) &&
         ((minorStatus == (OM_uint32) KRB5KRB_AP_ERR_TKT_EXPIRED) ||
          (minorStatus == (OM_uint32) KRB5KDC_ERR_NEVER_VALID) ||
          (minorStatus == (OM_uint32) KRB5KDC_ERR_TGT_REVOKED))) ||
        ((majorStatus == GSS_S_CRED_UNAVAIL) &&
         (minorStatus == KG_EMPTY_CCACHE)))
    {
        // Need (new) Kerberos credentials because there are no
        // credentials or the credentials are expired or otherwise
        // invalid.

        bNeedCredentials = TRUE;
        goto error;
    }

    if (majorStatus == GSS_S_FAILURE)
    {
        switch (minorStatus)
        {
            case (OM_uint32) KRB5KRB_AP_ERR_SKEW:
                dwError = ERROR_TIME_SKEW;
                BAIL_ON_LW_ERROR(dwError);
                break;
            default:
                BAIL_ON_GSS_ERROR(dwError, majorStatus, minorStatus);
                break;
        }
    }

    if ((majorStatus != GSS_S_COMPLETE) &&
        (majorStatus != GSS_S_CONTINUE_NEEDED))
    {
        BAIL_ON_GSS_ERROR(dwError, majorStatus, minorStatus);
    }

error:
    if (targetName)
    {
        gss_release_name(&minorStatus, &targetName);
    }

    if (outputBufferDesc.value)
    {
        majorStatus = gss_release_buffer(&minorStatus, &outputBufferDesc);
    }

    if (gssContext)
    {
        majorStatus = gss_delete_sec_context(&minorStatus, &gssContext, GSS_C_NO_BUFFER);
    }

    *pbNeedCredentials = bNeedCredentials;

    return dwError;
}