~ubuntu-branches/ubuntu/oneiric/likewise-open/oneiric

« back to all changes in this revision

Viewing changes to lsass/interop/auth/pam/pam-conv.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Salley
  • Date: 2010-11-22 12:06:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122120600-8lba1fpceot71wlb
Tags: 6.0.0.53010-1
Likewise Open 6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
 */
49
49
#include "pam-lsass.h"
50
50
 
51
 
int
 
51
DWORD
52
52
LsaPamConverse(
53
53
    pam_handle_t* pamh,
54
54
    PCSTR         pszPrompt,
56
56
    PSTR*         ppszResponse
57
57
    )
58
58
{
59
 
    DWORD  dwError = PAM_SUCCESS;
 
59
    LSA_PAM_CONVERSE_MESSAGE message;
 
60
 
 
61
    message.messageStyle = messageStyle;
 
62
    message.pszMessage = pszPrompt;
 
63
    message.ppszResponse = ppszResponse;
 
64
 
 
65
    return LsaPamConverseMulti(pamh, 1, &message);
 
66
}
 
67
 
 
68
DWORD
 
69
LsaPamConverseMulti(
 
70
    pam_handle_t*             pamh,
 
71
    int                       numMessages,
 
72
    PLSA_PAM_CONVERSE_MESSAGE pLsaPamConvMessages
 
73
    )
 
74
{
 
75
    DWORD  dwError = 0;
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;
 
80
    int    iPamError = 0;
 
81
    int    i;
65
82
 
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);
68
86
 
69
 
    memset(&msg, 0, sizeof(struct pam_message));
70
 
    pMsg = &msg;
71
 
 
72
 
    pMsg->msg_style = messageStyle;
73
 
    pMsg->msg       = (PAM_MESSAGE_MSG_TYPE)pszPrompt;
74
 
 
75
 
    if (pConv->conv)
