autofssrv_cmd.c revision 4668b4765530cf37289235e483f301100cc1ae21
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek Copyright (C) 2012 Red Hat
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek Autofs responder: commands
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek This program is free software; you can redistribute it and/or modify
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek it under the terms of the GNU General Public License as published by
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek the Free Software Foundation; either version 3 of the License, or
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek (at your option) any later version.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek This program is distributed in the hope that it will be useful,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek GNU General Public License for more details.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek You should have received a copy of the GNU General Public License
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic int autofs_cmd_send_error(struct autofs_cmd_ctx *cmdctx, int err)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekautofs_cmd_send_empty(struct autofs_cmd_ctx *cmdctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek return sss_cmd_send_empty(cmdctx->cctx, cmdctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekautofs_cmd_done(struct autofs_cmd_ctx *cmdctx, int ret)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* all fine, just return here */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* async processing, just return here */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* very bad error */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek return setent_add_ref(memctx, map_ctx, &map_ctx->reqs, req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekautofs_setent_notify(struct autofs_map_ctx *map_ctx, errno_t ret)
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek unsigned long mcount;
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek unsigned long i;
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek for (i = 0; i < mcount; i++) {
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("Could not delete key from hash\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek *map = talloc_get_type(value.ptr, struct autofs_map_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Unexpected error reading from autofs map hash [%d][%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic int autofs_map_hash_remove (TALLOC_CTX *ctx);
08c72b84d85d482f030a30cf74786695f097e91cJakub Hrozek map = talloc_get_type(item->value.ptr, struct autofs_map_ctx);
08c72b84d85d482f030a30cf74786695f097e91cJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Invalid autofs map\n"));
08c72b84d85d482f030a30cf74786695f097e91cJakub Hrozek /* So that the destructor wouldn't attempt to remove the map from hash
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Missing autofs map name.\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Add this entry to the hash table */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Unable to add hash table entry for [%s]", key.str));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Hash error [%d][%s]", hret, hash_error_string(hret)));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek talloc_set_destructor((TALLOC_CTX *) map, autofs_map_hash_remove);
08c72b84d85d482f030a30cf74786695f097e91cJakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, ("autofs map [%s] was already removed\n",
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek /* Remove the autofs map result object from the lookup table */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not remove key from table! [%d][%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic struct tevent_req *
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic errno_t setautomntent_recv(struct tevent_req *req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void sss_autofs_cmd_setautomntent_done(struct tevent_req *req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek/* FIXME - file a ticket to have per-responder private
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * data instead of growing the cli_ctx structure */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksss_autofs_cmd_setautomntent(struct cli_ctx *client)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("sss_autofs_cmd_setautomntent\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cmdctx = talloc_zero(client, struct autofs_cmd_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek sss_packet_get_body(client->creq->in, &body, &blen);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* if not terminated fail */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If the body isn't valid UTF-8, fail */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Got request for automount map named %s\n", rawname));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek req = setautomntent_send(cmdctx, rawname, cmdctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Fatal error calling setautomntent_send\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek tevent_req_set_callback(req, sss_autofs_cmd_setautomntent_done, cmdctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void sss_autofs_cmd_setautomntent_done(struct tevent_req *req)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek tevent_req_callback_data(req, struct autofs_cmd_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("setautomntent done\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_recv failed\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Either we succeeded or no domains were eligible */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("setautomntent did not find requested map\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Notify the caller that this entry wasn't found */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("setautomntent found data\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sss_packet_grow(packet, 2*sizeof(uint32_t));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Couldn't grow the packet\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ((uint32_t *)body)[0] = 1; /* Got some results */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Error creating packet\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeklookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekautofs_map_result_timeout(struct tevent_context *ev,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Free the autofs map result context
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * The destructor for the autofs map will remove itself
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * from the hash table
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not set up life timer for autofs maps. "
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "Entries may become stale.\n"));
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozeksetautomntent_get_autofs_map(struct autofs_ctx *actx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic struct tevent_req *
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek req = tevent_req_create(mem_ctx, &state, struct setautomntent_state);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Could not create tevent request for setautomntent\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek dctx = talloc_zero(state, struct autofs_dom_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory\n"));
1542b85f13d72329685bdd97aa879c36d11f81beSumit Bose ret = sss_parse_name_for_domains(state, client->rctx->domains,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Requesting info for automount map [%s] from [%s]\n",
4668b4765530cf37289235e483f301100cc1ae21Sumit Bose dctx->domain = responder_get_domain(client->rctx, domname);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek client->automntmap_name = talloc_strdup(client, rawname);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* this is a multidomain search */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek client->automntmap_name = talloc_strdup(client, state->mapname);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Is the result context already available?
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Check for existing lookups for this map
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek ret = setautomntent_get_autofs_map(actx, state->mapname, &state->map);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Another process already requested this map
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Check whether it's ready for processing.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Map %s is ready to be processed\n", state->mapname));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Map %s was marked as nonexistent\n", state->mapname));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Result object is still being constructed
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Register for notification when it's ready
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Map %s is being looked up, registering for notification\n",
129310e872a0a70e721ba59363e518176ef406d6Jakub Hrozek ret = autofs_setent_add_ref(state, state->map, req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Will return control below */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Map %s needs to be looked up\n", state->mapname));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek state->map = talloc_zero(actx, struct autofs_map_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek state->map->mapname = talloc_strdup(state->map, state->mapname);
129310e872a0a70e721ba59363e518176ef406d6Jakub Hrozek ret = autofs_setent_add_ref(state, state->map, req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Perform lookup */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek lookup_ctx = talloc_zero(state->map, struct setautomntent_lookup_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Steal the dom_ctx onto the lookup_ctx so it doesn't go out of scope if
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * this request is canceled while other requests are in-progress.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek lookup_ctx->dctx = talloc_steal(lookup_ctx, state->dctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("lookup_automntmap_step "
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "is refreshing the cache, re-entering the mainloop\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Could not get data from cache\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Unexpected error from get_autofs_map [%d]: %s\n",
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozeksetautomntent_get_autofs_map(struct autofs_ctx *actx,
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek /* Iterate over the hash and remove all maps */
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("Could not remove existing maps from hash\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeklookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeklookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct sss_domain_info *dom = lookup_ctx->dctx->domain;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct autofs_dom_ctx *dctx = lookup_ctx->dctx;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Check each domain for this map name */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* if it is a domainless search, skip domains that require fully
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * qualified names instead */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek while (dom && dctx->cmd_ctx->check_next && dom->fqnames) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* No domains left to search */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (!dom) break;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* make sure we reset the check_provider flag when we check
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * a new domain */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* make sure to update the dctx if we changed domain */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Requesting info for [%s@%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Fatal: Sysdb CTX not found for this domain!\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Look into the cache */
2913240aee51ce81195148a4d814e967f66839c4Simo Sorce ret = sysdb_get_map_byname(dctx, sysdb, dom, lookup_ctx->mapname,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Could not check cache\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("No automount map [%s] in cache for domain [%s]\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Moving on to next domain\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = get_autofs_map(lookup_ctx->actx, lookup_ctx->mapname, &map);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Something really bad happened! */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Autofs map entry was lost!\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (dctx->map == NULL && !dctx->check_provider) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Autofs map not found, setting negative cache\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = lookup_automntmap_update_cache(lookup_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Looking up automount maps from the DP\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Error looking up automount maps [%d]: %s\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* OK, the map is in cache and valid.
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek * Let's get all members and return it
2913240aee51ce81195148a4d814e967f66839c4Simo Sorce ret = sysdb_autofs_entries_by_map(map, sysdb, dom, map->mapname,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Error looking automount map entries [%d]: %s\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("setautomntent done for map %s\n", lookup_ctx->mapname));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek set_autofs_map_lifetime(dom->autofsmap_timeout, lookup_ctx, map);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek map = talloc_zero(lookup_ctx->actx, struct autofs_map_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek map->mapname = talloc_strdup(map, lookup_ctx->mapname);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If we've gotten here, then no domain contained this map */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void autofs_dp_send_map_req_done(struct tevent_req *req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeklookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct autofs_dom_ctx *dctx = lookup_ctx->dctx;
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek if (strcmp(lookup_ctx->mapname, "auto.master") != 0) {
1bcb68cc3069a6bd539289e68a87a0815aa2a1beJakub Hrozek cache_expire = ldb_msg_find_attr_as_uint64(dctx->map,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* if we have any reply let's check cache validity */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sss_cmd_check_cache(dctx->map, 0, cache_expire);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Cached entry is valid, returning..\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Error checking cache: %d\n", ret));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* dont loop forever :-) */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* keep around current data in case backend is offline */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* FIXME - do this by default */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek req = sss_dp_get_autofs_send(lookup_ctx->cctx, lookup_ctx->rctx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Out of memory sending data provider request\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cb_ctx = talloc_zero(lookup_ctx->dctx, struct dp_callback_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cb_ctx->callback = lookup_automntmap_cache_updated;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cb_ctx->cctx = lookup_ctx->dctx->cmd_ctx->cctx;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek tevent_req_set_callback(req, autofs_dp_send_map_req_done, cb_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = autofs_cmd_send_error(lookup_ctx->dctx->cmd_ctx, ret);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek autofs_cmd_done(lookup_ctx->dctx->cmd_ctx, ret);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void autofs_dp_send_map_req_done(struct tevent_req *req)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek tevent_req_callback_data(req, struct dp_callback_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek talloc_get_type(cb_ctx->ptr, struct setautomntent_lookup_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ret = sss_dp_get_autofs_recv(cb_ctx->mem_ctx, req,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstatic void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek talloc_get_type(ptr, struct setautomntent_lookup_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek struct autofs_dom_ctx *dctx = lookup_ctx->dctx;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("Unable to get information from Data Provider\n"
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "Error: %u, %u, %s\n"
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek "Will try to return what we have in cache\n",
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek (unsigned int)err_maj, (unsigned int)err_min, err_msg));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* Loop to the next domain if possible */
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce if (dctx->cmd_ctx->check_next && get_next_domain(dctx->domain, false)) {
0232747f04b650796db56fd7b487aee8a96fab03Simo Sorce dctx->domain = get_next_domain(dctx->domain, false);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* ok the backend returned, search to see if we have updated results */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* We have results to return */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekgetautomntent_process(struct autofs_cmd_ctx *cmdctx,
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozekgetautomntent_implicit_done(struct tevent_req *req);
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozekfill_autofs_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksss_autofs_cmd_getautomntent(struct cli_ctx *client)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("sss_autofs_cmd_getautomntent\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cmdctx = talloc_zero(client, struct autofs_cmd_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Missing autofs context\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* get autofs map name and index to query */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek sss_packet_get_body(client->creq->in, &body, &blen);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* if not null-terminated fail */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If the name isn't valid UTF-8, fail */
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) {
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->cursor, body+c+namelen+1, blen, &c);
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->max_entries, body+c+namelen+1, blen, &c);
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek ("Requested data of map %s cursor %d max entries %d\n",
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek cmdctx->mapname, cmdctx->cursor, cmdctx->max_entries));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ret = get_autofs_map(actx, cmdctx->mapname, &map);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("An unexpected error occurred: [%d][%s]\n",
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("negative cache hit\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("returning entries for [%s]\n", map->mapname));
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek ret = getautomntent_process(cmdctx, map, cmdctx->cursor, cmdctx->max_entries);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozekgetautomntent_implicit_done(struct tevent_req *req)
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek tevent_req_callback_data(req, struct autofs_cmd_ctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_recv failed\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No such map\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ret = get_autofs_map(actx, cmdctx->mapname, &map);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Cannot get map after setautomntent succeeded?\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Map not ready after setautomntent succeeded\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekgetautomntent_process(struct autofs_cmd_ctx *cmdctx,
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* create response packet */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (!map->map || !map->entries || !map->entries[0] ||
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No entries found\n"));
cd2327153a9ac55f3cf470c294691506096bd1ebPavel Březina /* allocate memory for number of entries in the packet */
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek ret = sss_packet_grow(client->creq->out, sizeof(uint32_t));
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Cannot grow packet\n"));
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek rp = sizeof(uint32_t); /* We'll write the number of entries here */
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek stop = max_entries < left ? max_entries : left;
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek for (i=0; i < stop; i++) {
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek ret = fill_autofs_entry(entry, client->creq->out, &rp);
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek ("Cannot fill entry %d/%d, skipping\n", i, stop));
cd2327153a9ac55f3cf470c294691506096bd1ebPavel Březina /* packet grows in fill_autofs_entry, body pointer may change,
cd2327153a9ac55f3cf470c294691506096bd1ebPavel Březina * thus we have to obtain it here */
cd2327153a9ac55f3cf470c294691506096bd1ebPavel Březina sss_packet_get_body(client->creq->out, &body, &blen);
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek SAFEALIGN_SET_UINT32(&body[rp], nentries, &rp);
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozekfill_autofs_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp)
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek const char *key;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek key = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_KEY, NULL);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek value = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_VALUE, NULL);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("Incomplete entry\n"));
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek len = sizeof(uint32_t) + sizeof(uint32_t) + keylen + sizeof(uint32_t) + valuelen;
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Cannot grow packet\n"));
c83ebdbc0629313ef6594215ed1674b9a783cfddJakub Hrozek SAFEALIGN_SET_UINT32(&body[*rp], valuelen, rp);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozekgetautomntbyname_process(struct autofs_cmd_ctx *cmdctx,
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek const char *key);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozekgetautomntbyname_implicit_done(struct tevent_req *req);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksss_autofs_cmd_getautomntbyname(struct cli_ctx *client)
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("sss_autofs_cmd_getautomntbyname\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek cmdctx = talloc_zero(client, struct autofs_cmd_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Missing autofs context\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* get autofs map name and index to query */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek sss_packet_get_body(client->creq->in, &body, &blen);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* FIXME - split out a function to get string from <len><str>\0 */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* if not null-terminated fail */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If the name isn't valid UTF-8, fail */
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* FIXME - split out a function to get string from <len><str>\0 */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&keylen, body+c, blen, &c);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* if not null-terminated fail */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* If the key isn't valid UTF-8, fail */
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek if (!sss_utf8_check((const uint8_t *) cmdctx->key, keylen -1)) {
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Requested data of map %s key %s\n", cmdctx->mapname, cmdctx->key));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ret = get_autofs_map(actx, cmdctx->mapname, &map);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek ("An unexpected error occurred: [%d][%s]\n",
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("negative cache hit\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Looking up value for [%s] in [%s]\n", cmdctx->key, map->mapname));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ret = getautomntbyname_process(cmdctx, map, cmdctx->key);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozekgetautomntbyname_implicit_done(struct tevent_req *req)
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek tevent_req_callback_data(req, struct autofs_cmd_ctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_recv failed\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No such map\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ret = get_autofs_map(actx, cmdctx->mapname, &map);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Cannot get map after setautomntent succeeded?\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ("Map not ready after setautomntent succeeded\n"));
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek ret = getautomntbyname_process(cmdctx, map, cmdctx->key);
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozekgetautomntbyname_process(struct autofs_cmd_ctx *cmdctx,
5dfb1257f62839eea1c31669cf3bbcb114c22183Jakub Hrozek const char *key)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek const char *k;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* create response packet */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek if (!map->map || !map->entries || !map->entries[0]) {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No entries found\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek k = ldb_msg_find_attr_as_string(map->entries[i],
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("Skipping incomplete entry\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Found key [%s]\n", key));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No key named [%s] found\n", key));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek value = ldb_msg_find_attr_as_string(map->entries[i],
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek len = sizeof(uint32_t) + sizeof(uint32_t) + valuelen;
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek sss_packet_get_body(client->creq->out, &body, &blen);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek SAFEALIGN_SET_UINT32(&body[rp], valuelen, &rp);
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozeksss_autofs_cmd_endautomntent(struct cli_ctx *client)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("endautomntent called\n"));
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek /* create response packet */
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozekstruct cli_protocol_version *register_cli_protocol_version(void)
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek static struct cli_protocol_version autofs_cli_protocol_version[] = {
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek { SSS_AUTOFS_SETAUTOMNTENT, sss_autofs_cmd_setautomntent },
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek { SSS_AUTOFS_GETAUTOMNTENT, sss_autofs_cmd_getautomntent },
9e80079370ff3b943832adc3c5ef430e64be0a0cJakub Hrozek { SSS_AUTOFS_GETAUTOMNTBYNAME, sss_autofs_cmd_getautomntbyname },