nss_services.c revision cff6bb5f8ee424b0e3aff74247e103e44075b16a
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen Stephen Gallagher <sgallagh@redhat.com>
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen Copyright (C) 2012 Red Hat
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen This program is free software; you can redistribute it and/or modify
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen it under the terms of the GNU General Public License as published by
463e82bdf0e990f4f2252d2b53ea23a5abe5883cTimo Sirainen the Free Software Foundation; either version 3 of the License, or
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (at your option) any later version.
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen This program is distributed in the hope that it will be useful,
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
d41573018e85896ec836d897fd554e87126147f5Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen GNU General Public License for more details.
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen You should have received a copy of the GNU General Public License
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainenstatic void sss_nss_getservent_data_clean(void) {
7bd3f5614e0dd2324dd1015f084de72c0b069a1aTimo Sirainen/* GETSERVBYNAME Request
2c677e9d339bc91d5b54376ba2986f71476c06abTimo Sirainen * 0-X: Sequence of two, zero-terminated strings (name, protocol).
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen * Protocol may be zero-length to imply "any"
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen * GETSERVBYPORT Request:
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen * 0-3: 16-bit port number in network byte order
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen * 8-X: Zero-terminated string (protocol)
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen * Protocol may be zero-length to imply "any"
153de7823e64c67678b3fc95719c41a8ec5b864dTimo Sirainen * 0-3: 32-bit unsigned number of results
f81a4d2002da0db33d11ca694d3a91b3ee2a0fdbTimo Sirainen * 4-7: 32-bit unsigned (reserved/padding)
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen * 7-X: Result data (blocks equal to number of results)
e6d7d19c328e7043ad35d5a52c1617bde915a16fTimo Sirainen * Result data:
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen * 0-3: 32-bit unsigned port number in network byte order
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen * 4-7: 32-bit unsigned number of aliases
7de1c472fd23ddac6b4dc5cbeee6fa6a8418b071Timo Sirainen * 8-X: sequence of zero-terminated strings
7de1c472fd23ddac6b4dc5cbeee6fa6a8418b071Timo Sirainen * (name, protocol, zero or more aliases)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainensss_nss_getsvc_readrep(struct sss_nss_svc_rep *sr,
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen size_t i, l, slen, dlen, pad, ptaliases, alen;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* Buffer must contain two 32-bit integers,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen * at least one character and null-terminator
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen * for the name, and at least a null-
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen * terminator for the protocol.
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* not enough space for data, bad packet */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* Get the port */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Get the number of aliases */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen SAFEALIGN_COPY_UINT32(&num_aliases, buf + sizeof(uint32_t), NULL);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* Copy in the name */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Copy in the protocol */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* Make sure sr->buffer[i+pad] is 32-bit aligned */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen /* Copy in the aliases */
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen sr->result->s_aliases = (char **) &(sr->buffer[i+pad]);
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen ptaliases = (sizeof(char *) * (num_aliases + 1)) + pad;
1cad0dd34667548ba39f794ddeb9fc486cf4c666Timo Sirainen return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen sr->result->s_aliases[num_aliases] = NULL; /* terminate array */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen for (l = 0; l < num_aliases; l++) {
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen sr->result->s_aliases[l] = &(sr->buffer[ptaliases]);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen /* Caught once glibc passing in buffer == 0x0 */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen memcpy(data + name_len + 1, protocol, proto_len + 1);
68b3667c9ee95951d7c3e03b19b2d37abbaa5736Timo Sirainen /* No protocol specified, pass empty string */
7889c9f65e23c83fc31cecf304cab4ab070d6aa1Timo Sirainen nret = sss_nss_make_request(SSS_NSS_GETSERVBYNAME, &rd,
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen /* no results if not found */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen /* only 1 result is accepted for this function */
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen_nss_sss_getservbyport_r(int port, const char *protocol,
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen /* Caught once glibc passing in buffer == 0x0 */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* Padding */
1e2887ae909d9817cc43a7e40ecb50508419f7edTimo Sirainen memcpy(data + sizeof(uint32_t)*2, protocol, proto_len + 1);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* No protocol specified, pass empty string */
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen nret = sss_nss_make_request(SSS_NSS_GETSERVBYPORT, &rd,
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen /* no results if not found */
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen /* only 1 result is accepted for this function */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* make sure we do not have leftovers, and release memory */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen nret = sss_nss_make_request(SSS_NSS_SETSERVENT,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenstatic enum nss_status internal_getservent_r(struct servent *result,
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen nret = internal_getservent_r(result, buffer, buflen, errnop);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenstatic enum nss_status internal_getservent_r(struct servent *result,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* Caught once glibc passing in buffer == 0x0 */
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen /* if there are leftovers return the next one */
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen sss_nss_getservent_data.ptr < sss_nss_getservent_data.len) {
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen repbuf = sss_nss_getservent_data.data + sss_nss_getservent_data.ptr;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen replen = sss_nss_getservent_data.len - sss_nss_getservent_data.ptr;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen ret = sss_nss_getsvc_readrep(&pwrep, repbuf, &replen);
51920d00fa50edf7b2e9b1019288d64b7abee7f3Timo Sirainen /* advance buffer pointer */
21ec6628c567eeff025af35d8027be01044b0b1aTimo Sirainen sss_nss_getservent_data.ptr = sss_nss_getservent_data.len - replen;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen /* release memory if any */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen nret = sss_nss_make_request(SSS_NSS_GETSERVENT, &rd,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* no results if not found */
d647e72663b52cb2301df5eaf93e67ee873a41f8Timo Sirainen /* skip metadata fields */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen sss_nss_getservent_data.ptr = SVC_METADATA_COUNT;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* call again ourselves, this will return the first result */
9887c39c5ba429169389153ca99de49e084a73f0Timo Sirainen return internal_getservent_r(result, buffer, buflen, errnop);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* make sure we do not have leftovers, and release memory */