proxy_services.c revision aec5785126354bd8b192f63fe04ea08dae9c0705
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder/*
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder SSSD
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder Authors:
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder Stephen Gallagher <sgallagh@redhat.com>
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder Copyright (C) 2012 Red Hat
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder This program is free software; you can redistribute it and/or modify
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder it under the terms of the GNU General Public License as published by
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder the Free Software Foundation; either version 3 of the License, or
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder (at your option) any later version.
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder This program is distributed in the hope that it will be useful,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder GNU General Public License for more details.
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder You should have received a copy of the GNU General Public License
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder*/
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder#include "providers/proxy/proxy.h"
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder#include "util/util.h"
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder#include "util/strtonum.h"
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder#include "db/sysdb_services.h"
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder#define BUFLEN 1024
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maedererrno_t
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maederproxy_save_service(struct sysdb_ctx *sysdb,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder struct servent *svc,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder bool lowercase,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder uint64_t cache_timeout)
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder{
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder errno_t ret;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder char *cased_name;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder const char **protocols;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder const char **cased_aliases;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder TALLOC_CTX *tmp_ctx;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder size_t num_aliases, i;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder time_t now = time(NULL);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder tmp_ctx = talloc_new(NULL);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!tmp_ctx) return ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_name = sss_get_cased_name(tmp_ctx, svc->s_name, !lowercase);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!cased_name) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder goto done;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder protocols = talloc_array(tmp_ctx, const char *, 2);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!protocols) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder goto done;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder protocols[0] = sss_get_cased_name(protocols, svc->s_proto,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder !lowercase);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!protocols[0]) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder goto done;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder protocols[1] = NULL;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
8b8548df458142254941ca61bbc1e7177f7c7c08Simon Ulbricht /* Count the aliases */
8b8548df458142254941ca61bbc1e7177f7c7c08Simon Ulbricht for(num_aliases = 0; svc->s_aliases[num_aliases]; num_aliases++);
8b8548df458142254941ca61bbc1e7177f7c7c08Simon Ulbricht
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (num_aliases >= 1) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_aliases = talloc_array(tmp_ctx, const char *, num_aliases + 1);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!cased_aliases) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder goto done;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder for (i = 0; i < num_aliases; i++) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_aliases[i] = sss_get_cased_name(tmp_ctx, svc->s_aliases[i],
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder !lowercase);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!cased_aliases[i]) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder goto done;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_aliases[num_aliases] = NULL;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder } else {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_aliases = NULL;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder }
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = sysdb_store_service(sysdb,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_name,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ntohs(svc->s_port),
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cased_aliases,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder protocols,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder cache_timeout,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder now);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maederdone:
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder talloc_free(tmp_ctx);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder return ret;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder}
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maedererrno_t
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maederget_serv_byname(struct proxy_id_ctx *ctx,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder struct sysdb_ctx *sysdb,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder struct sss_domain_info *dom,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder const char *name,
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder const char *protocol)
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder{
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder errno_t ret;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder enum nss_status status;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder struct servent *result;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder TALLOC_CTX *tmp_ctx;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder char buffer[BUFLEN];
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder tmp_ctx = talloc_new(NULL);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!tmp_ctx) return ENOMEM;
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder result = talloc_zero(tmp_ctx, struct servent);
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder if (!result) {
158e6d8b5f7ebabef2d020ff045ede18fab15ff9Christian Maeder ret = ENOMEM;
goto done;
}
status = ctx->ops.getservbyname_r(name, protocol, result,
buffer, BUFLEN, &ret);
if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_NOTFOUND) {
DEBUG(SSSDBG_MINOR_FAILURE,
("getservbyname_r failed for service [%s].\n", name));
return ret;
}
if (status == NSS_STATUS_NOTFOUND) {
/* Make sure we remove it from the cache */
ret = sysdb_svc_delete(sysdb, name, 0, protocol);
} else {
/* Results found. Save them into the cache */
ret = proxy_save_service(sysdb, result,
!dom->case_sensitive,
ctx->entry_cache_timeout);
}
done:
talloc_free(tmp_ctx);
return ret;
}
errno_t
get_serv_byport(struct proxy_id_ctx *ctx,
struct sysdb_ctx *sysdb,
struct sss_domain_info *dom,
const char *be_filter,
const char *protocol)
{
errno_t ret;
enum nss_status status;
struct servent *result;
TALLOC_CTX *tmp_ctx;
uint16_t port;
char buffer[BUFLEN];
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
result = talloc_zero(tmp_ctx, struct servent);
if (!result) {
ret = ENOMEM;
goto done;
}
errno = 0;
port = htons(strtouint16(be_filter, NULL, 0));
if (errno) {
ret = errno;
goto done;
}
status = ctx->ops.getservbyport_r(port, protocol, result,
buffer, BUFLEN, &ret);
if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_NOTFOUND) {
DEBUG(SSSDBG_MINOR_FAILURE,
("getservbyport_r failed for service [%s].\n", be_filter));
return ret;
}
if (status == NSS_STATUS_NOTFOUND) {
/* Make sure we remove it from the cache */
ret = sysdb_svc_delete(sysdb, NULL, port, protocol);
} else {
/* Results found. Save them into the cache */
ret = proxy_save_service(sysdb, result,
!dom->case_sensitive,
ctx->entry_cache_timeout);
}
done:
talloc_free(tmp_ctx);
return ret;
}