4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/*
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Authors:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Pavel Březina <pbrezina@redhat.com>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Copyright (C) 2016 Red Hat
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina This program is free software; you can redistribute it and/or modify
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina it under the terms of the GNU General Public License as published by
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina the Free Software Foundation; either version 3 of the License, or
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina (at your option) any later version.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina This program is distributed in the hope that it will be useful,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina GNU General Public License for more details.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina You should have received a copy of the GNU General Public License
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina*/
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "util/util.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "util/cert.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "lib/idmap/sss_idmap.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "responder/nss/nss_protocol.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_done(struct cli_ctx *cli_ctx, errno_t error)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina switch (error) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina case EOK:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Create empty packet if none was provided. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (pctx->creq->out == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_packet_new(pctx->creq, 0,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_cmd(pctx->creq->in),
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina &pctx->creq->out);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_set_error(pctx->creq->out, EOK);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Sending reply: success\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina case ENOENT:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Sending reply: not found\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_cmd_send_empty(cli_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina default:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Sending reply: error [%d]: %s\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina error, sss_strerror(error));
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_cmd_send_error(cli_ctx, error);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinadone:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send reply [%d]: %s!\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret, sss_strerror(ret));
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_cmd_done(cli_ctx, NULL);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinavoid nss_protocol_reply(struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_ctx *nss_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_cmd_ctx *cmd_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cache_req_result *result,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_protocol_fill_packet_fn fill_fn)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_packet_new(pctx->creq, 0, sss_packet_get_cmd(pctx->creq->in),
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina &pctx->creq->out);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = fill_fn(nss_ctx, cmd_ctx, pctx->creq->out, result);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_set_error(pctx->creq->out, EOK);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinadone:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_protocol_done(cli_ctx, ret);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *rawname;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t blen;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_body(pctx->creq->in, &body, &blen);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If not terminated fail. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (body[blen - 1] != '\0') {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If the body isn't valid UTF-8, fail */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (!sss_utf8_check(body, blen - 1)) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Body is not UTF-8 string!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina rawname = (const char *)body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (rawname[0] == '\0') {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "An empty name was provided!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_rawname = rawname;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Boseerrno_t
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bosenss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname,
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint32_t *_flags)
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose{
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose struct cli_protocol *pctx;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose const char *rawname;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint8_t *body;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose size_t blen;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint8_t *p;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint32_t flags;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose sss_packet_get_body(pctx->creq->in, &body, &blen);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose if (blen < 1 + sizeof(uint32_t)) {
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Body too short!\n");
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EINVAL;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose /* If first argument not terminated fail. */
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose if (body[blen - 1 - sizeof(uint32_t)] != '\0') {
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n");
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EINVAL;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose p = memchr(body, '\0', blen);
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio /* Although body for sure is null terminated, let's add this check here
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio * so static analyzers are happier. */
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio if (p == NULL) {
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio DEBUG(SSSDBG_CRIT_FAILURE,
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio "memchr() returned NULL, body is not null terminated!\n");
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio return EINVAL;
1d88a0591ce8445ea3b6a88845a5997d61c915b4Fabiano Fidêncio }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose /* If the body isn't valid UTF-8, fail */
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose if (!sss_utf8_check(body, (p - body))) {
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "First argument is not UTF-8 string!\n");
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EINVAL;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose rawname = (const char *)body;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose if (rawname[0] == '\0') {
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "An empty name was provided!\n");
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EINVAL;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose p++;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose if ((p - body) + sizeof(uint32_t) != blen) {
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Body has unexpected size!\n");
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EINVAL;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose SAFEALIGN_COPY_UINT32(&flags, p, NULL);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose p += sizeof(uint32_t);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose *_rawname = rawname;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose *_flags = flags;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EOK;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose}
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t blen;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint32_t id;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_body(pctx->creq->in, &body, &blen);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (blen != sizeof(uint32_t)) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina SAFEALIGN_COPY_UINT32(&id, body, NULL);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_id = id;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Boseerrno_t
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bosenss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id,
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint32_t *_flags)
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose{
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose struct cli_protocol *pctx;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint8_t *body;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose size_t blen;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint32_t id;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose uint32_t flags;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose sss_packet_get_body(pctx->creq->in, &body, &blen);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose if (blen != 2 * sizeof(uint32_t)) {
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EINVAL;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose }
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose SAFEALIGN_COPY_UINT32(&id, body, NULL);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose SAFEALIGN_COPY_UINT32(&flags, body + sizeof(uint32_t), NULL);
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose *_id = id;
55f7d8034d783c01789d76a2b9ffc901045e8af8Sumit Bose *_flags = flags;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose return EOK;
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose}
cf93f7c2f2031078bbbff095dae01eb4f8deff85Sumit Bose
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_protocol_parse_id(cli_ctx, _limit);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_svc_name(struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char **_name,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char **_protocol)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *protocol;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *name;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t protocol_len;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t name_len;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t blen;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina int i;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_body(pctx->creq->in, &body, &blen);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If not terminated fail. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (body[blen - 1] != '\0') {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Calculate service name length. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina for (i = 0, name_len = 0; body[i] != '\0'; i++) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina name_len++;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Calculate protocol name length, use index from previous cycle. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina for (protocol_len = 0; body[i + 1] != '\0'; i++) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina protocol_len++;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (name_len == 0) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina name = (const char *)body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina protocol = protocol_len == 0 ? NULL : (const char *)(body + name_len + 1);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (!sss_utf8_check((const uint8_t *)name, name_len)) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Name is not UTF-8 string\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (!sss_utf8_check((const uint8_t *)protocol, protocol_len)) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Protocol is not UTF-8 string\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_name = name;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_protocol = protocol;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_svc_port(struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint16_t *_port,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char **_protocol)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *protocol;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t protocol_len;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint16_t port;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t blen;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina int i;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_body(pctx->creq->in, &body, &blen);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If not terminated fail. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (body[blen - 1] != '\0') {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina SAFEALIGN_COPY_UINT16(&port, body, NULL);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina port = ntohs(port);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Move behind the port and padding to get the protocol. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina body = body + 2 * sizeof(uint16_t) + sizeof(uint32_t);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Calculate protocol name length. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina for (protocol_len = 0, i = 0; body[i] != '\0'; i++) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina protocol_len++;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina protocol = protocol_len == 0 ? NULL : (const char *)body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (!sss_utf8_check((const uint8_t *)protocol, protocol_len)) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Protocol is not UTF-8 string\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_port = port;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_protocol = protocol;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_cert(struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char **_derb64)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *derb64;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t pem_size;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina char *pem_cert;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t blen;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_body(pctx->creq->in, &body, &blen);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If not terminated fail. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (body[blen - 1] != '\0') {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina derb64 = (const char *)body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Input certificate [%s]\n", derb64);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Check input. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_cert_derb64_to_pem(cli_ctx, derb64, &pem_cert, &pem_size);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Unable to convert certificate to pem [%d]: %s\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret, sss_strerror(ret));
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_free(pem_cert);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_derb64 = derb64;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_protocol_parse_sid(struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char **_sid)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_protocol *pctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_ctx *nss_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *sid;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *bin_sid;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t bin_len;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint8_t *body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina size_t blen;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum idmap_error_code err;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_packet_get_body(pctx->creq->in, &body, &blen);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If not terminated fail. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (body[blen - 1] != '\0') {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sid = (const char *)body;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* If the body isn't a SID, fail */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina err = sss_idmap_sid_to_bin_sid(nss_ctx->idmap_ctx, sid, &bin_sid,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina &bin_len);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (err != IDMAP_SUCCESS) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Unable to convert SID to binary [%s].\n", sid);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EINVAL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina sss_idmap_free_bin_sid(nss_ctx->idmap_ctx, bin_sid);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "Input SID [%s]\n", sid);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *_sid = sid;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}