示例#1
0
DWORD
LsaPamSetDataString(
    pam_handle_t* pamh,
    PCSTR pszKey,
    PCSTR pszStr
    )
{
    DWORD dwError = 0;
    PSTR pszStrCopy = NULL;
    int iPamError = 0;

    dwError = LwAllocateString(pszStr, &pszStrCopy);
    BAIL_ON_LSA_ERROR(dwError);
    
    iPamError = pam_set_data(pamh, pszKey, pszStrCopy, LsaPamCleanupDataString);
    dwError = LsaPamUnmapErrorCode(iPamError);
    BAIL_ON_LSA_ERROR(dwError);

error:
    
    return dwError;
}
示例#2
0
DWORD
LsaPamGetContext(
    pam_handle_t* pamh, 
    int           flags, 
    int           argc, 
    const char**  argv,
    PPAMCONTEXT*  ppPamContext
    )
{
    DWORD       dwError = 0;
    PPAMCONTEXT pPamContext = NULL;
    BOOLEAN     bFreeContext = FALSE;
    int         iPamError = 0;
    
    LSA_LOG_PAM_DEBUG("LsaPamGetContext::begin");
    
    iPamError = pam_get_data(pamh, MODULE_NAME, (PAM_GET_DATA_TYPE)&pPamContext);
    dwError = LsaPamUnmapErrorCode(iPamError);
    if (dwError)
    {
        if (dwError == LsaPamUnmapErrorCode(PAM_NO_MODULE_DATA))
        {
                dwError = LwAllocateMemory(
                                sizeof(PAMCONTEXT),
                                (PVOID*)&pPamContext);
                BAIL_ON_LSA_ERROR(dwError);

                bFreeContext = TRUE;

                iPamError = pam_set_data(
                                pamh,
                                MODULE_NAME,
                                (PVOID)pPamContext,
                                &LsaPamCleanupContext);
                dwError = LsaPamUnmapErrorCode(iPamError);
                BAIL_ON_LSA_ERROR(dwError);

                bFreeContext = FALSE;
        }
        else
        {
                BAIL_ON_LSA_ERROR(dwError);
        }
    }

    dwError = LsaPamGetLoginId(pamh, pPamContext, NULL, FALSE);
    BAIL_ON_LSA_ERROR(dwError);
    
    dwError = LsaPamGetOptions(
                    pamh,
                    flags,
                    argc,
                    argv,
                    &pPamContext->pamOptions);
    BAIL_ON_LSA_ERROR(dwError);
    
    *ppPamContext = pPamContext;
    
cleanup:

    LSA_LOG_PAM_DEBUG("LsaPamGetContext::end");

    return dwError;

error:

    if (pPamContext && bFreeContext) {
       LsaPamFreeContext(pPamContext);
    }

    *ppPamContext = NULL;
    
    LSA_LOG_PAM_ERROR("LsaPamGetContext failed [error code: %u]", dwError);

    goto cleanup;
}
示例#3
0
DWORD
LsaPamGetLoginId(
    pam_handle_t* pamh,
    PPAMCONTEXT   pPamContext,
    PSTR*         ppszLoginId,
    BOOLEAN       bAllowPrompt
    )
{
    DWORD dwError = 0;
    PSTR pszLoginId = NULL;
    PSTR pszPamId = NULL;
    int iPamError = 0;
    
    LSA_LOG_PAM_DEBUG("LsaPamGetLoginId::begin");

        
    iPamError = pam_get_item(
                    pamh,
                    PAM_USER,
                    (PAM_GET_ITEM_TYPE)&pszPamId);
    dwError = LsaPamUnmapErrorCode(iPamError);
#if HAVE_DECL_PAM_BAD_ITEM
    if (dwError == LsaPamUnmapErrorCode(PAM_BAD_ITEM))
    {
        pszPamId = NULL;
        dwError = 0;
    }
#endif
    BAIL_ON_LSA_ERROR(dwError);
    if (LW_IS_NULL_OR_EMPTY_STR(pszPamId) && bAllowPrompt)
    {
        iPamError = pam_get_user(
                        pamh,
                        (PPCHAR_ARG_CAST)&pszPamId,
                        NULL);
        dwError = LsaPamUnmapErrorCode(iPamError);
        if (dwError)
        {
           dwError = (dwError == LsaPamUnmapErrorCode(PAM_CONV_AGAIN)) ?
               LsaPamUnmapErrorCode(PAM_INCOMPLETE) :
               LsaPamUnmapErrorCode(PAM_SERVICE_ERR);
           BAIL_ON_LSA_ERROR(dwError);
        }
	    if (LW_IS_NULL_OR_EMPTY_STR(pszPamId))
	    {
	       dwError = LsaPamUnmapErrorCode(PAM_SERVICE_ERR);
	       BAIL_ON_LSA_ERROR(dwError);
	    }
    }

    dwError = LwStrDupOrNull(
                pszPamId,
                &pszLoginId);
    BAIL_ON_LSA_ERROR(dwError);
    
    LW_SAFE_FREE_STRING(pPamContext->pszLoginName);
    dwError = LwStrDupOrNull(pszPamId, &pPamContext->pszLoginName);
    BAIL_ON_LSA_ERROR(dwError);

    if (ppszLoginId)
    {
        *ppszLoginId = pszLoginId;
    }
    else
    {
        LW_SAFE_FREE_STRING(pszLoginId);
    }

cleanup:

    LSA_LOG_PAM_DEBUG("LsaPamGetLoginId::end");

    return dwError;

error:

    LW_SAFE_FREE_STRING(pszLoginId);
    
    if (ppszLoginId)
    {
       *ppszLoginId = NULL;
    }
    
    LSA_LOG_PAM_ERROR("LsaPamGetLoginId failed [error code: %u]", dwError);

    goto cleanup;
}
示例#4
0
DWORD
LsaPamConverseMulti(
    pam_handle_t*             pamh,
    int                       numMessages,
    PLSA_PAM_CONVERSE_MESSAGE pLsaPamConvMessages
    )
{
    DWORD  dwError = 0;
    struct pam_conv* pConv = NULL;
    struct pam_response* pResponses = NULL;
    struct pam_message* msgs = NULL;
    struct pam_message** pMsgs = NULL;
    int    iPamError = 0;
    int    i;
    
    iPamError = pam_get_item(pamh, PAM_CONV, (PAM_GET_ITEM_TYPE)&pConv);
    dwError = LsaPamUnmapErrorCode(iPamError);
    BAIL_ON_LSA_ERROR(dwError);

    if (!pConv)
    {
        dwError = LsaPamUnmapErrorCode(PAM_CONV_ERR);
        BAIL_ON_LSA_ERROR(dwError);
    }
    else if (pConv->conv)
    {
        dwError = LwAllocateMemory(numMessages * sizeof(*msgs),
                (PVOID*) &msgs);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwAllocateMemory(numMessages * sizeof(*pMsgs),
                (PVOID*) &pMsgs);
        BAIL_ON_LSA_ERROR(dwError);

        for (i = 0; i < numMessages; ++i)
        {
            msgs[i].msg_style = pLsaPamConvMessages[i].messageStyle;
            msgs[i].msg = pLsaPamConvMessages[i].pszMessage;

            switch (msgs[i].msg_style)
            {
                case PAM_PROMPT_ECHO_ON:
                case PAM_PROMPT_ECHO_OFF:
                    if (pLsaPamConvMessages[i].ppszResponse == NULL)
                    {
                        BAIL_WITH_LSA_ERROR(LW_ERROR_INVALID_PARAMETER);
                    }
                    break;

                default:
                    if (pLsaPamConvMessages[i].ppszResponse != NULL)
                    {
                        BAIL_WITH_LSA_ERROR(LW_ERROR_INVALID_PARAMETER);
                    }
                    break;
            }

            pMsgs[i] = &msgs[i];
        }

        iPamError = pConv->conv(numMessages,
                (PAM_CONV_2ND_ARG_TYPE)pMsgs,
                &pResponses,
                pConv->appdata_ptr);
        dwError = LsaPamUnmapErrorCode(iPamError);
        BAIL_ON_LSA_ERROR(dwError);
    }
    else
    {
        LSA_LOG_PAM_INFO("Unable to send prompt to user from PAM. Most likely the calling program is non-interactive");
        // Leave pResponses as NULL.
    }

    for (i = 0; i < numMessages; ++i)
    {
        switch (pLsaPamConvMessages[i].messageStyle)
        {
            case PAM_PROMPT_ECHO_ON:
            case PAM_PROMPT_ECHO_OFF:
                /*
                 * The pResponses == NULL check is here because
                 * it's perfectly OK for it to be NULL if none of the
                 * messages required a response.
                 */
                if (pResponses == NULL || pResponses[i].resp == NULL)
                {
                   BAIL_WITH_LSA_ERROR(PAM_CONV_ERR);
                }

                *pLsaPamConvMessages[i].ppszResponse = pResponses[i].resp;
                break;

            default:
                if (pResponses != NULL && pResponses[i].resp != NULL)
                {
                    /* Got a response we weren't expecting. */
                    BAIL_WITH_LSA_ERROR(PAM_CONV_ERR);
                }
                break;
        }
    }

cleanup:
    if (pResponses)
    {
        /*
         * All the .resp pointers have either been copied to
         * the caller or freed.
         */
        free(pResponses);
    }

    LW_SAFE_FREE_MEMORY(msgs);
    LW_SAFE_FREE_MEMORY(pMsgs);

    return dwError;

error:
    if (pResponses)
    {
        for (i = 0; i < numMessages; ++i)
        {
            LW_SECURE_FREE_STRING(pResponses[i].resp);
        }
    }

    goto cleanup;
}