+ int lineno );
+
+static int
+read_baseObject(
+ BackendDB *be,
+ const char *fname );
+
+static ConfigDriver sql_cf_gen;
+
+enum {
+ BSQL_CONCAT_PATT = 1,
+ BSQL_CREATE_NEEDS_SEL,
+ BSQL_UPPER_NEEDS_CAST,
+ BSQL_HAS_LDAPINFO_DN_RU,
+ BSQL_FAIL_IF_NO_MAPPING,
+ BSQL_ALLOW_ORPHANS,
+ BSQL_BASE_OBJECT,
+ BSQL_LAYER,
+ BSQL_SUBTREE_SHORTCUT,
+ BSQL_FETCH_ALL_ATTRS,
+ BSQL_FETCH_ATTRS,
+ BSQL_CHECK_SCHEMA,
+ BSQL_ALIASING_KEYWORD,
+ BSQL_AUTOCOMMIT
+};
+
+static ConfigTable sqlcfg[] = {
+ { "dbhost", "hostname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_dbhost),
+ "( OLcfgDbAt:6.1 NAME 'olcDbHost' "
+ "DESC 'Hostname of SQL server' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "dbname", "name", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_dbname),
+ "( OLcfgDbAt:6.2 NAME 'olcDbName' "
+ "DESC 'Name of SQL database' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "dbuser", "username", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_dbuser),
+ "( OLcfgDbAt:6.3 NAME 'olcDbUser' "
+ "DESC 'Username for SQL session' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "dbpasswd", "password", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_dbpasswd),
+ "( OLcfgDbAt:6.4 NAME 'olcDbPass' "
+ "DESC 'Password for SQL session' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "concat_pattern", "pattern", 2, 2, 0,
+ ARG_STRING|ARG_MAGIC|BSQL_CONCAT_PATT, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.20 NAME 'olcSqlConcatPattern' "
+ "DESC 'Pattern used to concatenate strings' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "subtree_cond", "SQL expression", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_subtree_cond),
+ "( OLcfgDbAt:6.21 NAME 'olcSqlSubtreeCond' "
+ "DESC 'Where-clause template for a subtree search condition' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "children_cond", "SQL expression", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_children_cond),
+ "( OLcfgDbAt:6.22 NAME 'olcSqlChildrenCond' "
+ "DESC 'Where-clause template for a children search condition' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "dn_match_cond", "SQL expression", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_dn_match_cond),
+ "( OLcfgDbAt:6.23 NAME 'olcSqlDnMatchCond' "
+ "DESC 'Where-clause template for a DN match search condition' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "oc_query", "SQL expression", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_oc_query),
+ "( OLcfgDbAt:6.24 NAME 'olcSqlOcQuery' "
+ "DESC 'Query used to collect objectClass mapping data' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "at_query", "SQL expression", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_at_query),
+ "( OLcfgDbAt:6.25 NAME 'olcSqlAtQuery' "
+ "DESC 'Query used to collect attributeType mapping data' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "insentry_stmt", "SQL expression", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_insentry_stmt),
+ "( OLcfgDbAt:6.26 NAME 'olcSqlInsEntryStmt' "
+ "DESC 'Statement used to insert a new entry' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "create_needs_select", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_CREATE_NEEDS_SEL, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.27 NAME 'olcSqlCreateNeedsSelect' "
+ "DESC 'Whether entry creation needs a subsequent select' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "upper_func", "SQL function name", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_upper_func),
+ "( OLcfgDbAt:6.28 NAME 'olcSqlUpperFunc' "
+ "DESC 'Function that converts a value to uppercase' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "upper_needs_cast", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_UPPER_NEEDS_CAST, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.29 NAME 'olcSqlUpperNeedsCast' "
+ "DESC 'Whether olcSqlUpperFunc needs an explicit cast' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "strcast_func", "SQL function name", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_strcast_func),
+ "( OLcfgDbAt:6.30 NAME 'olcSqlStrcastFunc' "
+ "DESC 'Function that converts a value to a string' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "delentry_stmt", "SQL expression", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_delentry_stmt),
+ "( OLcfgDbAt:6.31 NAME 'olcSqlDelEntryStmt' "
+ "DESC 'Statement used to delete an existing entry' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "renentry_stmt", "SQL expression", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_renentry_stmt),
+ "( OLcfgDbAt:6.32 NAME 'olcSqlRenEntryStmt' "
+ "DESC 'Statement used to rename an entry' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "delobjclasses_stmt", "SQL expression", 2, 2, 0, ARG_STRING|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_delobjclasses_stmt),
+ "( OLcfgDbAt:6.33 NAME 'olcSqlDelObjclassesStmt' "
+ "DESC 'Statement used to delete the ID of an entry' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "has_ldapinfo_dn_ru", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_HAS_LDAPINFO_DN_RU, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.34 NAME 'olcSqlHasLDAPinfoDnRu' "
+ "DESC 'Whether the dn_ru column is present' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "fail_if_no_mapping", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_FAIL_IF_NO_MAPPING, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.35 NAME 'olcSqlFailIfNoMapping' "
+ "DESC 'Whether to fail on unknown attribute mappings' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "allow_orphans", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_ALLOW_ORPHANS, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.36 NAME 'olcSqlAllowOrphans' "
+ "DESC 'Whether to allow adding entries with no parent' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "baseobject", "[file]", 1, 2, 0,
+ ARG_STRING|ARG_MAGIC|BSQL_BASE_OBJECT, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.37 NAME 'olcSqlBaseObject' "
+ "DESC 'Manage an in-memory baseObject entry' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "sqllayer", "name", 2, 0, 0,
+ ARG_MAGIC|BSQL_LAYER, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.38 NAME 'olcSqlLayer' "
+ "DESC 'Helper used to map DNs between LDAP and SQL' "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
+ { "use_subtree_shortcut", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_SUBTREE_SHORTCUT, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.39 NAME 'olcSqlUseSubtreeShortcut' "
+ "DESC 'Collect all entries when searchBase is DB suffix' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "fetch_all_attrs", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_FETCH_ALL_ATTRS, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.40 NAME 'olcSqlFetchAllAttrs' "
+ "DESC 'Require all attributes to always be loaded' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "fetch_attrs", "attrlist", 2, 0, 0,
+ ARG_MAGIC|BSQL_FETCH_ATTRS, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.41 NAME 'olcSqlFetchAttrs' "
+ "DESC 'Set of attributes to always fetch' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "check_schema", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|BSQL_CHECK_SCHEMA, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.42 NAME 'olcSqlCheckSchema' "
+ "DESC 'Check schema after modifications' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { "aliasing_keyword", "string", 2, 2, 0,
+ ARG_STRING|ARG_MAGIC|BSQL_ALIASING_KEYWORD, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.43 NAME 'olcSqlAliasingKeyword' "
+ "DESC 'The aliasing keyword' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "aliasing_quote", "string", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct backsql_info, sql_aliasing_quote),
+ "( OLcfgDbAt:6.44 NAME 'olcSqlAliasingQuote' "
+ "DESC 'Quoting char of the aliasing keyword' "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "autocommit", "yes|no", 2, 2, 0,
+ ARG_ON_OFF|ARG_MAGIC|SQL_AUTOCOMMIT, (void *)sql_cf_gen,
+ "( OLcfgDbAt:6.45 NAME 'olcSqlAutocommit' "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
+ { NULL, NULL, 0, 0, 0, ARG_IGNORED,
+ NULL, NULL, NULL, NULL }
+};
+
+static ConfigOCs sqlocs[] = {
+ {
+ "( OLcfgDbOc:6.1 "
+ "NAME 'olcSqlConfig' "
+ "DESC 'SQL backend configuration' "
+ "SUP olcDatabaseConfig "
+ "MUST olcDbName "
+ "MAY ( olcDbHost $ olcDbUser $ olcDbPass $ olcSqlConcatPattern $ "
+ "olcSqlSubtreeCond $ olcsqlChildrenCond $ olcSqlDnMatchCond $ "
+ "olcSqlOcQuery $ olcSqlAtQuery $ olcSqlInsEntryStmt $ "
+ "olcSqlCreateNeedsSelect $ olcSqlUpperFunc $ olcSqlUpperNeedsCast $ "
+ "olcSqlStrCastFunc $ olcSqlDelEntryStmt $ olcSqlRenEntryStmt $ "
+ "olcSqlDelObjClassesStmt $ olcSqlHasLDAPInfoDnRu $ "
+ "olcSqlFailIfNoMapping $ olcSqlAllowOrphans $ olcSqlBaseObject $ "
+ "olcSqlLayer $ olcSqlUseSubtreeShortcut $ olcSqlFetchAllAttrs $ "
+ "olcSqlFetchAttrs $ olcSqlCheckSchema $ olcSqlAliasingKeyword $ "
+ "olcSqlAliasingQuote $ olcSqlAutocommit ) )",
+ Cft_Database, sqlcfg },
+ { NULL, Cft_Abstract, NULL }
+};
+
+static int
+sql_cf_gen( ConfigArgs *c )