aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher/*
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher SSSD
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher Authors:
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher Copyright (C) 2012 Red Hat
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher This program is free software; you can redistribute it and/or modify
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher it under the terms of the GNU General Public License as published by
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher (at your option) any later version.
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher This program is distributed in the hope that it will be useful,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher GNU General Public License for more details.
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher You should have received a copy of the GNU General Public License
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher*/
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher#include "providers/proxy/proxy.h"
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher#include "util/util.h"
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher#include "util/strtonum.h"
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher#include "db/sysdb_services.h"
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher#define BUFLEN 1024
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallaghererrno_t
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidekproxy_save_service(struct sss_domain_info *domain,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher struct servent *svc,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher bool lowercase,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher uint64_t cache_timeout)
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher{
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher errno_t ret;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher char *cased_name;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher const char **protocols;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher const char **cased_aliases;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher TALLOC_CTX *tmp_ctx;
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek char *lc_alias = NULL;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher time_t now = time(NULL);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher tmp_ctx = talloc_new(NULL);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!tmp_ctx) return ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek cased_name = sss_get_cased_name(tmp_ctx, svc->s_name,
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek domain->case_preserve);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!cased_name) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ret = ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher protocols = talloc_array(tmp_ctx, const char *, 2);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!protocols) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ret = ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher protocols[0] = sss_get_cased_name(protocols, svc->s_proto,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher !lowercase);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!protocols[0]) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ret = ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher protocols[1] = NULL;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher /* Count the aliases */
215280b9af59ab28abc501c242e4802984c9281aJakub Hrozek ret = sss_get_cased_name_list(tmp_ctx,
215280b9af59ab28abc501c242e4802984c9281aJakub Hrozek (const char * const *) svc->s_aliases,
215280b9af59ab28abc501c242e4802984c9281aJakub Hrozek !lowercase, &cased_aliases);
215280b9af59ab28abc501c242e4802984c9281aJakub Hrozek if (ret != EOK) {
215280b9af59ab28abc501c242e4802984c9281aJakub Hrozek goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek if (domain->case_preserve) {
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek /* Add lowercased alias to allow case-insensitive lookup */
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek lc_alias = sss_tc_utf8_str_tolower(tmp_ctx, svc->s_name);
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek if (lc_alias == NULL) {
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n");
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek ret = ENOMEM;
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek goto done;
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek }
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek ret = add_string_to_list(tmp_ctx, lc_alias,
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek discard_const_p(char **, &cased_aliases));
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek if (ret != EOK) {
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek DEBUG(SSSDBG_OP_FAILURE,
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek "Failed to add lowercased name alias.\n");
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek goto done;
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek }
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek }
38429c99bf5af14c2d6bae6ddcf70974fdd103ccMichal Zidek
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_store_service(domain,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher cased_name,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ntohs(svc->s_port),
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher cased_aliases,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher protocols,
e299638926171e0e92a36122aeff6611cd52418dStephen Gallagher NULL, NULL,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher cache_timeout,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher now);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagherdone:
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher talloc_free(tmp_ctx);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher return ret;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher}
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallaghererrno_t
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagherget_serv_byname(struct proxy_id_ctx *ctx,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher struct sss_domain_info *dom,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher const char *name,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher const char *protocol)
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher{
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher errno_t ret;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher enum nss_status status;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher struct servent *result;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher TALLOC_CTX *tmp_ctx;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher char buffer[BUFLEN];
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher tmp_ctx = talloc_new(NULL);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!tmp_ctx) return ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher result = talloc_zero(tmp_ctx, struct servent);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!result) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ret = ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher status = ctx->ops.getservbyname_r(name, protocol, result,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher buffer, BUFLEN, &ret);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_NOTFOUND) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "getservbyname_r failed for service [%s].\n", name);
8c9ecf0bd04be87a61d5f0e490ab8a7c48f481ddPavel Reichl goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (status == NSS_STATUS_NOTFOUND) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher /* Make sure we remove it from the cache */
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_svc_delete(dom, name, 0, protocol);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher } else {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher /* Results found. Save them into the cache */
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = proxy_save_service(dom, result,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher !dom->case_sensitive,
bd92e8ee315d4da9350b9ef0358c88a7b54aeebeStephen Gallagher dom->service_timeout);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagherdone:
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher talloc_free(tmp_ctx);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher return ret;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher}
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallaghererrno_t
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagherget_serv_byport(struct proxy_id_ctx *ctx,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher struct sss_domain_info *dom,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher const char *be_filter,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher const char *protocol)
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher{
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher errno_t ret;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher enum nss_status status;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher struct servent *result;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher TALLOC_CTX *tmp_ctx;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher uint16_t port;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher char buffer[BUFLEN];
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher tmp_ctx = talloc_new(NULL);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!tmp_ctx) return ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher result = talloc_zero(tmp_ctx, struct servent);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (!result) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ret = ENOMEM;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher errno = 0;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher port = htons(strtouint16(be_filter, NULL, 0));
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (errno) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher ret = errno;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher status = ctx->ops.getservbyport_r(port, protocol, result,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher buffer, BUFLEN, &ret);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_NOTFOUND) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "getservbyport_r failed for service [%s].\n", be_filter);
8c9ecf0bd04be87a61d5f0e490ab8a7c48f481ddPavel Reichl goto done;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher if (status == NSS_STATUS_NOTFOUND) {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher /* Make sure we remove it from the cache */
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_svc_delete(dom, NULL, port, protocol);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher } else {
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher /* Results found. Save them into the cache */
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = proxy_save_service(dom, result,
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher !dom->case_sensitive,
bd92e8ee315d4da9350b9ef0358c88a7b54aeebeStephen Gallagher dom->service_timeout);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher }
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagherdone:
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher talloc_free(tmp_ctx);
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher return ret;
aec5785126354bd8b192f63fe04ea08dae9c0705Stephen Gallagher}
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallaghererrno_t
627d83dff183219826489949cb55ef71945e94abStephen Gallagherenum_services(struct proxy_id_ctx *ctx,
627d83dff183219826489949cb55ef71945e94abStephen Gallagher struct sysdb_ctx *sysdb,
627d83dff183219826489949cb55ef71945e94abStephen Gallagher struct sss_domain_info *dom)
627d83dff183219826489949cb55ef71945e94abStephen Gallagher{
627d83dff183219826489949cb55ef71945e94abStephen Gallagher TALLOC_CTX *tmpctx;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher bool in_transaction = false;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher struct servent *svc;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher enum nss_status status;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher size_t buflen;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher char *buffer;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher char *newbuf;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher errno_t ret, sret;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher time_t now = time(NULL);
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek const char **protocols;
215280b9af59ab28abc501c242e4802984c9281aJakub Hrozek const char **cased_aliases;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos bool again;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Enumerating services\n");
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallagher tmpctx = talloc_new(NULL);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (!tmpctx) {
627d83dff183219826489949cb55ef71945e94abStephen Gallagher return ENOMEM;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallagher svc = talloc(tmpctx, struct servent);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (!svc) {
627d83dff183219826489949cb55ef71945e94abStephen Gallagher ret = ENOMEM;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher goto done;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallagher buflen = DEFAULT_BUFSIZE;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher buffer = talloc_size(tmpctx, buflen);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (!buffer) {
627d83dff183219826489949cb55ef71945e94abStephen Gallagher ret = ENOMEM;
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek goto done;
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek }
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek protocols = talloc_zero_array(tmpctx, const char *, 2);
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek if (protocols == NULL) {
980a535ac81b0f63ce18fc2311dab702ced7fdc6Jakub Hrozek ret = ENOMEM;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher goto done;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallagher ret = sysdb_transaction_start(sysdb);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (ret) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
627d83dff183219826489949cb55ef71945e94abStephen Gallagher goto done;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher in_transaction = true;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallagher status = ctx->ops.setservent();
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (status != NSS_STATUS_SUCCESS) {
627d83dff183219826489949cb55ef71945e94abStephen Gallagher ret = EIO;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher goto done;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos do {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos again = false;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos /* always zero out the svc structure */
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos memset(svc, 0, sizeof(struct servent));
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos /* get entry */
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos status = ctx->ops.getservent_r(svc, buffer, buflen, &ret);
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos switch (status) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos case NSS_STATUS_TRYAGAIN:
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz /* buffer too small? */
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos if (buflen < MAX_BUF_SIZE) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos buflen *= 2;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos if (buflen > MAX_BUF_SIZE) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos buflen = MAX_BUF_SIZE;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos newbuf = talloc_realloc_size(tmpctx, buffer, buflen);
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos if (!newbuf) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos ret = ENOMEM;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos goto done;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos buffer = newbuf;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos again = true;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos break;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos case NSS_STATUS_NOTFOUND:
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos /* we are done here */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Enumeration completed.\n");
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos ret = sysdb_transaction_commit(sysdb);
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek goto done;
21d485184df986e1a123f70c689517386e51a5ceMichal Zidek }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos in_transaction = false;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos break;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos case NSS_STATUS_SUCCESS:
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos DEBUG(SSSDBG_TRACE_INTERNAL,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Service found (%s, %d/%s)\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov svc->s_name, svc->s_port, svc->s_proto);
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos protocols[0] = sss_get_cased_name(protocols, svc->s_proto,
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos dom->case_sensitive);
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos if (!protocols[0]) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos ret = ENOMEM;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos goto done;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos protocols[1] = NULL;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos ret = sss_get_cased_name_list(tmpctx,
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos (const char * const *) svc->s_aliases,
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos dom->case_sensitive, &cased_aliases);
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos if (ret != EOK) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos /* Do not fail completely on errors.
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos * Just report the failure to save and go on */
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to store service [%s]. Ignoring.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov strerror(ret));
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos again = true;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos break;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek ret = sysdb_store_service(dom,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek svc->s_name,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek svc->s_port,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek cased_aliases,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek protocols,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek NULL, NULL,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek dom->service_timeout,
4fcc50e133f90cd4c5931a3ac48c84cb628b16fcMichal Zidek now);
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos if (ret) {
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos /* Do not fail completely on errors.
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos * Just report the failure to save and go on */
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Failed to store service [%s]. Ignoring.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov strerror(ret));
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos again = true;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos break;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos case NSS_STATUS_UNAVAIL:
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos /* "remote" backend unavailable. Enter offline mode */
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos ret = ENXIO;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos break;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos default:
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos ret = EIO;
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "proxy -> getservent_r failed (%d)[%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos break;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
499718cb04a534ba76ee9dfb055c2bfc96fdeeb3Ondrej Kos } while (again);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher
627d83dff183219826489949cb55ef71945e94abStephen Gallagherdone:
627d83dff183219826489949cb55ef71945e94abStephen Gallagher talloc_zfree(tmpctx);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (in_transaction) {
627d83dff183219826489949cb55ef71945e94abStephen Gallagher sret = sysdb_transaction_cancel(sysdb);
627d83dff183219826489949cb55ef71945e94abStephen Gallagher if (sret != EOK) {
627d83dff183219826489949cb55ef71945e94abStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not cancel transaction! [%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov strerror(sret));
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher }
627d83dff183219826489949cb55ef71945e94abStephen Gallagher ctx->ops.endservent();
627d83dff183219826489949cb55ef71945e94abStephen Gallagher return ret;
627d83dff183219826489949cb55ef71945e94abStephen Gallagher}