From d6ef3bfcb0793d36d4db1b53d6e02372062554ef Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 1 Oct 2010 11:30:44 +0200 Subject: [PATCH 3/8] Add handling of nested netgroups to nss client --- src/responder/nss/nsssrv_netgroup.c | 5 +- src/sss_client/nss_netgroup.c | 173 +++++++++++++++++++++-------------- src/sss_client/sss_cli.h | 5 + 3 files changed, 112 insertions(+), 71 deletions(-) diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c index 0989c9a..c1c1901 100644 --- a/src/responder/nss/nsssrv_netgroup.c +++ b/src/responder/nss/nsssrv_netgroup.c @@ -797,13 +797,16 @@ static errno_t nss_cmd_retnetgrent(struct cli_ctx *client, domainlen += strlen(triples[client->netgrent_cur]->domainname); } - len = hostlen + userlen + domainlen; + len = 1 + hostlen + userlen + domainlen; ret = sss_packet_grow(packet, len); if (ret != EOK) { return ret; } sss_packet_get_body(packet, &body, &blen); + body[rp] = SSS_NETGR_REP_TRIPLE; + rp++; + if (hostlen == 1) { body[rp] = '\0'; } else { diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c index edc5020..1b213c6 100644 --- a/src/sss_client/nss_netgroup.c +++ b/src/sss_client/nss_netgroup.c @@ -48,8 +48,10 @@ static struct sss_nss_getnetgrent_data { * 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) * For each result: - * 8-X: sequence of \0 terminated strings representing tuple + * 8-X: sequence of a type indicator and \0 terminated strings representing + * tuple * (host, user, domain) + * or a netgroup, depending on the type indicator */ #define NETGR_METADATA_COUNT 2 * sizeof(uint32_t) struct sss_nss_netgr_rep { @@ -78,83 +80,114 @@ static int sss_nss_getnetgr_readrep(struct sss_nss_netgr_rep *pr, size_t i, slen; ssize_t dlen; - if (*len < 3) { + if (*len < 4) { /* Not enough space for data, bad packet */ return EBADMSG; } - sbuf = (char *)&buf[0]; + sbuf = (char *)&buf[1]; slen = *len; dlen = pr->buflen; - /* Host value */ + /* Type */ i = 0; - pr->result->val.triple.host = &(pr->buffer[i]); - while (slen > i && dlen > 0) { - pr->buffer[i] = sbuf[i]; - if (pr->buffer[i] == '\0') break; - i++; - dlen--; - } - if (slen <= i) { /* premature end of buf */ - return EBADMSG; - } - if (dlen <= 0) { /* not enough memory */ - return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ - } - i++; - dlen--; - - /* libc expects NULL instead of empty string */ - if (strlen(pr->result->val.triple.host) == 0) { - pr->result->val.triple.host = NULL; - } - - /* User value */ - pr->result->val.triple.user = &(pr->buffer[i]); - while (slen > i && dlen > 0) { - pr->buffer[i] = sbuf[i]; - if (pr->buffer[i] == '\0') break; - i++; - dlen--; - } - if (slen <= i) { /* premature end of buf */ - return EBADMSG; - } - if (dlen <= 0) { /* not enough memory */ - return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ - } - i++; - dlen--; - - /* libc expects NULL instead of empty string */ - if (strlen(pr->result->val.triple.user) == 0) { - pr->result->val.triple.user = NULL; + switch (buf[0]) { + case SSS_NETGR_REP_TRIPLE: + pr->result->type = triple_val; + + /* Host value */ + pr->result->val.triple.host = &(pr->buffer[i]); + while (slen > i && dlen > 0) { + pr->buffer[i] = sbuf[i]; + if (pr->buffer[i] == '\0') break; + i++; + dlen--; + } + if (slen <= i) { /* premature end of buf */ + return EBADMSG; + } + if (dlen <= 0) { /* not enough memory */ + return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ + } + i++; + dlen--; + + /* libc expects NULL instead of empty string */ + if (strlen(pr->result->val.triple.host) == 0) { + pr->result->val.triple.host = NULL; + } + + /* User value */ + pr->result->val.triple.user = &(pr->buffer[i]); + while (slen > i && dlen > 0) { + pr->buffer[i] = sbuf[i]; + if (pr->buffer[i] == '\0') break; + i++; + dlen--; + } + if (slen <= i) { /* premature end of buf */ + return EBADMSG; + } + if (dlen <= 0) { /* not enough memory */ + return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ + } + i++; + dlen--; + + /* libc expects NULL instead of empty string */ + if (strlen(pr->result->val.triple.user) == 0) { + pr->result->val.triple.user = NULL; + } + + /* Domain value */ + pr->result->val.triple.domain = &(pr->buffer[i]); + while (slen > i && dlen > 0) { + pr->buffer[i] = sbuf[i]; + if (pr->buffer[i] == '\0') break; + i++; + dlen--; + } + if (slen <= i) { /* premature end of buf */ + return EBADMSG; + } + if (dlen <= 0) { /* not enough memory */ + return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ + } + i++; + dlen--; + + /* libc expects NULL instead of empty string */ + if (strlen(pr->result->val.triple.domain) == 0) { + pr->result->val.triple.domain = NULL; + } + + break; + case SSS_NETGR_REP_GROUP: + pr->result->type = group_val; + + pr->result->val.group = &(pr->buffer[i]); + while (slen > i && dlen > 0) { + pr->buffer[i] = sbuf[i]; + if (pr->buffer[i] == '\0') break; + i++; + dlen--; + } + if (slen <= i) { /* premature end of buf */ + return EBADMSG; + } + if (dlen <= 0) { /* not enough memory */ + return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ + } + i++; + dlen--; + + break; + default: + return EBADMSG; } - /* Domain value */ - pr->result->val.triple.domain = &(pr->buffer[i]); - while (slen > i && dlen > 0) { - pr->buffer[i] = sbuf[i]; - if (pr->buffer[i] == '\0') break; - i++; - dlen--; - } - if (slen <= i) { /* premature end of buf */ - return EBADMSG; - } - if (dlen <= 0) { /* not enough memory */ - return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ - } - i++; - dlen--; - - /* libc expects NULL instead of empty string */ - if (strlen(pr->result->val.triple.domain) == 0) { - pr->result->val.triple.domain = NULL; - } - *len = slen -i; + *len = slen -i -1; return 0; } diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index 1a068d5..fcea8e6 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -410,6 +410,11 @@ enum user_info_type { * @} */ /* end of group sss_pam_cli */ +enum sss_netgr_rep_type { + SSS_NETGR_REP_TRIPLE = 1, + SSS_NETGR_REP_GROUP +}; + enum sss_cli_error_codes { ESSS_SSS_CLI_ERROR_START = 0x1000, ESSS_BAD_PRIV_SOCKET, -- 1.7.2.3