summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2012-01-06 16:47:50 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-01-18 09:27:56 -0500
commitfd3714d0cf068f3c782c1fff32105fc51cc97a0e (patch)
tree4763af29c0a5e3fa2dd293744dccb1f268e7fca9
parent4e19af30cbaf819bdd88f7d0390aeabeb2797a60 (diff)
downloadsssd-fd3714d0cf068f3c782c1fff32105fc51cc97a0e.tar.gz
sssd-fd3714d0cf068f3c782c1fff32105fc51cc97a0e.tar.xz
sssd-fd3714d0cf068f3c782c1fff32105fc51cc97a0e.zip
NSS: Add sss_readrep_copy_string
There were many places in the client code where we were duplicating a loop to copy data in from the response buffer. This patch turns those loops into a function for easier maintenance and easier-to-read *readrep() routines.
-rw-r--r--src/sss_client/common.c30
-rw-r--r--src/sss_client/nss_group.c66
-rw-r--r--src/sss_client/nss_netgroup.c105
-rw-r--r--src/sss_client/nss_passwd.c99
-rw-r--r--src/sss_client/sss_cli.h12
5 files changed, 131 insertions, 181 deletions
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index 94d15a529..998f7c8ce 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -918,3 +918,33 @@ void sss_pam_lock(void) { return; }
void sss_pam_unlock(void) { return; }
#endif
+
+errno_t sss_readrep_copy_string(const char *in,
+ size_t *offset,
+ size_t *slen,
+ size_t *dlen,
+ char **out,
+ size_t *size)
+{
+ size_t i = 0;
+ while (*slen > *offset && *dlen > 0) {
+ (*out)[i] = in[*offset];
+ if ((*out)[i] == '\0') break;
+ i++;
+ (*offset)++;
+ (*dlen)--;
+ }
+ if (*slen <= *offset) { /* premature end of buf */
+ return EBADMSG;
+ }
+ if (*dlen == 0) { /* not enough memory */
+ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
+ }
+ (*offset)++;
+ (*dlen)--;
+ if (size) {
+ *size = i;
+ }
+
+ return EOK;
+}
diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c
index f5e715c86..7e5f79ad5 100644
--- a/src/sss_client/nss_group.c
+++ b/src/sss_client/nss_group.c
@@ -78,8 +78,8 @@ struct sss_nss_gr_rep {
static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
uint8_t *buf, size_t *len)
{
- size_t i, l, slen, ptmem, pad;
- ssize_t dlen;
+ errno_t ret;
+ size_t i, l, slen, ptmem, pad, dlen, glen;
char *sbuf;
uint32_t mem_num;
uint32_t c;
@@ -98,36 +98,19 @@ static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
pr->result->gr_name = &(pr->buffer[0]);
i = 0;
- 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--;
+
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->gr_name,
+ NULL);
+ if (ret != EOK) return ret;
pr->result->gr_passwd = &(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--;
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->gr_passwd,
+ NULL);
+ if (ret != EOK) return ret;
/* Make sure pr->buffer[i+pad] is 32 bit aligned */
pad = 0;
@@ -147,22 +130,13 @@ static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
for (l = 0; l < mem_num; l++) {
pr->result->gr_mem[l] = &(pr->buffer[ptmem]);
- while ((slen > i) && (dlen > 0)) {
- pr->buffer[ptmem] = sbuf[i];
- if (pr->buffer[ptmem] == '\0') break;
- i++;
- dlen--;
- ptmem++;
- }
- 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--;
- ptmem++;
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->gr_mem[l],
+ &glen);
+ if (ret != EOK) return ret;
+
+ ptmem += glen + 1;
}
*len = slen -i;
diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c
index f63b11359..f72d547e8 100644
--- a/src/sss_client/nss_netgroup.c
+++ b/src/sss_client/nss_netgroup.c
@@ -62,9 +62,10 @@ struct sss_nss_netgr_rep {
static int sss_nss_getnetgr_readrep(struct sss_nss_netgr_rep *pr,
uint8_t *buf, size_t *len)
{
+ errno_t ret;
char *sbuf;
- size_t i, slen;
- ssize_t dlen;
+ char *temp;
+ size_t i, slen, dlen, size;
uint32_t type;
if (*len < 6) {
@@ -84,92 +85,66 @@ static int sss_nss_getnetgr_readrep(struct sss_nss_netgr_rep *pr,
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--;
+ temp = &(pr->buffer[i]);
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &temp,
+ &size);
+ if (ret != EOK) return ret;
/* libc expects NULL instead of empty string */
- if (strlen(pr->result->val.triple.host) == 0) {
+ if (size == 0) {
pr->result->val.triple.host = NULL;
+ } else {
+ pr->result->val.triple.host = temp;
}
/* 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--;
+ temp = &(pr->buffer[i]);
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &temp,
+ &size);
+ if (ret != EOK) return ret;
/* libc expects NULL instead of empty string */
- if (strlen(pr->result->val.triple.user) == 0) {
+ if (size == 0) {
pr->result->val.triple.user = NULL;
+ } else {
+ pr->result->val.triple.user = temp;
}
/* 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--;
+ temp = &(pr->buffer[i]);
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &temp,
+ &size);
+ if (ret != EOK) return ret;
/* libc expects NULL instead of empty string */
- if (strlen(pr->result->val.triple.domain) == 0) {
+ if (size == 0) {
pr->result->val.triple.domain = NULL;
+ } else {
+ pr->result->val.triple.domain = temp;
}
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--;
+ temp = &(pr->buffer[i]);
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &temp,
+ NULL);
+ if (ret != EOK) return ret;
+
+ pr->result->val.group = temp;
break;
+
default:
return EBADMSG;
}
diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c
index 15de59728..16124948e 100644
--- a/src/sss_client/nss_passwd.c
+++ b/src/sss_client/nss_passwd.c
@@ -72,6 +72,7 @@ struct sss_nss_pw_rep {
static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
uint8_t *buf, size_t *len)
{
+ errno_t ret;
size_t i, slen, dlen;
char *sbuf;
uint32_t c;
@@ -91,84 +92,42 @@ static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
i = 0;
pr->result->pw_name = &(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--;
+
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->pw_name,
+ NULL);
+ if (ret != EOK) return ret;
pr->result->pw_passwd = &(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--;
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->pw_passwd,
+ NULL);
+ if (ret != EOK) return ret;
pr->result->pw_gecos = &(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--;
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->pw_gecos,
+ NULL);
+ if (ret != EOK) return ret;
+
pr->result->pw_dir = &(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--;
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->pw_dir,
+ NULL);
+ if (ret != EOK) return ret;
pr->result->pw_shell = &(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 */
- }
-
- *len = slen -i -1;
+ ret = sss_readrep_copy_string(sbuf, &i,
+ &slen, &dlen,
+ &pr->result->pw_shell,
+ NULL);
+ if (ret != EOK) return ret;
+ *len = slen - i;
return 0;
}
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
index dc15ac13b..c6e53e60a 100644
--- a/src/sss_client/sss_cli.h
+++ b/src/sss_client/sss_cli.h
@@ -36,6 +36,11 @@
typedef int errno_t;
#endif
+
+#ifndef EOK
+#define EOK 0
+#endif
+
#define SSS_NSS_PROTOCOL_VERSION 1
#define SSS_PAM_PROTOCOL_VERSION 3
#define SSS_SUDO_PROTOCOL_VERSION 0
@@ -508,4 +513,11 @@ void sss_nss_unlock(void);
void sss_pam_lock(void);
void sss_pam_unlock(void);
+errno_t sss_readrep_copy_string(const char *in,
+ size_t *offset,
+ size_t *slen,
+ size_t *dlen,
+ char **out,
+ size_t *size);
+
#endif /* _SSSCLI_H */