From fd3714d0cf068f3c782c1fff32105fc51cc97a0e Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Fri, 6 Jan 2012 16:47:50 -0500 Subject: 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. --- src/sss_client/common.c | 30 ++++++++++++ src/sss_client/nss_group.c | 66 ++++++++------------------ src/sss_client/nss_netgroup.c | 105 ++++++++++++++++-------------------------- src/sss_client/nss_passwd.c | 99 ++++++++++++--------------------------- src/sss_client/sss_cli.h | 12 +++++ 5 files changed, 131 insertions(+), 181 deletions(-) (limited to 'src/sss_client') 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 */ -- cgit