cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher Copyright (C) 2012 Red Hat
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher This program is free software; you can redistribute it and/or modify
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher it under the terms of the GNU General Public License as published by
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher the Free Software Foundation; either version 3 of the License, or
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher (at your option) any later version.
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher This program is distributed in the hope that it will be useful,
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher GNU General Public License for more details.
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher You should have received a copy of the GNU General Public License
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagherstatic void sss_nss_getservent_data_clean(void) {
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher if (sss_nss_getservent_data.data != NULL) {
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher/* GETSERVBYNAME Request
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 0-X: Sequence of two, zero-terminated strings (name, protocol).
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * Protocol may be zero-length to imply "any"
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * GETSERVBYPORT Request:
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 0-3: 16-bit port number in network byte order
8126906ab783494204dc853c814b0882d2a76523Stephen Gallagher * 16-X: Zero-terminated string (protocol)
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * Protocol may be zero-length to imply "any"
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 0-3: 32-bit unsigned number of results
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 4-7: 32-bit unsigned (reserved/padding)
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 7-X: Result data (blocks equal to number of results)
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * Result data:
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 0-3: 32-bit unsigned port number in network byte order
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 4-7: 32-bit unsigned number of aliases
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * 8-X: sequence of zero-terminated strings
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * (name, protocol, zero or more aliases)
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallaghersss_nss_getsvc_readrep(struct sss_nss_svc_rep *sr,
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher size_t i, l, slen, dlen, pad, ptaliases, alen;
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Buffer must contain two 32-bit integers,
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * at least one character and null-terminator
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * for the name, and at least a null-
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher * terminator for the protocol.
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* not enough space for data, bad packet */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Get the port */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Get the number of aliases */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher SAFEALIGN_COPY_UINT32(&num_aliases, buf + sizeof(uint32_t), NULL);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher sbuf = (char *)&buf[2 * sizeof(uint32_t)];
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Copy in the name */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Copy in the protocol */
8bf65dbab8703697c85b033beb5c189fce17b036Michal Zidek /* Make sure sr->buffer[i+pad] is aligned to sizeof(char *) */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Copy in the aliases */
684405758a96bd9fb47480d44f2e1a2f038f8defMichal Zidek sr->result->s_aliases = DISCARD_ALIGN(&(sr->buffer[i+pad]), char **);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher ptaliases = (sizeof(char *) * (num_aliases + 1)) + pad;
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher sr->result->s_aliases[num_aliases] = NULL; /* terminate array */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher for (l = 0; l < num_aliases; l++) {
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher sr->result->s_aliases[l] = &(sr->buffer[ptaliases]);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Caught once glibc passing in buffer == 0x0 */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher memcpy(data + name_len + 1, protocol, proto_len + 1);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* No protocol specified, pass empty string */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher nret = sss_nss_make_request(SSS_NSS_GETSERVBYNAME, &rd,
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek /* Get number of results from repbuf. */
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* no results if not found */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* only 1 result is accepted for this function */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher_nss_sss_getservbyport_r(int port, const char *protocol,
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* Caught once glibc passing in buffer == 0x0 */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* No protocol specified, pass empty string */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher nret = sss_nss_make_request(SSS_NSS_GETSERVBYPORT, &rd,
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek /* Get number of results from repbuf. */
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* no results if not found */
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher /* only 1 result is accepted for this function */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* make sure we do not have leftovers, and release memory */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher nret = sss_nss_make_request(SSS_NSS_SETSERVENT,
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagherstatic enum nss_status internal_getservent_r(struct servent *result,
cc7ee57f3adada83ac657e69636ca995d5b6948eStephen Gallagher_nss_sss_getservent_r(struct servent *result,
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher nret = internal_getservent_r(result, buffer, buflen, errnop);
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagherstatic enum nss_status internal_getservent_r(struct servent *result,
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* Caught once glibc passing in buffer == 0x0 */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* if there are leftovers return the next one */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher if (sss_nss_getservent_data.data != NULL &&
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher sss_nss_getservent_data.ptr < sss_nss_getservent_data.len) {
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher repbuf = sss_nss_getservent_data.data + sss_nss_getservent_data.ptr;
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher replen = sss_nss_getservent_data.len - sss_nss_getservent_data.ptr;
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher ret = sss_nss_getsvc_readrep(&pwrep, repbuf, &replen);
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* advance buffer pointer */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher sss_nss_getservent_data.ptr = sss_nss_getservent_data.len - replen;
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* release memory if any */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher nret = sss_nss_make_request(SSS_NSS_GETSERVENT, &rd,
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek /* Get number of results from repbuf */
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* no results if not found */
a171d77f40aa92e240e91aa4bafe5a392a98b5a2Michal Zidek if ((num_results == 0) || (replen - SVC_METADATA_COUNT == 0)) {
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* skip metadata fields */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher sss_nss_getservent_data.ptr = SVC_METADATA_COUNT;
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* call again ourselves, this will return the first result */
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher return internal_getservent_r(result, buffer, buflen, errnop);
cff6bb5f8ee424b0e3aff74247e103e44075b16aStephen Gallagher /* make sure we do not have leftovers, and release memory */