summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-10-01 11:30:44 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-10-13 09:49:37 -0400
commit36fc83f3f64bb16db7bef3e1cebe829424edacd1 (patch)
tree562368dab0ce034d0b06061c273cc82cb8771afb /src
parentc640ae818270b1e8d57190516587d06c007d3938 (diff)
downloadsssd-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.c5
-rw-r--r--src/sss_client/nss_netgroup.c172
-rw-r--r--src/sss_client/sss_cli.h5
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,