123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- * Copyright 2005 - 2016 Zarafa and its licensors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- #include "LDAPConfigCheck.h"
- LDAPConfigCheck::LDAPConfigCheck(const char *lpszConfigFile) : ECConfigCheck("LDAP Configuration file", lpszConfigFile)
- {
- }
- void LDAPConfigCheck::loadChecks()
- {
- // TODO: add check for ldap_host is resolvable IP address
- // TODO: add check for ldap_port on ldap_host is reachable
- addCheck("ldap_bind_user", CONFIG_MANDATORY);
- addCheck("ldap_last_modification_attribute", CONFIG_MANDATORY);
- addCheck("ldap_server_charset", 0, &testCharset);
- addCheck("ldap_search_base", CONFIG_MANDATORY);
- addCheck("ldap_object_type_attribute", CONFIG_MANDATORY);
- addCheck("ldap_user_type_attribute_value", CONFIG_MANDATORY);
- addCheck("ldap_group_type_attribute_value", CONFIG_MANDATORY);
- addCheck("ldap_company_type_attribute_value", CONFIG_MANDATORY | CONFIG_HOSTED_USED);
- addCheck("ldap_contact_type_attribute_value", 0);
- addCheck("ldap_addresslist_type_attribute_value", 0);
- addCheck("ldap_dynamicgroup_type_attribute_value", 0);
- addCheck("ldap_server_type_attribute_value", CONFIG_MULTI_USED);
- addCheck("ldap_user_search_filter", 0, &testLdapQuery);
- addCheck("ldap_group_search_filter", 0, &testLdapQuery);
- addCheck("ldap_company_search_filter", 0, &testLdapQuery);
- addCheck("ldap_user_unique_attribute", CONFIG_MANDATORY);
- addCheck("ldap_user_unique_attribute_type", 0, &testLdapType);
- addCheck("ldap_group_unique_attribute", CONFIG_MANDATORY);
- addCheck("ldap_group_unique_attribute_type", 0, &testLdapType);
- addCheck("ldap_groupmembers_attribute_type", 0, &testLdapType);
- addCheck("ldap_company_unique_attribute", CONFIG_HOSTED_USED | CONFIG_MANDATORY);
- addCheck("ldap_company_unique_attribute_type", CONFIG_HOSTED_USED, &testLdapType);
- addCheck("ldap_company_view_attribute_type", CONFIG_HOSTED_USED, &testLdapType);
- addCheck("ldap_company_admin_attribute_type", CONFIG_HOSTED_USED, &testLdapType);
- addCheck("ldap_company_system_admin_attribute_type", CONFIG_HOSTED_USED, &testLdapType);
- addCheck("ldap_quota_userwarning_recipients_attribute_type", 0, &testLdapType);
- addCheck("ldap_quota_companywarning_recipients_attribute_type", 0, &testLdapType);
- }
- int LDAPConfigCheck::testLdapScope(const config_check_t *check)
- {
- if (check->value1.empty() ||
- check->value1 == "base" ||
- check->value1 == "one" ||
- check->value1 == "sub")
- return CHECK_OK;
- printError(check->option1, "contains unknown scope \"" + check->value1 + "\"");
- return CHECK_ERROR;
- }
- int LDAPConfigCheck::testLdapType(const config_check_t *check)
- {
- if (check->value1.empty() ||
- check->value1 == "text" ||
- check->value1 == "binary" ||
- check->value1 == "dn" ||
- check->value1 == "attribute")
- return CHECK_OK;
- printError(check->option1, "contains unknown type \"" + check->value1 + "\"");
- return CHECK_ERROR;
- }
- int LDAPConfigCheck::testLdapQuery(const config_check_t *check)
- {
- std::string stack;
- bool contains_data; /* '(' was followed by attribute comparison */
- bool contains_check; /* '=' found */
- /* Empty queries are always correct */
- if (check->value1.empty())
- return CHECK_OK;
- /* If the query contains any of the following characters it is broken */
- if (check->value1.find_first_of("{}") != std::string::npos) {
- printError(check->option1, "contains invalid character: \"" + check->value1 + "\"");
- return CHECK_ERROR;
- }
- /* Queries _must_ always be enclosed by '(' and ')',
- * note that this check will pass '(a=1)(b=2)' as correct,
- * we will block this in the for loop.
- */
- if (*check->value1.begin() != '(' || *check->value1.rbegin() != ')')
- goto error_exit;
- /* Since we already checked the first character, we can add it to the stack */
- stack += check->value1[0];
- contains_data = false;
- contains_check = false;
- /* Loop through the string, the following queries must be marked broken:
- * (a=1)(a=2) => Must be enclosed by '(' and ')'
- * ((a=1) => Requires equal number '(' and ')'
- * (a=1)) => Requires equal number '(' and ')'
- * (a) => A check consists of attribute=value comparison
- * ((a=1)(a=2)) => Requires '|' or '&' to combine the 2 queries
- * (&a=1) => '|' and '&' should only be present in front of '('
- */
- for (auto i = check->value1.cbegin() + 1; i != check->value1.cend(); ++i) {
- if (stack.empty())
- goto error_exit;
- switch (*i) {
- case '(':
- if (contains_data)
- goto error_exit;
- if (*stack.rbegin() != '|' &&
- *stack.rbegin() != '&')
- goto error_exit;
- stack += *i;
- break;
- case ')':
- if (!contains_data || !contains_check)
- goto error_exit;
- stack.erase(stack.end() - 1);
- contains_data = false;
- contains_check = false;
- break;
- case '|':
- case '&':
- if (contains_data)
- goto error_exit;
- stack += *i;
- break;
- case '=':
- if (!contains_data)
- goto error_exit;
- contains_check = true;
- break;
- default:
- if (*stack.rbegin() == '|' ||
- *stack.rbegin() == '&')
- goto error_exit;
- contains_data = true;
- break;
- }
- }
- return CHECK_OK;
- error_exit:
- printError(check->option1, "contains malformatted string: \"" + check->value1 + "\"");
- return CHECK_ERROR;
- }
|