diff options
author | Sumit Bose <sbose@redhat.com> | 2010-10-01 11:30:44 +0200 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-10-13 09:49:37 -0400 |
commit | 36fc83f3f64bb16db7bef3e1cebe829424edacd1 (patch) | |
tree | 562368dab0ce034d0b06061c273cc82cb8771afb /src | |
parent | c640ae818270b1e8d57190516587d06c007d3938 (diff) | |
download | sssd-36fc83f3f64bb16db7bef3e1cebe829424edacd1.tar.gz sssd-36fc83f3f64bb16db7bef3e1cebe829424edacd1.tar.bz2 sssd-36fc83f3f64bb16db7bef3e1cebe829424edacd1.zip |
Add handling of nested netgroups to nss client
Diffstat (limited to 'src')
-rw-r--r-- | src/responder/nss/nsssrv_netgroup.c | 5 | ||||
-rw-r--r-- | src/sss_client/nss_netgroup.c | 172 | ||||
-rw-r--r-- | src/sss_client/sss_cli.h | 5 |
3 files changed, 113 insertions, 69 deletions
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c index 8c6de84c..706a660c 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 edc5020f..86178544 100644 --- a/src/sss_client/nss_netgroup.c +++ b/src/sss_client/nss_netgroup.c @@ -45,11 +45,14 @@ static struct sss_nss_getnetgrent_data { /* * Replies: * - * 0-3: 32bit unsigned number of results + * 0-3: 32bit unsigned number of results N * 4-7: 32bit unsigned (reserved/padding) * For each result: - * 8-X: sequence of \0 terminated strings representing tuple - * (host, user, domain) + * 8-11: 32bit unsigned type of result + * 12-X: \0 terminated string representing a tuple + * (host, user, domain) + * or a netgroup, depending on the type indicator + * ... repeated N times */ #define NETGR_METADATA_COUNT 2 * sizeof(uint32_t) struct sss_nss_netgr_rep { @@ -77,82 +80,115 @@ static int sss_nss_getnetgr_readrep(struct sss_nss_netgr_rep *pr, char *sbuf; size_t i, slen; ssize_t dlen; + uint32_t type; - if (*len < 3) { + if (*len < 6) { /* Not enough space for data, bad packet */ return EBADMSG; } - sbuf = (char *)&buf[0]; - slen = *len; + sbuf = (char *)(buf + sizeof(uint32_t)); + slen = *len - sizeof(uint32_t); dlen = pr->buflen; - /* Host value */ 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 */ + SAFEALIGN_COPY_UINT32(&type, buf, NULL); + switch (type) { + 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; } - 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; - } *len = slen -i; diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index 1a068d5f..fcea8e64 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, |