76
 
    {
77
 
        dwError = pConv->conv(1,
78
 
                (PAM_CONV_2ND_ARG_TYPE)&pMsg,
79
 
                &pResponse,
 
87
    if (!pConv)
 
88
    {
 
89
        dwError = LsaPamUnmapErrorCode(PAM_CONV_ERR);
 
90
        BAIL_ON_LSA_ERROR(dwError);
 
91
    }
 
92
    else if (pConv->conv)
 
93
    {
 
94
        dwError = LwAllocateMemory(numMessages * sizeof(*msgs),
 
95
                (PVOID*) &msgs);
 
96
        BAIL_ON_LSA_ERROR(dwError);
 
97
 
 
98
        dwError = LwAllocateMemory(numMessages * sizeof(*pMsgs),
 
99
                (PVOID*) &pMsgs);
 
100
        BAIL_ON_LSA_ERROR(dwError);
 
101
 
 
102
        for (i = 0; i < numMessages; ++i)
 
103
        {
 
104
            msgs[i].msg_style = pLsaPamConvMessages[i].messageStyle;
 
105
            msgs[i].msg = (PAM_MESSAGE_MSG_TYPE) pLsaPamConvMessages[i].pszMessage;
 
106
 
 
107
            switch (msgs[i].msg_style)
 
108
            {
 
109
                case PAM_PROMPT_ECHO_ON:
 
110
                case PAM_PROMPT_ECHO_OFF:
 
111
                    if (pLsaPamConvMessages[i].ppszResponse == NULL)
 
112
                    {
 
113
                        BAIL_WITH_LSA_ERROR(LW_ERROR_INVALID_PARAMETER);
 
114
                    }
 
115
                    break;
 
116
 
 
117
                default:
 
118
                    if (pLsaPamConvMessages[i].ppszResponse != NULL)
 
119
                    {
 
120
                        BAIL_WITH_LSA_ERROR(LW_ERROR_INVALID_PARAMETER);
 
121
                    }
 
122
                    break;
 
123
            }
 
124
 
 
125
            pMsgs[i] = &msgs[i];
 
126
        }
 
127
 
 
128
        iPamError = pConv->conv(numMessages,
 
129
                (PAM_CONV_2ND_ARG_TYPE)pMsgs,
 
130
                &pResponses,
80
131
                pConv->appdata_ptr);
 
132
        dwError = LsaPamUnmapErrorCode(iPamError);
81
133
        BAIL_ON_LSA_ERROR(dwError);
82
134
    }
83
135
    else
84
136
    {
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.
87
139
    }
88
140
 
89
 
    switch (messageStyle)
 
141
    for (i = 0; i < numMessages; ++i)
90
142
    {
91
 
        case PAM_PROMPT_ECHO_ON:
92
 
        case PAM_PROMPT_ECHO_OFF:
93
 
            if (pResponse == NULL || (pResponse->resp == NULL)) {
94
 
 
95
 
               dwError = PAM_CONV_ERR;
96
 
               BAIL_ON_LSA_ERROR(dwError);
97
 
 
98
 
            } else {
99
 
 
100
 
               dwError = LwAllocateString(pResponse->resp, &pszResponse);
101
 
               BAIL_ON_LSA_ERROR(dwError);
102
 
 
103
 
            }
104
 
            break;
105
 
    }
106
 
 
107
 
    // We don't need a response for certain message styles
108
 
    // For instance, PAM_ERROR_MSG or PAM_TEXT_INFO
109
 
    if (ppszResponse) {
110
 
       *ppszResponse = pszResponse;
 
143
        switch (pLsaPamConvMessages[i].messageStyle)
 
144
        {
 
145
            case PAM_PROMPT_ECHO_ON:
 
146
            case PAM_PROMPT_ECHO_OFF:
 
147
                /*
 
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.
 
151
                 */
 
152
                if (pResponses == NULL || pResponses[i].resp == NULL)
 
153
                {
 
154
                   BAIL_WITH_LSA_ERROR(PAM_CONV_ERR);
 
155
                }
 
156
 
 
157
                *pLsaPamConvMessages[i].ppszResponse = pResponses[i].resp;
 
158
                break;
 
159
 
 
160
            default:
 
161
                if (pResponses != NULL && pResponses[i].resp != NULL)
 
162
                {
 
163
                    /* Got a response we weren't expecting. */
 
164
                    BAIL_WITH_LSA_ERROR(PAM_CONV_ERR);
 
165
                }
 
166
                break;
 
167
        }
111
168
    }
112
169
 
113
170
cleanup:
114
 
 
115
 
    if (pResponse) {
116
 
        if (pResponse->resp) {
117
 
            memset(pResponse->resp, 0, strlen(pResponse->resp));
118
 
            free(pResponse->resp);
119
 
        }
120
 
        free(pResponse);
 
171
    if (pResponses)
 
172
    {
 
173
        /*
 
174
         * All the .resp pointers have either been copied to
 
175
         * the caller or freed.
 
176
         */
 
177
        free(pResponses);
121
178
    }
122
179
 
123
 
    return LsaPamMapErrorCode(dwError, NULL);
 
180
    LW_SAFE_FREE_MEMORY(msgs);
 
181
    LW_SAFE_FREE_MEMORY(pMsgs);
 
182
 
 
183
    return dwError;
124
184
 
125
185
error:
126
 
 
127
 
    if (ppszResponse != NULL)
 
186
    if (pResponses)
128
187
    {
129
 
        *ppszResponse = NULL;
 
188
        for (i = 0; i < numMessages; ++i)
 
189
        {
 
190
            LW_SAFE_CLEAR_FREE_STRING(pResponses[i].resp);
 
191
        }
130
192
    }
131
193
 
132
 
    LW_SAFE_CLEAR_FREE_STRING(pszResponse);
133
 
 
134
194
    goto cleanup;
135
195
}
136
196