nsssrv_services.c revision 188f9e1e646b0bed530913ca76bbcdf0f342cc66
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Copyright (C) 2012 Red Hat
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher This program is free software; you can redistribute it and/or modify
056302a92862fda16351d7192600746746f38e5dStephen Gallagher it under the terms of the GNU General Public License as published by
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher (at your option) any later version.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher This program is distributed in the hope that it will be useful,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher GNU General Public License for more details.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher You should have received a copy of the GNU General Public License
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t lookup_service_step(struct tevent_req *req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void lookup_service_done(struct tevent_req *req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define SVC_NAME_CASED (dom->case_sensitive ? state->name \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define SVC_PROTO_CASED (dom->case_sensitive ? state->proto \
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Provider Lookup Logic:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Iterate through the available caches. If the cached entry is
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * present and not expired, return it immediately(*). If it is
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * present and expired, add it to a list of domains eligible to
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * be checked. If it is in the negative cache, skip over it and
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * do not add it to the eligible domain list.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Once we have searched all of the caches, if the entry has not
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * been determined to be available, search all domains in order
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * to see if any of them contain the requested entry.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * (*) Optionally perform a midpoint cache refresh if appropriate.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher req = tevent_req_create(mem_ctx, &state, struct getserv_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (dom = cctx->rctx->domains; dom; dom = dom->next) num_domains++;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Create an array of domains to check. To save resizes, we'll
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * assume that all will be checked
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Store both the case-sensitive and lowercased names
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * in the state object, to avoid recalculating the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * lowercase in multiple domains.
056302a92862fda16351d7192600746746f38e5dStephen Gallagher state->proto = talloc_strdup(state, service_protocol);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->cased_proto = sss_get_cased_name(state, service_protocol,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If we're looking up by name */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Store both the case-sensitive and lowercased names
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * in the state object, to avoid recalculating the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * lowercase in multiple domains.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->name = talloc_strdup(state, service_name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->cased_name = sss_get_cased_name(state, service_name,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* if it is a domainless search, skip domains that require fully
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * qualified names instead */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while (dom && cmdctx->check_next && dom->fqnames) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Critical: Sysdb CTX not found for [%s]!\n", dom->name));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If we're looking up by name */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check the negative cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_ncache_check_service(nctx->ncache,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If negatively cached, return we didn't find it */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Service [%s:%s] does not exist in [%s]! "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "(negative cache)\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SVC_PROTO_CASED ? SVC_PROTO_CASED : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If this is a multi-domain search, try the next one */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* This was a single-domain search.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * exit the loop. Since it was negatively-
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * cached, don't add it to the eligible
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * domains list.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check the cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Checking cache for [%s:%s@%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SVC_PROTO_CASED ? SVC_PROTO_CASED : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else { /* Looking up by port */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check the negative cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_ncache_check_service_port(nctx->ncache,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If negatively cached, return we didn't find it */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Service [%lu:%s] does not exist in [%s]! "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "(negative cache)\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SVC_PROTO_CASED ? SVC_PROTO_CASED : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If this is a multi-domain search, try the next one */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* This was a single-domain search.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * exit the loop. Since it was negatively-
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * cached, don't add it to the eligible
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * domains list.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Check the cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Checking cache for [%lu:%s@%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SVC_PROTO_CASED ? SVC_PROTO_CASED : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sysdb_getservbyport(state, sysdb, port,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret != EOK && ret != ENOENT) goto immediate;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Not found in the cache. Add this domain to the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * list of eligible domains to check the provider.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* No provider to check. Set the negative cache here */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_ncache_set_service_name(nctx->ncache, false,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Failure to set the negative cache is non-fatal.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We'll log an error and continue.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not set negative cache for [%s][%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_ncache_set_service_port(nctx->ncache, false,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Failure to set the negative cache is non-fatal.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We'll log an error and continue.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not set negative cache for [%lu][%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If this is a multi-domain search, try the next one */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* This was a single-domain search.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * exit the loop.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Found a result. Check its validity */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("getservby* returned more than one result!\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher lastUpdate = ldb_msg_find_attr_as_uint64(state->res->msgs[0],
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cacheExpire = ldb_msg_find_attr_as_uint64(state->res->msgs[0],
056302a92862fda16351d7192600746746f38e5dStephen Gallagher (cacheExpire - lastUpdate)*nctx->cache_refresh_percent/100;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If the percentage results in an expiration
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * less than ten seconds after the lastUpdate time,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * that's too often we will simply set it to 10s
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* cache still valid */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We're past the the cache refresh timeout
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We'll return the value from the cache, but we'll also
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * queue the cache entry for update out-of-band.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Performing midpoint cache update\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Update the cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher subreq = sss_dp_get_account_send(cctx, cctx->rctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Out of memory sending out-of-band data provider "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "request\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* This is non-fatal, so we'll continue here */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We don't need to listen for a reply, so we will free the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * request here.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* The cache is valid. Return it */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Cache is expired. Add this domain to the
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * list of eligible domains to check the provider.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* If this is a multi-domain search, try the next one */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* This was a single-domain search.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * exit the loop.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* No valid cached entries found and
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * not found in negative caches.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Iterate through the domains and try
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * to look the data up.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* No domains to search. Return ENOENT */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t lookup_service_step(struct tevent_req *req)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct cli_ctx *cctx = state->dctx->cmdctx->cctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Update the cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_set_callback(subreq, lookup_service_done, req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic void lookup_service_done(struct tevent_req *subreq)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct cli_ctx *cctx = state->dctx->cmdctx->cctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct sss_domain_info *dom = state->domains[state->dom_idx];
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_dp_get_account_recv(state, subreq,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Unable to get information from Data Provider\n"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "dp_error: [%u], errno: [%u], error_msg: [%s]\n"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Will try to return what we have in cache\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher (unsigned int)err_maj, (unsigned int)err_min,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Recheck the cache after the lookup.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We can ignore the expiration values here, because
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * either we have just updated it or the provider is
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * offline. Either way, whatever is in the cache should
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * be returned, if it exists. Otherwise, move to the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * next provider.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Critical: Sysdb CTX not found for [%s]!\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Re-checking cache for [%s:%s@%s]\n",
056302a92862fda16351d7192600746746f38e5dStephen Gallagher SVC_PROTO_CASED ? SVC_PROTO_CASED : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Re-checking cache for [%lu:%s@%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SVC_PROTO_CASED ? SVC_PROTO_CASED : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Nothing in the cache.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Set the negative cache
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = sss_ncache_set_service_name(nctx->ncache, false,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Failure to set the negative cache is non-fatal.
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * We'll log an error and continue.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not set negative cache for [%s][%s]\n",
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher ret = sss_ncache_set_service_port(nctx->ncache, false,
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Failure to set the negative cache is non-fatal.
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * We'll log an error and continue.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not set negative cache for [%lu][%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Need to check other domains */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* No more domains to search. Return ENOENT */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set EAGAIN so we will re-enter the mainloop */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Cache contained results. Return them */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* An error occurred, fail the request */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* ret == EAGAIN: Reenter mainloop */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *_res = talloc_steal(mem_ctx, state->res);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int *count)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int num, i, j;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* FIXME: Should we account for fully-qualified
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * service names?
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* first 2 fields (len and reserved), filled up later */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_packet_grow(packet, 2 * sizeof(uint32_t));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (i = 0; i < msg_count; i++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* new service */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!ldb_msg_check_string_attribute(msg, "objectClass",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(1, ("Wrong object (%s) found on stack!\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* new result starts at end of previous result */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Get the service name */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Could not identify service name, skipping\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Get the port */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher port = (uint16_t) ldb_msg_find_attr_as_uint(msg, SYSDB_SVC_PORT, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("No port for service [%s]. Skipping\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Get the service protocol.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Use the requested protocol if present,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * otherwise take the first protocol returned
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * by the sysdb.
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * If more than one is available, select the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * first in the message.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher el = ldb_msg_find_element(msg, SYSDB_SVC_PROTO);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher orig_proto = (const char *)el->values[0].data;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tmpstr = sss_get_cased_name(tmp_ctx, orig_proto, dom->case_sensitive);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("sss_get_cased_name failed, skipping\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_packet_grow(packet, 2 * sizeof(uint16_t)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_packet_get_body(packet, &body, &blen);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Store the port number */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SAFEALIGN_SET_UINT32(&body[rzero + rsize], (uint32_t)htons(port), &rsize);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Get the aliases */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher el = ldb_msg_find_element(msg, SYSDB_NAME_ALIAS);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* No aliases for this user */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We'll store the alias count here */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Store the primary name */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Store the protocol */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher for (j = 0; j < num_aliases; j++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher to_sized_string(&alias, (const char *)el->values[j].data);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_packet_get_body(packet, &body, &blen);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Store the alias */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher SAFEALIGN_SET_UINT32(&body[aptr], written_aliases, &rsize);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* if num is 0 most probably something went wrong,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * reset packet and return ENOENT */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ((uint32_t *)body)[0] = num; /* num results */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher/*****************
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * getservbyname *
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *****************/
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghererrno_t parse_getservbyname(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghernss_cmd_getserv_done(struct tevent_req *req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint nss_cmd_getservbyname(struct cli_ctx *cctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdctx = talloc_zero(cctx, struct nss_cmd_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dctx = talloc_zero(cmdctx, struct nss_dom_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* get service name and protocol */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_packet_get_body(cctx->creq->in, &body, &blen);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* if not terminated fail */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = parse_getservbyname(cmdctx, body, blen,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not parse request\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Requesting info for service [%s:%s] from [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher service_protocol ? service_protocol : "<ANY>",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* this is a multidomain search */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Identify if this backend requires a provider check */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Ok, find it! */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_set_callback(req, nss_cmd_getserv_done, dctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghererrno_t parse_getservbyname(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* The raw name is at most one character shorter
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * than the body length (if the protocol wasn't
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * specified). Since this is a common case, we'll
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * just assume the maximum memory size for the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher rawname = talloc_array(tmp_ctx, char, blen - 1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Copy in the service name */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* blen - 1 was reached without hitting
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * a NULL-terminator. No protocol field
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * is possible.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Copy in the protocol */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Zero-length protocol
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Just set the protocol to NULL
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* The protocol must be no longer than the remaining
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * body space, after the name was copied.
056302a92862fda16351d7192600746746f38e5dStephen Gallagher protocol = talloc_array(tmp_ctx, char, blen - i - 1);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* blen was reached without hitting
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * a NULL-terminator.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Body longer than the name and protocol\n"));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = sss_parse_name(tmp_ctx, names, rawname,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not split name and domain of [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *domain_name = talloc_steal(mem_ctx, domname);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher *service_name = talloc_steal(mem_ctx, svc_name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher *service_protocol = talloc_steal(mem_ctx, protocol);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghernss_cmd_getserv_done(struct tevent_req *req)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int i;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher tevent_req_callback_data(req, struct nss_dom_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher reqret = getserv_recv(dctx, req, &dctx->res);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("getservbyname failed\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Either we succeeded or no domains were eligible */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_packet_new(cmdctx->cctx->creq, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_packet_get_cmd(cmdctx->cctx->creq->in),
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Notify the caller that this entry wasn't found */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_cmd_empty_packet(cmdctx->cctx->creq->out);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = fill_service(cmdctx->cctx->creq->out,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not create response packet: [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, ("Error creating packet\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghererrno_t parse_getservbyport(TALLOC_CTX *mem_ctx,
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Copy in the port */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher port_and_padding_len = 2 * sizeof(uint16_t);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Copy in the protocol */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Zero-length protocol
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * Just set the protocol to NULL
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* The protocol must be no longer than the remaining
056302a92862fda16351d7192600746746f38e5dStephen Gallagher protocol = talloc_array(tmp_ctx, char, blen - i);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* blen was reached without hitting
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * a NULL-terminator.
056302a92862fda16351d7192600746746f38e5dStephen Gallagher if (j != blen - port_and_padding_len - 1) {
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Body longer than the name and protocol\n"));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher *service_protocol = talloc_steal(mem_ctx, protocol);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher/*****************
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * getservbyport *
056302a92862fda16351d7192600746746f38e5dStephen Gallagher *****************/
056302a92862fda16351d7192600746746f38e5dStephen Gallagherint nss_cmd_getservbyport(struct cli_ctx *cctx)
056302a92862fda16351d7192600746746f38e5dStephen Gallagher cmdctx = talloc_zero(cctx, struct nss_cmd_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher dctx = talloc_zero(cmdctx, struct nss_dom_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* get service port and protocol */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher sss_packet_get_body(cctx->creq->in, &body, &blen);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* if not terminated fail */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = parse_getservbyport(cmdctx, body, blen,
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Could not parse request\n"));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Requesting info for service on port [%lu/%s]\n",
056302a92862fda16351d7192600746746f38e5dStephen Gallagher port, service_protocol ? service_protocol : "<ANY>"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* All port lookups are multidomain searches */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Identify if this backend requires a provider check */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Ok, find it! */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher req = getserv_send(cmdctx, cctx->ev, port,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_set_callback(req, nss_cmd_getserv_done, dctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghersetservent_step(struct setent_step_ctx *step_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallaghersetservent_step_done(struct tevent_req *req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghersetservent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *cctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, ("Received setservent request\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Reset the read pointers */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher req = tevent_req_create(mem_ctx, &state, struct setservent_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher state->dctx = talloc_zero(state, struct nss_dom_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->dctx->domain = cctx->rctx->domains;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Is the result context already available */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* All of the necessary data is in place
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We can return now, getservent requests will work at this point
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Object is still being constructed
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Register for notification when it's
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = nss_setent_add_ref(state, state->nctx->svcctx, req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Create a new result context
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We are creating it on the nss_ctx so that it doesn't
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * go away if the original request does. We will delete
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * it when the refcount goes to zero;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->nctx->svcctx = talloc_zero(nctx, struct getent_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Assume that all domains will have results (to avoid having
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * to reallocate later
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->nctx->svcctx->doms = talloc_zero_array(state->nctx->svcctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Add a callback reference for ourselves */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = nss_setent_add_ref(state, state->nctx->svcctx, req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* ok, start the searches */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * this request is canceled while other requests are in-progress.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher step_ctx->dctx = talloc_steal(step_ctx, state->dctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* There are more domains to check */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Re-enter the mainloop */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Error [%s] requesting info from domain [%s]. Skipping.\n",
056302a92862fda16351d7192600746746f38e5dStephen Gallagher strerror(ret), step_ctx->dctx->domain->name));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher step_ctx->dctx->domain = step_ctx->dctx->domain->next;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* All domains failed */
056302a92862fda16351d7192600746746f38e5dStephen Gallaghersetservent_step(struct setent_step_ctx *step_ctx)
056302a92862fda16351d7192600746746f38e5dStephen Gallagher tevent_req_set_callback(req, setservent_step_done, step_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagherlookup_servent_done(struct tevent_req *subreq);
056302a92862fda16351d7192600746746f38e5dStephen Gallaghersetservent_finalize(struct setent_step_ctx *step_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher req = tevent_req_create(mem_ctx, &state, struct lookup_servent_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* No provider check required. Just ask the
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Sysdb CTX not found for [%s]!\n", dom->name));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = sysdb_enumservent(state, sysdb, &state->res);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Whatever the result, we're done, so report it */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We need to ask the provider for an enumeration */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Update the cache */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher subreq = sss_dp_get_account_send(req, rctx, state->dom,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_set_callback(subreq, lookup_servent_done, req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherlookup_servent_done(struct tevent_req *subreq)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_data(req, struct lookup_servent_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = sss_dp_get_account_recv(state, subreq,
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Unable to get information from Data Provider\n"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "dp_error: [%u], errno: [%u], error_msg: [%s]\n"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "Will try to return what we have in cache\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher (unsigned int)dp_err, (unsigned int)dp_ret,
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Check the cache now */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Sysdb CTX not found for [%s]!\n", state->dom->name));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sysdb_enumservent(state, sysdb, &state->res);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Whatever the result, we're done, so report it */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_data(req, struct lookup_servent_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghersetservent_step_done(struct tevent_req *req)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_callback_data(req, struct setent_step_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct nss_dom_ctx *dctx = step_ctx->dctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct getent_ctx *svcctx = step_ctx->getent_ctx;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = lookup_servent_recv(step_ctx, req, &res);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Domain [%s] returned no results\n", dctx->domain->name));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Error [%s] while retrieving info from domain [%s]. "
056302a92862fda16351d7192600746746f38e5dStephen Gallagher "Skipping.\n", strerror(ret), dctx->domain->name));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Continue on */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Got some results
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Add the retrieved results to the list
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svcctx->doms[svcctx->num].domain = dctx->domain;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher svcctx->doms[svcctx->num].res = talloc_steal(svcctx->doms, res);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher step_ctx->dctx->domain = step_ctx->dctx->domain->next;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* There are more domains to check */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Re-enter the mainloop */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Error [%s] requesting info from domain [%s]. Skipping.\n",
056302a92862fda16351d7192600746746f38e5dStephen Gallagher strerror(ret), step_ctx->dctx->domain->name));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher step_ctx->dctx->domain = step_ctx->dctx->domain->next;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* All domains have been checked */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghersetservent_result_timeout(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghersetservent_finalize(struct setent_step_ctx *step_ctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We've finished all our lookups
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * The result object is now safe to read.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Set up a lifetime timer for this result object
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * We don't want this result object to outlive the
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * enum cache refresh timeout
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tv = tevent_timeval_current_ofs(nctx->enum_cache_timeout, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher te = tevent_add_timer(rctx->ev, nctx->svcctx, tv,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Could not set up life timer for setservent result object. "
056302a92862fda16351d7192600746746f38e5dStephen Gallagher "Entries may become stale.\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghersetservent_result_timeout(struct tevent_context *ev,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct nss_ctx *nctx = talloc_get_type(pvt, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("setservent result object has expired. Cleaning up.\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Free the service enumeration context.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * If additional getservent requests come in, they will invoke
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * an implicit setservent and refresh the result object.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghernss_cmd_setservent_done(struct tevent_req *req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher cmdctx = talloc_zero(cctx, struct nss_cmd_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ("Fatal error calling nss_cmd_setservent_send\n"));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher tevent_req_set_callback(req, nss_cmd_setservent_done, cmdctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghernss_cmd_setservent_done(struct tevent_req *req)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher tevent_req_callback_data(req, struct nss_cmd_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Either we succeeded or no domains
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * were eligible.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Return an acknowledgment
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sss_packet_new(cmdctx->cctx->creq, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher sss_packet_get_cmd(cmdctx->cctx->creq->in),
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Something bad happened.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * Return an error
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghernss_cmd_implicit_setservent_done(struct tevent_req *req);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghernss_cmd_getservent_immediate(struct nss_cmd_ctx *cmdctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint nss_cmd_getservent(struct cli_ctx *cctx)
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Requesting info for all services\n"));
056302a92862fda16351d7192600746746f38e5dStephen Gallagher cmdctx = talloc_zero(cctx, struct nss_cmd_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Save the current index and cursor locations
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * If we end up calling setservent implicitly, because the response object
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * expired and has to be recreated, we want to resume from the same
056302a92862fda16351d7192600746746f38e5dStephen Gallagher cmdctx->saved_dom_idx = cctx->svc_dom_idx;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher if(!nctx->svcctx || !nctx->svcctx->ready) {
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Make sure we invoke setservent if it hasn't been run or is still
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * processing from another client
056302a92862fda16351d7192600746746f38e5dStephen Gallagher return nss_cmd_getservent_immediate(cmdctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallaghernss_cmd_implicit_setservent_done(struct tevent_req *req)
056302a92862fda16351d7192600746746f38e5dStephen Gallagher tevent_req_callback_data(req, struct nss_cmd_ctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* ENOENT is acceptable, as it just means that there were no entries
056302a92862fda16351d7192600746746f38e5dStephen Gallagher * to be returned. This will be handled gracefully in retservent
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Implicit setservent failed with unexpected error [%d][%s]\n",
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* Restore the saved index and cursor locations */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher cmdctx->cctx->svc_dom_idx = cmdctx->saved_dom_idx;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher cmdctx->cctx->svcent_cur = cmdctx->saved_cur;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = nss_cmd_getservent_immediate(cmdctx);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Immediate retrieval failed with unexpected error "
056302a92862fda16351d7192600746746f38e5dStephen Gallaghernss_cmd_getservent_immediate(struct nss_cmd_ctx *cmdctx)
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* get max num of entries to return in one call */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher sss_packet_get_body(cctx->creq->in, &body, &blen);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher /* create response packet */
056302a92862fda16351d7192600746746f38e5dStephen Gallagher sss_packet_set_error(cctx->creq->out, ret);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher unsigned int n = 0;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (cctx->svc_dom_idx >= svcctx->num) break;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher if (n <= 0 && (cctx->svc_dom_idx+1 < svcctx->num)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!n) break;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher msgs = &(pdom->res->msgs[cctx->svcent_cur]);
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ret = sss_cmd_empty_packet(cctx->creq->out);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint nss_cmd_endservent(struct cli_ctx *cctx)
056302a92862fda16351d7192600746746f38e5dStephen Gallagher ("Terminating request info for all accounts\n"));
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* create response packet */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Reset the indices so that subsequent requests start at zero */