From 98531e56318b65eb1bb6883fdfe12e771d8a1efe Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 24 Feb 2009 19:28:40 -0500 Subject: Add PAM responder Also move responders under server/responder with shared code in server/responder/common Signed-off-by: Simo Sorce --- server/responder/pam/pamsrv_cmd.c | 196 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 server/responder/pam/pamsrv_cmd.c (limited to 'server/responder/pam/pamsrv_cmd.c') diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c new file mode 100644 index 000000000..4fdded309 --- /dev/null +++ b/server/responder/pam/pamsrv_cmd.c @@ -0,0 +1,196 @@ +#include +#include + +#include "util/util.h" +#include "responder/common/responder_common.h" +#include "responder/common/responder_cmd.h" +#include "responder/common/responder_packet.h" +#include "responder/pam/pamsrv.h" + +static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) { + int start; + int end; + int last=blen-1; + char *delim; + + start = end = 0; + while ( end < last && body[end++]!='\0'); + pd->user = (char *) &body[start]; + + delim = strchr(pd->user, SSS_DOMAIN_DELIM); + if (delim != NULL ) { + *delim = '\0'; + pd->domain = delim+1; + } else { + pd->domain = NULL; + } + + start = end; + while ( end < last && body[end++]!='\0'); + pd->service = (char *) &body[start]; + + start = end; + while ( end < last && body[end++]!='\0'); + pd->tty = (char *) &body[start]; + + start = end; + while ( end < last && body[end++]!='\0'); + pd->ruser = (char *) &body[start]; + + start = end; + while ( end < last && body[end++]!='\0'); + pd->rhost = (char *) &body[start]; + + start = end; + pd->authtok_type = (int) body[start]; + start += sizeof(uint32_t); + pd->authtok_size = (int) body[start]; + start += sizeof(uint32_t); + end = start+pd->authtok_size; + if ( pd->authtok_size == 0 ) { + pd->authtok = NULL; + } else { + if ( end <= blen ) { + pd->authtok = (uint8_t *) &body[start]; + } else { + DEBUG(1, ("Invalid authtok size: %d\n", pd->authtok_size)); + return EINVAL; + } + } + + start = end; + pd->newauthtok_type = (int) body[start]; + start += sizeof(uint32_t); + pd->newauthtok_size = (int) body[start]; + start += sizeof(uint32_t); + end = start+pd->newauthtok_size; + if ( pd->newauthtok_size == 0 ) { + pd->newauthtok = NULL; + } else { + if ( end <= blen ) { + pd->newauthtok = (uint8_t *) &body[start]; + } else { + DEBUG(1, ("Invalid newauthtok size: %d\n", pd->newauthtok_size)); + return EINVAL; + } + } + + DEBUG_PAM_DATA(4, pd); + + return EOK; +} + +static void pam_reply(struct cli_ctx *cctx, int pam_status, char *domain) { + struct sss_cmd_ctx *nctx; + int32_t ret_status = pam_status; + uint8_t *body; + size_t blen; + int ret; + int err = EOK; + + DEBUG(4, ("pam_reply get called.\n")); + nctx = talloc_zero(cctx, struct sss_cmd_ctx); + if (!nctx) { + err = ENOMEM; + goto done; + } + nctx->cctx = cctx; + nctx->check_expiration = true; + + ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), + &cctx->creq->out); + if (ret != EOK) { + err = ret; + goto done; + } + + ret = sss_packet_grow(cctx->creq->out, sizeof(int) + strlen(domain)+1 ); + if (ret != EOK) { + err = ret; + goto done; + } + + sss_packet_get_body(cctx->creq->out, &body, &blen); + DEBUG(4, ("blen: %d\n", blen)); + memcpy(body, &ret_status, sizeof(int32_t)); + memcpy(body+sizeof(int32_t), domain, strlen(domain)+1); + +done: + sss_cmd_done(nctx); +} + +static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) +{ + uint8_t *body; + size_t blen; + int ret; + struct pam_data *pd; + + pd = talloc(cctx, struct pam_data); + if (pd == NULL) return ENOMEM; + + sss_packet_get_body(cctx->creq->in, &body, &blen); + if (blen >= sizeof(uint32_t) && + ((uint32_t *)(&body[blen - sizeof(uint32_t)]))[0] != END_OF_PAM_REQUEST) { + DEBUG(1, ("Received data not terminated.\n")); + talloc_free(pd); + return EINVAL; + } + + pd->cmd = pam_cmd; + ret=pam_parse_in_data(body, blen, pd); + if( ret != 0 ) { + talloc_free(pd); + return EINVAL; + } + + ret=pam_dp_send_req(cctx, pam_reply, PAM_DP_TIMEOUT, pd); + DEBUG(4, ("pam_dp_send_req returned %d\n", ret)); + + return ret; +} + +static int pam_cmd_authenticate(struct cli_ctx *cctx) { + DEBUG(4, ("entering pam_cmd_authenticate\n")); + return pam_forwarder(cctx, SSS_PAM_AUTHENTICATE); +} + +static int pam_cmd_setcred(struct cli_ctx *cctx) { + DEBUG(4, ("entering pam_cmd_setcred\n")); + return pam_forwarder(cctx, SSS_PAM_SETCRED); +} + +static int pam_cmd_acct_mgmt(struct cli_ctx *cctx) { + DEBUG(4, ("entering pam_cmd_acct_mgmt\n")); + return pam_forwarder(cctx, SSS_PAM_ACCT_MGMT); +} + +static int pam_cmd_open_session(struct cli_ctx *cctx) { + DEBUG(4, ("entering pam_cmd_open_session\n")); + return pam_forwarder(cctx, SSS_PAM_OPEN_SESSION); +} + +static int pam_cmd_close_session(struct cli_ctx *cctx) { + DEBUG(4, ("entering pam_cmd_close_session\n")); + return pam_forwarder(cctx, SSS_PAM_CLOSE_SESSION); +} + +static int pam_cmd_chauthtok(struct cli_ctx *cctx) { + DEBUG(4, ("entering pam_cmd_chauthtok\n")); + return pam_forwarder(cctx, SSS_PAM_CHAUTHTOK); +} + +struct sss_cmd_table *register_sss_cmds(void) { + static struct sss_cmd_table sss_cmds[] = { + {SSS_GET_VERSION, sss_cmd_get_version}, + {SSS_PAM_AUTHENTICATE, pam_cmd_authenticate}, + {SSS_PAM_SETCRED, pam_cmd_setcred}, + {SSS_PAM_ACCT_MGMT, pam_cmd_acct_mgmt}, + {SSS_PAM_OPEN_SESSION, pam_cmd_open_session}, + {SSS_PAM_CLOSE_SESSION, pam_cmd_close_session}, + {SSS_PAM_CHAUTHTOK, pam_cmd_chauthtok}, + {SSS_CLI_NULL, NULL} + }; + + return sss_cmds; +} -- cgit