From ab691765dc8d727d01f061d846e7c765e89fb299 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 8 May 2009 09:53:35 +0200 Subject: added more flexible handling of client protocol - allow different protocol versions for PAM and NSS - support more than one protocol version in the responder --- server/responder/common/responder.h | 8 ++++++++ server/responder/common/responder_cmd.c | 34 ++++++++++++++++++++++++++++++++- server/responder/nss/nsssrv_cmd.c | 10 ++++++++++ server/responder/pam/pamsrv_cmd.c | 13 ++++++++++++- sss_client/common.c | 22 +++++++++++++++++---- sss_client/sss_cli.h | 3 ++- 6 files changed, 83 insertions(+), 7 deletions(-) diff --git a/server/responder/common/responder.h b/server/responder/common/responder.h index f5d5246fb..946418c86 100644 --- a/server/responder/common/responder.h +++ b/server/responder/common/responder.h @@ -43,6 +43,12 @@ struct cli_request { struct sss_packet *out; }; +struct cli_protocol_version { + uint32_t version; + char *date; + char *description; +}; + struct sss_names_ctx { char *re_pattern; char *fq_fmt; @@ -83,6 +89,7 @@ struct cli_ctx { struct tevent_fd *cfde; struct sockaddr_un addr; struct cli_request *creq; + struct cli_protocol_version *cli_protocol_version; int priv; }; @@ -111,6 +118,7 @@ int sss_parse_name(TALLOC_CTX *memctx, int sss_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds); void sss_cmd_done(struct cli_ctx *cctx, void *freectx); int sss_cmd_get_version(struct cli_ctx *cctx); +struct cli_protocol_version *register_cli_protocol_version(void); /* responder_dp.c */ int sss_dp_init(struct resp_ctx *rctx, struct sbus_method dp_methods[]); diff --git a/server/responder/common/responder_cmd.c b/server/responder/common/responder_cmd.c index 33caa032b..cab8b6940 100644 --- a/server/responder/common/responder_cmd.c +++ b/server/responder/common/responder_cmd.c @@ -36,9 +36,39 @@ void sss_cmd_done(struct cli_ctx *cctx, void *freectx) int sss_cmd_get_version(struct cli_ctx *cctx) { + uint8_t *req_body; + size_t req_blen; uint8_t *body; size_t blen; int ret; + uint32_t client_version; + int i; + static struct cli_protocol_version *cli_protocol_version = NULL; + + cctx->cli_protocol_version = NULL; + + if (cli_protocol_version == NULL) { + cli_protocol_version = register_cli_protocol_version(); + } + + if (cli_protocol_version != NULL) { + cctx->cli_protocol_version = &cli_protocol_version[0]; + + sss_packet_get_body(cctx->creq->in, &req_body, &req_blen); + if (req_blen == sizeof(uint32_t)) { + client_version = (uint32_t ) *req_body; + DEBUG(4, ("Received client version [%d].\n", client_version)); + + i=0; + while(cli_protocol_version[i].version>0) { + if (cli_protocol_version[i].version == client_version) { + cctx->cli_protocol_version = &cli_protocol_version[i]; + break; + } + i++; + } + } + } /* create response packet */ ret = sss_packet_new(cctx->creq, sizeof(uint32_t), @@ -48,7 +78,9 @@ int sss_cmd_get_version(struct cli_ctx *cctx) return ret; } sss_packet_get_body(cctx->creq->out, &body, &blen); - ((uint32_t *)body)[0] = SSS_PROTOCOL_VERSION; + ((uint32_t *)body)[0] = cctx->cli_protocol_version!=NULL ? + cctx->cli_protocol_version->version : 0; + DEBUG(4, ("Offered version [%d].\n", ((uint32_t *)body)[0])); sss_cmd_done(cctx, NULL); return EOK; diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c index cf491ccf2..a8a3c6864 100644 --- a/server/responder/nss/nsssrv_cmd.c +++ b/server/responder/nss/nsssrv_cmd.c @@ -3105,6 +3105,16 @@ done: return EOK; } +struct cli_protocol_version *register_cli_protocol_version(void) +{ + static struct cli_protocol_version nss_cli_protocol_version[] = { + {1, "2008-09-05", "initial version, \\0 terminated strings"}, + {0, NULL, NULL} + }; + + return nss_cli_protocol_version; +} + static struct sss_cmd_table nss_cmds[] = { {SSS_GET_VERSION, sss_cmd_get_version}, {SSS_NSS_GETPWNAM, nss_cmd_getpwnam}, diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c index df0cba454..02b52138e 100644 --- a/server/responder/pam/pamsrv_cmd.c +++ b/server/responder/pam/pamsrv_cmd.c @@ -656,7 +656,18 @@ static int pam_cmd_chauthtok(struct cli_ctx *cctx) { return pam_forwarder(cctx, SSS_PAM_CHAUTHTOK); } -struct sss_cmd_table *register_sss_cmds(void) { +struct cli_protocol_version *register_cli_protocol_version(void) +{ + static struct cli_protocol_version pam_cli_protocol_version[] = { + {1, "2008-09-05", "initial version, \\0 terminated strings"}, + {0, NULL, NULL} + }; + + return pam_cli_protocol_version; +} + +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}, diff --git a/sss_client/common.c b/sss_client/common.c index d0fb01183..91b65cdca 100644 --- a/sss_client/common.c +++ b/sss_client/common.c @@ -295,15 +295,29 @@ static enum nss_status sss_nss_make_request_nochecks( * 0-3: 32bit unsigned version number */ -static int sss_nss_check_version(void) +static int sss_nss_check_version(const char *socket_name) { uint8_t *repbuf; size_t replen; enum nss_status nret; int errnop; int res = NSS_STATUS_UNAVAIL; + uint32_t expected_version; + struct sss_cli_req_data req; + + if (strcmp(socket_name, SSS_NSS_SOCKET_NAME) == 0) { + expected_version = SSS_NSS_PROTOCOL_VERSION; + } else if (strcmp(socket_name, SSS_PAM_SOCKET_NAME) == 0 || + strcmp(socket_name, SSS_PAM_PRIV_SOCKET_NAME) == 0) { + expected_version = SSS_PAM_PROTOCOL_VERSION; + } else { + return NSS_STATUS_UNAVAIL; + } + + req.len = sizeof(expected_version); + req.data = &expected_version; - nret = sss_nss_make_request_nochecks(SSS_GET_VERSION, NULL, + nret = sss_nss_make_request_nochecks(SSS_GET_VERSION, &req, &repbuf, &replen, &errnop); if (nret != NSS_STATUS_SUCCESS) { return nret; @@ -313,7 +327,7 @@ static int sss_nss_check_version(void) return res; } - if (((uint32_t *)repbuf)[0] == SSS_PROTOCOL_VERSION) { + if (((uint32_t *)repbuf)[0] == expected_version) { res = NSS_STATUS_SUCCESS; } @@ -555,7 +569,7 @@ static enum sss_status sss_cli_check_socket(int *errnop, const char *socket_name sss_cli_sd = mysd; - if (sss_nss_check_version()) { + if (sss_nss_check_version(socket_name) == NSS_STATUS_SUCCESS) { return SSS_STATUS_SUCCESS; } diff --git a/sss_client/sss_cli.h b/sss_client/sss_cli.h index 17749af88..ba412fd07 100644 --- a/sss_client/sss_cli.h +++ b/sss_client/sss_cli.h @@ -21,7 +21,8 @@ #define SSS_PAM_SOCKET_NAME "/var/lib/sss/pipes/pam" #define SSS_PAM_PRIV_SOCKET_NAME "/var/lib/sss/pipes/private/pam" -#define SSS_PROTOCOL_VERSION 1 +#define SSS_NSS_PROTOCOL_VERSION 1 +#define SSS_PAM_PROTOCOL_VERSION 1 enum sss_cli_command { /* null */ -- cgit