5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina Pavel Březina <pbrezina@redhat.com>
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina Copyright (C) 2012 Red Hat
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina This program is free software; you can redistribute it and/or modify
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina it under the terms of the GNU General Public License as published by
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina the Free Software Foundation; either version 3 of the License, or
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina (at your option) any later version.
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina This program is distributed in the hope that it will be useful,
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina GNU General Public License for more details.
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina You should have received a copy of the GNU General Public License
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březinastatic int sdap_sudo_get_ip_addresses(TALLOC_CTX *mem_ctx, char ***_ip_addr);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic void sdap_sudo_get_hostinfo_done(struct tevent_req *req);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx,
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic void sdap_sudo_get_hostnames_done(struct tevent_req *subreq);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic int sdap_sudo_get_hostnames_recv(TALLOC_CTX *mem_ctx,
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březinastruct tevent_req * sdap_sudo_get_hostinfo_send(TALLOC_CTX *mem_ctx,
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina struct sdap_sudo_get_hostinfo_state *state = NULL;
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina /* create request */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "tevent_req_create() failed\n");
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina /* load info from configuration */
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina conf_hostnames = dp_opt_get_string(opts->basic, SDAP_SUDO_HOSTNAMES);
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina conf_ip_addr = dp_opt_get_string(opts->basic, SDAP_SUDO_IP);
04759b59e71c78ab23b84d13dd29d9c6dd680adbMichal Zidek ret = split_on_separator(state, conf_hostnames, ' ', true, true,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to parse hostnames [%d]: %s\n", ret, strerror(ret));
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Hostnames set to: %s\n", conf_hostnames);
04759b59e71c78ab23b84d13dd29d9c6dd680adbMichal Zidek ret = split_on_separator(state, conf_ip_addr, ' ', true, true,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to parse IP addresses [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "IP addresses set to: %s\n",
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* if IP addresses are not specified, configure it automatically */
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina ret = sdap_sudo_get_ip_addresses(state, &state->ip_addr);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unable to detect IP addresses [%d]: %s\n",
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina /* if hostnames are not specified, configure it automatically */
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina subreq = sdap_sudo_get_hostnames_send(state, be_ctx);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina tevent_req_set_callback(subreq, sdap_sudo_get_hostinfo_done, req);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic void sdap_sudo_get_hostinfo_done(struct tevent_req *subreq)
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina struct sdap_sudo_get_hostinfo_state *state = NULL;
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state = tevent_req_data(req, struct sdap_sudo_get_hostinfo_state);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina ret = sdap_sudo_get_hostnames_recv(state, subreq, &state->hostnames);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve hostnames [%d]: %s\n",
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březinaint sdap_sudo_get_hostinfo_recv(TALLOC_CTX *mem_ctx,
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina struct sdap_sudo_get_hostinfo_state *state = NULL;
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina state = tevent_req_data(req, struct sdap_sudo_get_hostinfo_state);
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina *hostnames = talloc_steal(mem_ctx, state->hostnames);
5f73b623fc72e3b9b3590420825f30e618b4d4ddPavel Březina *ip_addr = talloc_steal(mem_ctx, state->ip_addr);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic int sdap_sudo_get_ip_addresses(TALLOC_CTX *mem_ctx,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not read interfaces [%d][%s]\n",
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina for (iface = ifaces; iface != NULL; iface = iface->ifa_next) {
34c222586c1ee4790ce3ff86a2ffb27c666c0662Stef Walter /* Some interfaces don't have an ifa_addr */
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek memcpy(&ip4_addr, iface->ifa_addr, sizeof(struct sockaddr_in));
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek memcpy(&ip4_network, iface->ifa_netmask, sizeof(struct sockaddr_in));
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* get network mask length */
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek ip4_netmask = ntohl(ip4_network.sin_addr.s_addr);
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* get network address */
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek ip4_network.sin_addr.s_addr = ip4_addr.sin_addr.s_addr
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek memcpy(&ip6_addr, iface->ifa_addr, sizeof(struct sockaddr_in6));
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek memcpy(&ip6_network, iface->ifa_netmask, sizeof(struct sockaddr_in6));
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* get network mask length */
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina for (i = 0; i < 4; i++) {
3bd01976012ac3959f76da3272ce03964b359356Michal Zidek ip6_netmask = ntohl(((uint32_t*)(&ip6_network.sin6_addr))[i]);
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* get network address */
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina for (i = 0; i < 4; i++) {
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* skip other families */
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* ip address */
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina if (inet_ntop(iface->ifa_addr->sa_family, sinx_addr,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop() failed [%d]: %s\n",
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina /* network */
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina if (inet_ntop(iface->ifa_addr->sa_family, sinx_network,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop() failed [%d]: %s\n",
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina ip_addr_list = talloc_realloc(tmp_ctx, ip_addr_list, char*,
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina ip_addr_list[addr_count - 2] = talloc_strdup(ip_addr_list, ip_addr);
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina ip_addr_list[addr_count - 1] = talloc_asprintf(ip_addr_list, "%s/%d",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Found IP address: %s in network %s/%d\n",
468f1c8d4763a65f24ab8d7523a5291ef6320db7Pavel Březina *_ip_addr_list = talloc_steal(mem_ctx, ip_addr_list);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina * SUDO allows only one hostname that is returned from gethostname()
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina * (and set to "localhost" if the returned value is empty)
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina * and then - if allowed - resolves its fqdn using gethostbyname() or
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina * getaddrinfo() if available.
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx,
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina struct sdap_sudo_get_hostnames_state *state = NULL;
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina /* hostname, fqdn and NULL */
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state->hostnames = talloc_zero_array(state, char*, 3);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina /* get hostname */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve machine hostname "
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state->hostnames[0] = talloc_strdup(state->hostnames, hostname);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina /* already a fqdn, determine hostname and finish */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Found fqdn: %s\n", hostname);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Found hostname: %s\n", hostname);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state->hostnames[1] = talloc_strdup(state->hostnames, hostname);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Found hostname: %s\n", hostname);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina /* get fqdn */
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina subreq = resolv_gethostbyname_send(state, state->ev, state->resolv_ctx,
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina tevent_req_set_callback(subreq, sdap_sudo_get_hostnames_done, req);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic void sdap_sudo_get_hostnames_done(struct tevent_req *subreq)
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina struct sdap_sudo_get_hostnames_state *state = NULL;
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state = tevent_req_data(req, struct sdap_sudo_get_hostnames_state);
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina ret = resolv_gethostbyname_recv(subreq, state, &resolv_status, NULL,
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina /* Empty result, just quit */
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "No hostent found\n");
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not resolve fqdn for this machine, error [%d]: %s, "
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina "resolver returned: [%d]: %s\n", ret, strerror(ret),
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov resolv_status, resolv_strerror(resolv_status));
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Found fqdn: %s\n", rhostent->name);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "state->hostnames is NULL\n");
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state->hostnames[1] = talloc_strdup(state->hostnames, rhostent->name);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březinastatic int sdap_sudo_get_hostnames_recv(TALLOC_CTX *mem_ctx,
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina struct sdap_sudo_get_hostnames_state *state = NULL;
fbaaa993eff7ef1ed5a62c38d6cdacd52a53d2d8Pavel Březina state = tevent_req_data(req, struct sdap_sudo_get_hostnames_state);