From 9a96214baea9fd899aa1dee3e221c8354ca26e55 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Thu, 23 Feb 2012 14:49:38 +0100 Subject: [PATCH] AUTOFS: Invoke implicit setautomntent if needed https://fedorahosted.org/sssd/ticket/1167 --- src/responder/autofs/autofs_private.h | 2 + src/responder/autofs/autofssrv_cmd.c | 199 +++++++++++++++++++++++++-------- 2 files changed, 156 insertions(+), 45 deletions(-) diff --git a/src/responder/autofs/autofs_private.h b/src/responder/autofs/autofs_private.h index 753089d24f767c9f6bac9799d3fd23708cb9fadf..b29b3bb0df7c92e23f5a752b0d57a7f3c59548e2 100644 --- a/src/responder/autofs/autofs_private.h +++ b/src/responder/autofs/autofs_private.h @@ -37,6 +37,8 @@ struct autofs_ctx { struct autofs_cmd_ctx { struct cli_ctx *cctx; char *mapname; + char *key; + uint32_t cursor; bool check_next; }; diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c index 2be87290270b7033bd8742cc4c85a0d8074196a6..58ffce1a05e640173f7e0a8b2fc0b4657f4dd4ba 100644 --- a/src/responder/autofs/autofssrv_cmd.c +++ b/src/responder/autofs/autofssrv_cmd.c @@ -127,7 +127,7 @@ set_autofs_map(struct autofs_ctx *actx, int hret; if (map->mapname == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Missing netgroup name.\n")); + DEBUG(SSSDBG_CRIT_FAILURE, ("Missing autofs map name.\n")); return EINVAL; } @@ -161,7 +161,7 @@ autofs_map_hash_remove(TALLOC_CTX *ctx) key.type = HASH_KEY_STRING; key.str = map->mapname; - /* Remove the netgroup result object from the lookup table */ + /* Remove the autofs map result object from the lookup table */ hret = hash_delete(map->map_table, &key); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -219,7 +219,8 @@ sss_autofs_cmd_setautomntent(struct cli_ctx *client) req = setautomntent_send(cmdctx, rawname, cmdctx); if (!req) { - DEBUG(0, ("Fatal error calling setautomntent_send\n")); + DEBUG(SSSDBG_CRIT_FAILURE, + ("Fatal error calling setautomntent_send\n")); ret = EIO; goto done; } @@ -814,6 +815,8 @@ static errno_t getautomntent_process(struct autofs_cmd_ctx *cmdctx, struct autofs_map_ctx *map, uint32_t cursor); +static void +getautomntent_implicit_done(struct tevent_req *req); static int sss_autofs_cmd_getautomntent(struct cli_ctx *client) @@ -825,9 +828,8 @@ sss_autofs_cmd_getautomntent(struct cli_ctx *client) size_t blen; errno_t ret; uint32_t namelen; - char *name; - uint32_t cursor; size_t c = 0; + struct tevent_req *req; DEBUG(SSSDBG_TRACE_INTERNAL, ("sss_autofs_cmd_getautomntent\n")); @@ -853,30 +855,37 @@ sss_autofs_cmd_getautomntent(struct cli_ctx *client) goto done; } - name = (char *) body+c; + cmdctx->mapname = (char *) body+c; /* if not null-terminated fail */ - if (name[namelen] != '\0') { + if (cmdctx->mapname[namelen] != '\0') { ret = EINVAL; goto done; } /* If the name isn't valid UTF-8, fail */ - if (!sss_utf8_check((const uint8_t *) name, namelen -1)) { + if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) { ret = EINVAL; goto done; } - SAFEALIGN_COPY_UINT32_CHECK(&cursor, body+c+namelen+1, blen, &c); + SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->cursor, body+c+namelen+1, blen, &c); DEBUG(SSSDBG_TRACE_FUNC, - ("Requested data of map %s cursor %d\n", name, cursor)); + ("Requested data of map %s cursor %d\n", cmdctx->mapname, cmdctx->cursor)); - ret = get_autofs_map(actx, name, &map); + ret = get_autofs_map(actx, cmdctx->mapname, &map); if (ret == ENOENT) { - /* FIXME */ - DEBUG(SSSDBG_MINOR_FAILURE, - ("implicit setautomntent not yet implemented\n")); + DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n")); + req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n")); + ret = EIO; + goto done; + } + + tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx); + ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -886,10 +895,16 @@ sss_autofs_cmd_getautomntent(struct cli_ctx *client) } if (map->ready == false) { - /* FIXME */ - DEBUG(SSSDBG_MINOR_FAILURE, - ("implicit setautomntent not yet implemented\n")); - ret = ENOENT; + DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n")); + req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n")); + ret = EIO; + goto done; + } + + tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx); + ret = EOK; goto done; } else if (map->found == false) { DEBUG(SSSDBG_TRACE_FUNC, ("negative cache hit\n")); @@ -900,12 +915,52 @@ sss_autofs_cmd_getautomntent(struct cli_ctx *client) DEBUG(SSSDBG_TRACE_INTERNAL, ("returning entries for [%s]\n", map->mapname)); - ret = getautomntent_process(cmdctx, map, cursor); + ret = getautomntent_process(cmdctx, map, cmdctx->cursor); done: return autofs_cmd_done(cmdctx, ret); } +static void +getautomntent_implicit_done(struct tevent_req *req) +{ + errno_t ret; + struct autofs_map_ctx *map; + struct autofs_cmd_ctx *cmdctx = + tevent_req_callback_data(req, struct autofs_cmd_ctx); + struct autofs_ctx *actx = + talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx); + + ret = setautomntent_recv(req); + talloc_zfree(req); + if (ret != EOK) { + if (ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_recv failed\n")); + } else { + DEBUG(SSSDBG_MINOR_FAILURE, ("No such map\n")); + } + goto done; + } + + ret = get_autofs_map(actx, cmdctx->mapname, &map); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Cannot get map after setautomntent succeeded?\n")); + goto done; + } + + if (map->ready == false) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Map not ready after setautomntent succeeded\n")); + goto done; + } + + ret = getautomntent_process(cmdctx, map, cmdctx->cursor); +done: + autofs_cmd_done(cmdctx, ret); + return; +} + static errno_t getautomntent_process(struct autofs_cmd_ctx *cmdctx, struct autofs_map_ctx *map, @@ -989,9 +1044,11 @@ done: } static errno_t -getautomnbyname_process(struct autofs_cmd_ctx *cmdctx, - struct autofs_map_ctx *map, - const char *key); +getautomntbyname_process(struct autofs_cmd_ctx *cmdctx, + struct autofs_map_ctx *map, + const char *key); +static void +getautomntbyname_implicit_done(struct tevent_req *req); static int sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) @@ -1003,12 +1060,11 @@ sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) uint8_t *body; size_t blen; uint32_t namelen; - char *name; uint32_t keylen; - char *key; size_t c = 0; + struct tevent_req *req; - DEBUG(SSSDBG_TRACE_INTERNAL, ("sss_autofs_cmd_getautomnbyname\n")); + DEBUG(SSSDBG_TRACE_INTERNAL, ("sss_autofs_cmd_getautomntbyname\n")); cmdctx = talloc_zero(client, struct autofs_cmd_ctx); if (!cmdctx) { @@ -1033,16 +1089,16 @@ sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) goto done; } - name = (char *) body+c; + cmdctx->mapname = (char *) body+c; /* if not null-terminated fail */ - if (name[namelen] != '\0') { + if (cmdctx->mapname[namelen] != '\0') { ret = EINVAL; goto done; } /* If the name isn't valid UTF-8, fail */ - if (!sss_utf8_check((const uint8_t *) name, namelen -1)) { + if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) { ret = EINVAL; goto done; } @@ -1057,28 +1113,35 @@ sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) goto done; } - key = (char *) body+c; + cmdctx->key = (char *) body+c; /* if not null-terminated fail */ - if (key[keylen] != '\0') { + if (cmdctx->key[keylen] != '\0') { ret = EINVAL; goto done; } /* If the key isn't valid UTF-8, fail */ - if (!sss_utf8_check((const uint8_t *) key, keylen -1)) { + if (!sss_utf8_check((const uint8_t *) cmdctx->key, keylen -1)) { ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_FUNC, - ("Requested data of map %s key %s\n", name, key)); + ("Requested data of map %s key %s\n", cmdctx->mapname, cmdctx->key)); - ret = get_autofs_map(actx, name, &map); + ret = get_autofs_map(actx, cmdctx->mapname, &map); if (ret == ENOENT) { - /* FIXME */ - DEBUG(SSSDBG_MINOR_FAILURE, - ("implicit setautomntent not yet implemented\n")); + DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n")); + req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n")); + ret = EIO; + goto done; + } + + tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx); + ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -1088,10 +1151,16 @@ sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) } if (map->ready == false) { - /* FIXME */ - DEBUG(SSSDBG_MINOR_FAILURE, - ("implicit setautomntent not yet implemented\n")); - ret = ENOENT; + DEBUG(SSSDBG_TRACE_FUNC, ("Performing implicit setautomntent\n")); + req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_send failed\n")); + ret = EIO; + goto done; + } + + tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx); + ret = EOK; goto done; } else if (map->found == false) { DEBUG(SSSDBG_TRACE_FUNC, ("negative cache hit\n")); @@ -1100,18 +1169,58 @@ sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) } DEBUG(SSSDBG_TRACE_INTERNAL, - ("Looking up value for [%s] in [%s]\n", key, map->mapname)); + ("Looking up value for [%s] in [%s]\n", cmdctx->key, map->mapname)); - ret = getautomnbyname_process(cmdctx, map, key); + ret = getautomntbyname_process(cmdctx, map, cmdctx->key); done: return autofs_cmd_done(cmdctx, ret); } +static void +getautomntbyname_implicit_done(struct tevent_req *req) +{ + errno_t ret; + struct autofs_map_ctx *map; + struct autofs_cmd_ctx *cmdctx = + tevent_req_callback_data(req, struct autofs_cmd_ctx); + struct autofs_ctx *actx = + talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx); + + ret = setautomntent_recv(req); + talloc_zfree(req); + if (ret != EOK) { + if (ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, ("setautomntent_recv failed\n")); + } else { + DEBUG(SSSDBG_MINOR_FAILURE, ("No such map\n")); + } + goto done; + } + + ret = get_autofs_map(actx, cmdctx->mapname, &map); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Cannot get map after setautomntent succeeded?\n")); + goto done; + } + + if (map->ready == false) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Map not ready after setautomntent succeeded\n")); + goto done; + } + + ret = getautomntbyname_process(cmdctx, map, cmdctx->key); +done: + autofs_cmd_done(cmdctx, ret); + return; +} + static errno_t -getautomnbyname_process(struct autofs_cmd_ctx *cmdctx, - struct autofs_map_ctx *map, - const char *key) +getautomntbyname_process(struct autofs_cmd_ctx *cmdctx, + struct autofs_map_ctx *map, + const char *key) { struct cli_ctx *client = cmdctx->cctx; errno_t ret; -- 1.7.7.6