db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose/*
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose SSSD
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose Library for rule based certificate to user mapping - LDAP mapping rules
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose Authors:
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose Sumit Bose <sbose@redhat.com>
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose Copyright (C) 2017 Red Hat
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose This program is free software; you can redistribute it and/or modify
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose it under the terms of the GNU General Public License as published by
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose the Free Software Foundation; either version 3 of the License, or
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose (at your option) any later version.
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose This program is distributed in the hope that it will be useful,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose but WITHOUT ANY WARRANTY; without even the implied warranty of
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose GNU General Public License for more details.
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose You should have received a copy of the GNU General Public License
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose along with this program. If not, see <http://www.gnu.org/licenses/>.
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose*/
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik#include <errno.h>
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik#include <stdbool.h>
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik#include <string.h>
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik#include <talloc.h>
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik#include "util/dlinklist.h"
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose#include "lib/certmap/sss_certmap.h"
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose#include "lib/certmap/sss_certmap_int.h"
0fba03cab9580cab6898e855bcd0ca9b2e54ce67Lukas Slebodnik
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestruct template_table {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *name;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char **attr_name;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char **conversion;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose};
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Boseconst char *empty[] = {NULL};
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Boseconst char *name_attr[] = {"short_name", NULL};
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Boseconst char *x500_conv[] = {"ad_x500", "ad", "ad_ldap",
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose "nss_x500", "nss", "nss_ldap", NULL};
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Boseconst char *bin_conv[] = {"bin", "base64", NULL};
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestruct template_table template_table[] = {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"issuer_dn", empty, x500_conv},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_dn", empty, x500_conv},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"cert", empty, bin_conv},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_rfc822_name", name_attr, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_dns_name", name_attr, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_x400_address", empty, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_directory_name", empty, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_ediparty_name", empty, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_uri", empty, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_ip_address", empty, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_registered_id", empty, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_pkinit_principal", name_attr, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_nt_principal", name_attr, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {"subject_principal", name_attr, empty},
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose {NULL, NULL, NULL}};
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestatic int check_parsed_template(struct sss_certmap_ctx *ctx,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct parsed_template *parsed)
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose{
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose size_t n;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose size_t a;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose size_t c;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose bool attr_name_valid = false;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose bool conversion_valid = false;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose for (n = 0; template_table[n].name != NULL; n++) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (strcmp(template_table[n].name, parsed->name) != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose continue;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (parsed->attr_name != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose for (a = 0; template_table[n].attr_name[a] != NULL; a++) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (strcmp(template_table[n].attr_name[a],
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->attr_name) == 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose attr_name_valid = true;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose break;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose attr_name_valid = true;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (parsed->conversion != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose for (c = 0; template_table[n].conversion[c] != NULL; c++) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (strcmp(template_table[n].conversion[c],
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->conversion) == 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose conversion_valid = true;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose break;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose conversion_valid = true;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (attr_name_valid && conversion_valid) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose}
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestatic int parse_template(TALLOC_CTX *mem_ctx, struct sss_certmap_ctx *ctx,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *template,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct parsed_template **parsed_template)
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose{
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose int ret;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct parsed_template *parsed = NULL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *dot;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *excl;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *p;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed = talloc_zero(mem_ctx, struct parsed_template);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (parsed == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose dot = strchr(template, '.');
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (dot != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose p = strchr(dot + 1, '.');
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (p != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Only one '.' allowed in template.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (dot == template) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Missing name in template.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose excl = strchr(template, '!');
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (excl != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose p = strchr(excl + 1, '!');
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (p != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Only one '!' allowed in template.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (excl == template) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Missing name in template.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (excl != NULL && excl[1] != '\0') {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->conversion = talloc_strdup(parsed, excl + 1);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (parsed->conversion == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Memory allocation failed.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (dot != NULL && dot[1] != '\0' && dot[1] != '!') {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (excl == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->attr_name = talloc_strdup(parsed, dot + 1);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->attr_name = talloc_strndup(parsed, dot + 1,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose (excl - dot - 1));
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (parsed->attr_name == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Memory allocation failed.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (dot != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->name = talloc_strndup(parsed, template, (dot - template));
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else if (excl != NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->name = talloc_strndup(parsed, template, (excl - template));
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose parsed->name = talloc_strdup(parsed, template);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (parsed->name == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = check_parsed_template(ctx, parsed);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Parse template invalid.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosedone:
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret == 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose *parsed_template = parsed;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose talloc_free(parsed);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return ret;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose}
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestatic int add_comp(struct sss_certmap_ctx *ctx, struct ldap_mapping_rule *rule,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *string, enum comp_type type)
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose{
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose int ret;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct ldap_mapping_rule_comp *comp;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose comp = talloc_zero(rule, struct ldap_mapping_rule_comp);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (comp == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose comp->type = type;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose comp->val = talloc_strdup(comp, string);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (comp->val == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose talloc_free(comp);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (type == comp_template) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = parse_template(comp, ctx, string, &comp->parsed_template);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose talloc_free(comp);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return ret;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose DLIST_ADD_END(rule->list, comp, struct ldap_mapping_rule_comp *);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose}
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestatic int add_string(struct sss_certmap_ctx *ctx,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct ldap_mapping_rule *rule, const char *string)
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose{
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return add_comp(ctx, rule, string, comp_string);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose}
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosestatic int add_template(struct sss_certmap_ctx *ctx,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct ldap_mapping_rule *rule, const char *string)
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose{
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return add_comp(ctx, rule, string, comp_template);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose}
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Boseint parse_ldap_mapping_rule(struct sss_certmap_ctx *ctx,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *rule_start,
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct ldap_mapping_rule **mapping_rule)
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose{
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose size_t c;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose const char *cur;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose char *tmp_string = NULL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose size_t tmp_string_size;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose struct ldap_mapping_rule *rule = NULL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose int ret;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose bool in_template = false;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose rule = talloc_zero(ctx, struct ldap_mapping_rule);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (rule == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose tmp_string_size = strlen(rule_start) + 1;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose tmp_string = talloc_zero_size(ctx, tmp_string_size);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (tmp_string == NULL) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = ENOMEM;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose cur = rule_start;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose c = 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose while (*cur != '\0') {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (c > tmp_string_size) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Cannot parse mapping rule.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EIO;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose switch (*cur) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose case '{':
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (in_template) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "'{' not allowed in templates.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (cur[1] == '{') {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose /* Add only a single '{' to the output */
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose tmp_string[c] = '{';
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose c++;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose cur += 2;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (c != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = add_string(ctx, rule, tmp_string);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Failed to add string.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose memset(tmp_string, 0, tmp_string_size);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose c = 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose cur++;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose in_template = true;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose break;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose case '}':
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (cur[1] == '}') {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (in_template) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "'}}' not allowed in templates.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose /* Add only a single '}' to the output */
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose tmp_string[c] = '}';
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose c++;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose cur += 2;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = add_template(ctx, rule, tmp_string);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Failed to add template.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose memset(tmp_string, 0, tmp_string_size);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose c = 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose cur++;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose in_template = false;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose break;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose default:
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose tmp_string[c] = *cur;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose c++;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose cur++;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (in_template) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Rule ended inside template.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (c != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = add_string(ctx, rule, tmp_string);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret != 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose CM_DEBUG(ctx, "Failed to add string.");
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = EINVAL;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose goto done;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose ret = 0;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bosedone:
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose if (ret == 0) {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose *mapping_rule = rule;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose } else {
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose talloc_free(rule);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose }
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose talloc_free(tmp_string);
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose return ret;
db36dca3d45e6eefbb30042ee65876566f1a6014Sumit Bose}