59
DWORD dwError = PAM_SUCCESS;
59
LSA_PAM_CONVERSE_MESSAGE message;
61
message.messageStyle = messageStyle;
62
message.pszMessage = pszPrompt;
63
message.ppszResponse = ppszResponse;
65
return LsaPamConverseMulti(pamh, 1, &message);
72
PLSA_PAM_CONVERSE_MESSAGE pLsaPamConvMessages
60
76
struct pam_conv* pConv = NULL;
61
struct pam_response* pResponse = NULL;
62
struct pam_message msg;
63
struct pam_message* pMsg = NULL;
64
PSTR pszResponse = NULL;
77
struct pam_response* pResponses = NULL;
78
struct pam_message* msgs = NULL;
79
struct pam_message** pMsgs = NULL;
66
dwError = pam_get_item(pamh, PAM_CONV, (PAM_GET_ITEM_TYPE)&pConv);
83
iPamError = pam_get_item(pamh, PAM_CONV, (PAM_GET_ITEM_TYPE)&pConv);
84
dwError = LsaPamUnmapErrorCode(iPamError);
67
85
BAIL_ON_LSA_ERROR(dwError);
69
memset(&msg, 0, sizeof(struct pam_message));
72
pMsg->msg_style = messageStyle;
73
pMsg->msg = (PAM_MESSAGE_MSG_TYPE)pszPrompt;
77
dwError = pConv->conv(1,
78
(PAM_CONV_2ND_ARG_TYPE)&pMsg,
89
dwError = LsaPamUnmapErrorCode(PAM_CONV_ERR);
90
BAIL_ON_LSA_ERROR(dwError);
94
dwError = LwAllocateMemory(numMessages * sizeof(*msgs),
96
BAIL_ON_LSA_ERROR(dwError);
98
dwError = LwAllocateMemory(numMessages * sizeof(*pMsgs),
100
BAIL_ON_LSA_ERROR(dwError);
102
for (i = 0; i < numMessages; ++i)
104
msgs[i].msg_style = pLsaPamConvMessages[i].messageStyle;
105
msgs[i].msg = (PAM_MESSAGE_MSG_TYPE) pLsaPamConvMessages[i].pszMessage;
107
switch (msgs[i].msg_style)
109
case PAM_PROMPT_ECHO_ON:
110
case PAM_PROMPT_ECHO_OFF:
111
if (pLsaPamConvMessages[i].ppszResponse == NULL)
113
BAIL_WITH_LSA_ERROR(LW_ERROR_INVALID_PARAMETER);
118
if (pLsaPamConvMessages[i].ppszResponse != NULL)
120
BAIL_WITH_LSA_ERROR(LW_ERROR_INVALID_PARAMETER);
128
iPamError = pConv->conv(numMessages,
129
(PAM_CONV_2ND_ARG_TYPE)pMsgs,
80
131
pConv->appdata_ptr);
132
dwError = LsaPamUnmapErrorCode(iPamError);
81
133
BAIL_ON_LSA_ERROR(dwError);
85
137
LSA_LOG_PAM_INFO("Unable to send prompt to user from PAM. Most likely the calling program is non-interactive");
86
// Leave pResponse as NULL.
138
// Leave pResponses as NULL.
141
for (i = 0; i < numMessages; ++i)
91
case PAM_PROMPT_ECHO_ON:
92
case PAM_PROMPT_ECHO_OFF:
93
if (pResponse == NULL || (pResponse->resp == NULL)) {
95
dwError = PAM_CONV_ERR;
96
BAIL_ON_LSA_ERROR(dwError);
100
dwError = LwAllocateString(pResponse->resp, &pszResponse);
101
BAIL_ON_LSA_ERROR(dwError);
107
// We don't need a response for certain message styles
108
// For instance, PAM_ERROR_MSG or PAM_TEXT_INFO
110
*ppszResponse = pszResponse;
143
switch (pLsaPamConvMessages[i].messageStyle)
145
case PAM_PROMPT_ECHO_ON:
146
case PAM_PROMPT_ECHO_OFF:
148
* The pResponses == NULL check is here because
149
* it's perfectly OK for it to be NULL if none of the
150
* messages required a response.
152
if (pResponses == NULL || pResponses[i].resp == NULL)
154
BAIL_WITH_LSA_ERROR(PAM_CONV_ERR);
157
*pLsaPamConvMessages[i].ppszResponse = pResponses[i].resp;
161
if (pResponses != NULL && pResponses[i].resp != NULL)
163
/* Got a response we weren't expecting. */
164
BAIL_WITH_LSA_ERROR(PAM_CONV_ERR);
116
if (pResponse->resp) {
117
memset(pResponse->resp, 0, strlen(pResponse->resp));
118
free(pResponse->resp);
174
* All the .resp pointers have either been copied to
175
* the caller or freed.
123
return LsaPamMapErrorCode(dwError, NULL);
180
LW_SAFE_FREE_MEMORY(msgs);
181
LW_SAFE_FREE_MEMORY(pMsgs);
127
if (ppszResponse != NULL)
129
*ppszResponse = NULL;
188
for (i = 0; i < numMessages; ++i)
190
LW_SAFE_CLEAR_FREE_STRING(pResponses[i].resp);
132
LW_SAFE_CLEAR_FREE_STRING(pszResponse);