diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2012-01-06 16:47:50 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-01-18 09:27:56 -0500 |
commit | fd3714d0cf068f3c782c1fff32105fc51cc97a0e (patch) | |
tree | 4763af29c0a5e3fa2dd293744dccb1f268e7fca9 | |
parent | 4e19af30cbaf819bdd88f7d0390aeabeb2797a60 (diff) | |
download | sssd-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.c | 30 | ||||
-rw-r--r-- | src/sss_client/nss_group.c | 66 | ||||
-rw-r--r-- | src/sss_client/nss_netgroup.c | 105 | ||||
-rw-r--r-- | src/sss_client/nss_passwd.c | 99 | ||||
-rw-r--r-- | src/sss_client/sss_cli.h | 12 |
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 */ |