diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2012-12-23 20:35:12 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2012-12-23 20:35:12 +0100 |
commit | f94a0d4e903ea040a38a56096e8f0f0eadb93a40 (patch) | |
tree | bb69ff593bc65763c06babd3f5ae30c5842fd87f /nss | |
parent | c7bb19c55c7a902e25bdd33b0d49a2ddcf62e07a (diff) |
update the netgroup by name request to have one result entry per netgroup with multiple rows within one result
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1874 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nss')
-rw-r--r-- | nss/netgroup.c | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/nss/netgroup.c b/nss/netgroup.c index f9421d2..17c6023 100644 --- a/nss/netgroup.c +++ b/nss/netgroup.c @@ -32,17 +32,9 @@ #include "compat/attrs.h" #include "common/set.h" -/* we redefine this here because we need to return NSS_STATUS_RETURN - instead of NSS_STATUS_NOTFOUND */ -#undef ERROR_OUT_NOSUCCESS -#define ERROR_OUT_NOSUCCESS(fp) \ - (void)tio_close(fp); \ - fp = NULL; \ - return NSS_STATUS_RETURN; - /* function for reading a single result entry */ -static nss_status_t read_netgrent(TFILE *fp, struct __netgrent *result, - char *buffer, size_t buflen, int *errnop) +static nss_status_t read_netgrent_line(TFILE *fp, struct __netgrent *result, + char *buffer, size_t buflen, int *errnop) { int32_t tmpint32; int type; @@ -54,6 +46,7 @@ static nss_status_t read_netgrent(TFILE *fp, struct __netgrent *result, /* the response is a reference to another netgroup */ result->type = group_val; READ_BUF_STRING(fp, result->val.group); + return NSS_STATUS_SUCCESS; } else if (type == NSLCD_NETGROUP_TYPE_TRIPLE) { @@ -80,11 +73,14 @@ static nss_status_t read_netgrent(TFILE *fp, struct __netgrent *result, result->val.triple.domain = NULL; bufptr--; /* free unused space */ } + return NSS_STATUS_SUCCESS; } - else - return NSS_STATUS_UNAVAIL; - /* we're done */ - return NSS_STATUS_SUCCESS; + else if (type == NSLCD_NETGROUP_TYPE_END) + /* make _nss_ldap_getnetgrent_r() indicate the end of the netgroup */ + return NSS_STATUS_RETURN; + /* we got something unexpected */ + ERROR_OUT_NOSUCCESS(fp); + return NSS_STATUS_UNAVAIL; } #ifdef NSS_FLAVOUR_GLIBC @@ -100,16 +96,18 @@ nss_status_t _nss_ldap_setnetgrent(const char *group, available in this function */ int32_t tmpint32; int errnocp; - int *errnop; - if (!_nss_ldap_enablelookups) - return NSS_STATUS_UNAVAIL; - errnop = &errnocp; + int *errnop = &errnocp; + NSS_EXTRA_DEFS + NSS_AVAILCHECK; /* check parameter */ if ((group == NULL) || (group[0] == '\0')) return NSS_STATUS_UNAVAIL; /* open a new stream and write the request */ NSLCD_REQUEST(netgrentfp, NSLCD_ACTION_NETGROUP_BYNAME, WRITE_STRING(netgrentfp, group)); + /* read response code */ + READ_RESPONSE_CODE(netgrentfp); + SKIP_STRING(netgrentfp); /* netgroup name */ return NSS_STATUS_SUCCESS; } @@ -117,8 +115,35 @@ nss_status_t _nss_ldap_setnetgrent(const char *group, nss_status_t _nss_ldap_getnetgrent_r(struct __netgrent *result, char *buffer, size_t buflen, int *errnop) { - NSS_GETENT(netgrentfp, NSLCD_ACTION_NETGROUP_BYNAME, - read_netgrent(netgrentfp, result, buffer, buflen, errnop)); + nss_status_t retv; + NSS_EXTRA_DEFS; + NSS_AVAILCHECK; + NSS_BUFCHECK; + /* check that we have a valid file descriptor */ + if (netgrentfp == NULL) + return NSS_STATUS_UNAVAIL; + /* prepare for buffer errors */ + tio_mark(netgrentfp); + /* read a response */ + retv = read_netgrent_line(netgrentfp, result, buffer, buflen, errnop); + /* check read result */ + if (retv == NSS_STATUS_TRYAGAIN) + { + /* if we have a full buffer try to reset the stream */ + if (tio_reset(netgrentfp)) + { + /* reset failed, we close and give up with a permanent error + because we cannot retry just the getent() call because it + may not be only the first entry that failed */ + tio_close(netgrentfp); + netgrentfp = NULL; + *errnop = EINVAL; + return NSS_STATUS_UNAVAIL; + } + } + else if ((retv != NSS_STATUS_SUCCESS) && (retv != NSS_STATUS_RETURN)) + netgrentfp = NULL; /* file should be closed by now */ + return retv; } /* close the stream opened with setnetgrent() above */ @@ -185,8 +210,7 @@ static nss_status_t netgroup_nslcd_getnetgrent(nss_backend_t *be, void *args) { NSS_GETENT(NETGROUP_BE(be)->fp, NSLCD_ACTION_NETGROUP_BYNAME, - read_netgrent(NETGROUP_BE(be)->fp, result, buffer, buflen, - errnop)); + read_netgrent_line(NETGROUP_BE(be)->fp, result, buffer, buflen, errnop)); } static nss_status_t netgroup_setnetgrent_setnetgrent(nss_backend_t |