* Continue SSPI authentication with next token as needed. */
| 213 | * Continue SSPI authentication with next token as needed. |
| 214 | */ |
| 215 | static int |
| 216 | pg_SSPI_continue(PGconn *conn, int payloadlen) |
| 217 | { |
| 218 | SECURITY_STATUS r; |
| 219 | CtxtHandle newContext; |
| 220 | ULONG contextAttr; |
| 221 | SecBufferDesc inbuf; |
| 222 | SecBufferDesc outbuf; |
| 223 | SecBuffer OutBuffers[1]; |
| 224 | SecBuffer InBuffers[1]; |
| 225 | char *inputbuf = NULL; |
| 226 | |
| 227 | if (conn->sspictx != NULL) |
| 228 | { |
| 229 | /* |
| 230 | * On runs other than the first we have some data to send. Put this |
| 231 | * data in a SecBuffer type structure. |
| 232 | */ |
| 233 | inputbuf = malloc(payloadlen); |
| 234 | if (!inputbuf) |
| 235 | { |
| 236 | appendPQExpBuffer(&conn->errorMessage, |
| 237 | libpq_gettext("out of memory allocating SSPI buffer (%d)\n"), |
| 238 | payloadlen); |
| 239 | return STATUS_ERROR; |
| 240 | } |
| 241 | if (pqGetnchar(inputbuf, payloadlen, conn)) |
| 242 | { |
| 243 | /* |
| 244 | * Shouldn't happen, because the caller should've ensured that the |
| 245 | * whole message is already in the input buffer. |
| 246 | */ |
| 247 | free(inputbuf); |
| 248 | return STATUS_ERROR; |
| 249 | } |
| 250 | |
| 251 | inbuf.ulVersion = SECBUFFER_VERSION; |
| 252 | inbuf.cBuffers = 1; |
| 253 | inbuf.pBuffers = InBuffers; |
| 254 | InBuffers[0].pvBuffer = inputbuf; |
| 255 | InBuffers[0].cbBuffer = payloadlen; |
| 256 | InBuffers[0].BufferType = SECBUFFER_TOKEN; |
| 257 | } |
| 258 | |
| 259 | OutBuffers[0].pvBuffer = NULL; |
| 260 | OutBuffers[0].BufferType = SECBUFFER_TOKEN; |
| 261 | OutBuffers[0].cbBuffer = 0; |
| 262 | outbuf.cBuffers = 1; |
| 263 | outbuf.pBuffers = OutBuffers; |
| 264 | outbuf.ulVersion = SECBUFFER_VERSION; |
| 265 | |
| 266 | r = InitializeSecurityContext(conn->sspicred, |
| 267 | conn->sspictx, |
| 268 | conn->sspitarget, |
| 269 | ISC_REQ_ALLOCATE_MEMORY, |
| 270 | 0, |
| 271 | SECURITY_NETWORK_DREP, |
| 272 | (conn->sspictx == NULL) ? NULL : &inbuf, |
no test coverage detected