From 07698463b92e36fa3dd351199dc3b20d63b4436f Mon Sep 17 00:00:00 2001 From: William Brown Date: Tue, 14 Nov 2017 16:38:17 +1000 Subject: [PATCH 1/9] Ticket 49218 - Certmap - Header file changes Bug Description: This adds support for pluggable certificate mapping libraries. To achieve this, this replaces the existing baked in certificate mapping code. Fix Description: This adds the header files required for the new v4 api, as well as re-locating some key log function defs for shared access. Important to note is the change of the log typse to an enum from a #define, and is the way we should always provide int defines due to compilers ability to check this for us. https://pagure.io/389-ds-base/issue/49218 https://pagure.io/lib389/issue/95 https://pagure.io/lib389/issue/84 Author: wibrown Review by: ??? --- ldap/servers/plugins/rever/rever.h | 5 + ldap/servers/slapd/pblock_v3.h | 1 + ldap/servers/slapd/proto-slap.h | 6 +- ldap/servers/slapd/slapi-internal-v4.h | 127 +++++++++++++++++++++ ldap/servers/slapd/slapi-plugin-v4.h | 74 ++++++++++++ ldap/servers/slapd/slapi-plugin.h | 48 +------- ldap/servers/slapd/slapi-private-v4.h | 198 +++++++++++++++++++++++++++++++++ ldap/servers/slapd/slapi_pal.h | 6 + 8 files changed, 417 insertions(+), 48 deletions(-) create mode 100644 ldap/servers/slapd/slapi-internal-v4.h create mode 100644 ldap/servers/slapd/slapi-plugin-v4.h create mode 100644 ldap/servers/slapd/slapi-private-v4.h diff --git a/ldap/servers/plugins/rever/rever.h b/ldap/servers/plugins/rever/rever.h index 5c7484a..09b45f5 100644 --- a/ldap/servers/plugins/rever/rever.h +++ b/ldap/servers/plugins/rever/rever.h @@ -20,6 +20,11 @@ #include "slap.h" #include +/* We pull in the internal headers for config */ + +#define SLAPI_PRIVATE_V4_ACKNOWLEDGE +#include + #define AES_MECH 1 #define DES_MECH 2 #define AES_REVER_SCHEME_NAME "AES" diff --git a/ldap/servers/slapd/pblock_v3.h b/ldap/servers/slapd/pblock_v3.h index 7ec2f37..654f8d3 100644 --- a/ldap/servers/slapd/pblock_v3.h +++ b/ldap/servers/slapd/pblock_v3.h @@ -134,6 +134,7 @@ typedef struct _slapi_pblock_intop /* pointer to array of results returned on search */ Slapi_Entry **pb_plugin_internal_search_op_entries; + uint64_t pb_plugin_internal_search_num_entries; char **pb_plugin_internal_search_op_referrals; LDAPControl **pb_search_ctrls; /* for search operations, allows plugins to provide controls to pass for each entry or referral returned */ diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 4a30def..b24c9e7 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -335,7 +335,7 @@ int config_set_maxbersize(const char *attrname, char *value, char *errorbuf, int int config_set_maxsasliosize(const char *attrname, char *value, char *errorbuf, int apply); int config_set_versionstring(const char *attrname, char *versionstring, char *errorbuf, int apply); int config_set_enquote_sup_oc(const char *attrname, char *value, char *errorbuf, int apply); -int config_set_basedn(const char *attrname, char *value, char *errorbuf, int apply); +int config_set_certmap_basedn(const char *attrname, char *value, char *errorbuf, int apply); int config_set_configdir(const char *attrname, char *value, char *errorbuf, int apply); int config_set_instancedir(const char *attrname, char *value, char *errorbuf, int apply); int config_set_schemadir(const char *attrname, char *value, char *errorbuf, int apply); @@ -493,8 +493,7 @@ size_t config_get_maxsasliosize(void); char *config_get_versionstring(void); char *config_get_buildnum(void); int config_get_enquote_sup_oc(void); -char *config_get_basedn(void); -char *config_get_configdir(void); +char *config_get_certmap_basedn(void); char *config_get_schemadir(void); char *config_get_lockdir(void); char *config_get_tmpdir(void); @@ -589,6 +588,7 @@ int modify_config_dse(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int postop_modify_config_dse(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg); int add_root_dse(Slapi_PBlock *pb); int load_plugin_entry(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg); +int load_plugin_v4_entry(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg); /* diff --git a/ldap/servers/slapd/slapi-internal-v4.h b/ldap/servers/slapd/slapi-internal-v4.h new file mode 100644 index 0000000..df478b7 --- /dev/null +++ b/ldap/servers/slapd/slapi-internal-v4.h @@ -0,0 +1,127 @@ +/* BEGIN COPYRIGHT BLOCK + * Copyright (C) 2017 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK */ + +#pragma once + +#include + +#define SLAPI_PLUGIN_V4_PRERELEASE_ACKNOWLEDGE +#define SLAPI_PRIVATE_V4_ACKNOWLEDGE + +#include + +/** + * Internal implementation details of the slapi-plugin v4 call system + * + * This is how the server INTERNALLY manages plugins. Unless you are working + * inside of ns-slapd, libslapd, you will *never* need to include this file. + */ + +typedef enum _plugin_v4_result { + PLUGIN_V4_SUCCESS, + PLUGIN_V4_INVALID_CONFIG, + PLUGIN_V4_NULL_POINTER, + PLUGIN_V4_DUPLICATE, + PLUGIN_V4_RESOURCE, + PLUGIN_V4_INVALID_PLUGIN, + PLUGIN_V4_UNKNOWN, + PLUGIN_V4_INVALID_STATE, +} plugin_v4_result; + +/* + * I think we need a result -> str table. + */ + +plugin_v4_result plugin_v4_init(); +plugin_v4_result plugin_v4_shutdown(); +void plugin_v4_destroy(); + +plugin_v4_result plugin_v4_validate(struct slapi_entry *plugin_entry); + +/** + * This is called with an entry to setup a plugin + */ +plugin_v4_result plugin_v4_startall(); +plugin_v4_result plugin_v4_stopall(); + +plugin_v4_result plugin_v4_modify(struct slapi_entry *plugin_entry); +plugin_v4_result plugin_v4_add(struct slapi_entry *plugin_entry); +plugin_v4_result plugin_v4_setup(struct slapi_entry *plugin_entry); +plugin_v4_result plugin_v4_delete(struct slapi_entry *plugin_entry); + +typedef struct _slapi_v4_plugin_registration { + /* + * The name of the plugin. We will enforce this matches + * the cn. + */ + char *sv4_name; + /* + * Plugin order of operation precedence. + */ + uint64_t precedence; + /* + * This function is called *before* the plugin starts + * and guarantees no operations will start until + * this function is completed. It's guaranteed that + * close will not run until start is complete. + */ + slapi_v4_plugin_result *(*sv4_start_fn)(void **ctx); + /* + * This function is called *after* the plugin has stopped + * processing any operations. This allows you to free and + * stop and resources from your operation. It's guaranteed + * that no other plugin fn will run at the same time as this. + */ + slapi_v4_plugin_result *(*sv4_close_fn)(void **ctx); + /* + * Map certificate details to an entry for bind. + */ + slapi_v4_plugin_result *(*sv4_bind_certmap_fn)(void *ctx, slapi_v4_certmap_pblock *pbc); + +} slapi_v4_plugin_registration; + +slapi_v4_plugin_registration * slapi_v4_plugin_registration_create(); +void slapi_v4_plugin_registration_destroy(slapi_v4_plugin_registration *pr); + +/* + * Internal result handling from operations. + */ +int64_t slapi_v4_plugin_result_is_ok(slapi_v4_plugin_result *result); + +/* + * PLUGIN CALLBACK HOOKS + * + * These are the functions that we call to trigger plugin operations. + */ +plugin_v4_result plugin_v4_start_operation(); +plugin_v4_result plugin_v4_close_operation(); +plugin_v4_result plugin_v4_call_bind_certmap(); + +/* + * Internal pblock operations + */ + +slapi_v4_search_pblock * slapi_v4_search_pblock_extract(Slapi_PBlock *pb); +slapi_v4_search_pblock * slapi_v4_search_pblock_create(); +/* Merge the results of B into A */ +void slapi_v4_search_pblock_merge(slapi_v4_search_pblock *pbs_a, slapi_v4_search_pblock *pbs_b); + +/* from plugin-internal-op */ +int search_internal_pb(Slapi_PBlock *pb); + + +/* + * SERVER UPGRADE INTERNALS + */ +typedef enum _upgrade_status { + UPGRADE_SUCCESS = 0, + UPGRADE_FAILURE = 1, +} upgrade_status; + +upgrade_status upgrade_server(void); + diff --git a/ldap/servers/slapd/slapi-plugin-v4.h b/ldap/servers/slapd/slapi-plugin-v4.h new file mode 100644 index 0000000..2dd615b --- /dev/null +++ b/ldap/servers/slapd/slapi-plugin-v4.h @@ -0,0 +1,74 @@ +/* BEGIN COPYRIGHT BLOCK + * Copyright (C) 2017 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK */ + +#pragma once + +#ifndef SLAPI_PLUGIN_V4_PRERELEASE_ACKNOWLEDGE +#error slapi plugin v4 is *not* stabilised for release. DO NOT USE IT. +#endif + +#include + +#include +#include + +/* Provides va_list */ +#include + + +/* + * Logging + */ + +/* allowed values for the "severity" parameter */ +/* THESE MUST MATCH SLAPI-PLUGIN.h */ +typedef enum _slapi_log_level { + SLAPI_LOG_FATAL = 0, + SLAPI_LOG_TRACE = 1, + SLAPI_LOG_PACKETS = 2, + SLAPI_LOG_ARGS = 3, + SLAPI_LOG_CONNS = 4, + SLAPI_LOG_BER = 5, + SLAPI_LOG_FILTER = 6, + SLAPI_LOG_CONFIG = 7, + SLAPI_LOG_ACL = 8, + SLAPI_LOG_SHELL = 9, + SLAPI_LOG_PARSE = 10, + SLAPI_LOG_HOUSE = 11, + SLAPI_LOG_REPL = 12, + SLAPI_LOG_CACHE = 13, + SLAPI_LOG_PLUGIN = 14, + SLAPI_LOG_TIMING = 15, + SLAPI_LOG_BACKLDBM = 16, + SLAPI_LOG_ACLSUMMARY = 17, + SLAPI_LOG_NUNCSTANS = 18, + SLAPI_LOG_EMERG = 19, + SLAPI_LOG_ALERT = 20, + SLAPI_LOG_CRIT = 21, + SLAPI_LOG_ERR = 22, + SLAPI_LOG_WARNING = 23, + SLAPI_LOG_NOTICE = 24, + SLAPI_LOG_INFO = 25, + SLAPI_LOG_DEBUG = 26, +} slapi_log_level; + +/* The last level must be set in log.c: SLAPI_LOG_MAX */ + +int32_t slapi_log_error(slapi_log_level loglevel, char *subsystem, char *fmt, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 3, 4))); +#else + ; +#endif + +int32_t slapi_log_error_ext(slapi_log_level loglevel, char *subsystem, char *fmt, va_list varg1, va_list varg2); + + +int32_t slapi_is_loglevel_set(const slapi_log_level loglevel); + + diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index 4566202..1498cbd 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -27,6 +27,9 @@ extern "C" { #endif +#define SLAPI_PLUGIN_V4_PRERELEASE_ACKNOWLEDGE +#include + /* Provides our int types and platform specific requirements. */ #include "slapi_pal.h" @@ -6061,51 +6064,6 @@ int slapi_register_plugin(const char *plugintype, int enabled, const char *inits int slapi_register_plugin_ext(const char *plugintype, int enabled, const char *initsymbol, slapi_plugin_init_fnptr initfunc, const char *name, char **argv, void *group_identity, int precedence); /* - * logging - */ -int slapi_log_error(int loglevel, char *subsystem, char *fmt, ...) -#ifdef __GNUC__ - __attribute__((format(printf, 3, 4))); -#else - ; -#endif - -int slapi_log_error_ext(int loglevel, char *subsystem, char *fmt, va_list varg1, va_list varg2); - -/* allowed values for the "severity" parameter */ -#define SLAPI_LOG_FATAL 0 -#define SLAPI_LOG_TRACE 1 -#define SLAPI_LOG_PACKETS 2 -#define SLAPI_LOG_ARGS 3 -#define SLAPI_LOG_CONNS 4 -#define SLAPI_LOG_BER 5 -#define SLAPI_LOG_FILTER 6 -#define SLAPI_LOG_CONFIG 7 -#define SLAPI_LOG_ACL 8 -#define SLAPI_LOG_SHELL 9 -#define SLAPI_LOG_PARSE 10 -#define SLAPI_LOG_HOUSE 11 -#define SLAPI_LOG_REPL 12 -#define SLAPI_LOG_CACHE 13 -#define SLAPI_LOG_PLUGIN 14 -#define SLAPI_LOG_TIMING 15 -#define SLAPI_LOG_BACKLDBM 16 -#define SLAPI_LOG_ACLSUMMARY 17 -#define SLAPI_LOG_NUNCSTANS 18 -/* Severity levels */ -#define SLAPI_LOG_EMERG 19 -#define SLAPI_LOG_ALERT 20 -#define SLAPI_LOG_CRIT 21 -#define SLAPI_LOG_ERR 22 -#define SLAPI_LOG_WARNING 23 -#define SLAPI_LOG_NOTICE 24 -#define SLAPI_LOG_INFO 25 -#define SLAPI_LOG_DEBUG 26 /* The last level must be set in log.c: SLAPI_LOG_MAX */ - -int slapi_is_loglevel_set(const int loglevel); - - -/* * locks and synchronization */ typedef struct slapi_mutex Slapi_Mutex; diff --git a/ldap/servers/slapd/slapi-private-v4.h b/ldap/servers/slapd/slapi-private-v4.h new file mode 100644 index 0000000..d50d81a --- /dev/null +++ b/ldap/servers/slapd/slapi-private-v4.h @@ -0,0 +1,198 @@ +/* BEGIN COPYRIGHT BLOCK + * Copyright (C) 2017 Red Hat, Inc. + * All rights reserved. + * + * License: GPL (version 3 or any later version). + * See LICENSE for details. + * END COPYRIGHT BLOCK */ + +#pragma once + +#ifndef SLAPI_PRIVATE_V4_ACKNOWLEDGE +#error slapi private v4 is *not* a guaranteed api. It may change between minor releases. +#endif + +/* + * If you're using the internal private header, you know + * what you're getting into. + */ +#define SLAPI_PLUGIN_V4_PRERELEASE_ACKNOWLEDGE +#include + +/* Could be SLAPI_V4_PLUGIN_RESULT_CODE? */ +/* We *must* define these values for FFI */ +typedef enum { + SLAPI_V4_PLUGIN_SUCCESS = 0, + SLAPI_V4_PLUGIN_FAILURE = 1 +} SV4_PLUGIN_RESULT_CODE; + +typedef struct _slapi_v4_plugin_result { + SV4_PLUGIN_RESULT_CODE result; + /* Should we have an LDAP response code here? */ + /* Will allow sending back responses easily. */ + int ldap_code; + char *msg; +} slapi_v4_plugin_result; + +/* + * Low level berval manipulation + */ + +void slapi_v4_bv_free(struct berval *v); + +struct berval **slapi_v4_bvarray_create(); +void slapi_v4_bvarray_destroy(struct berval **array); +struct berval **slapi_v4_bvarray_append(struct berval **array, struct berval *bv); +void slapi_v4_bvarray_fold(struct berval **array, void (*fn)(struct berval *bv, void *acc, void *arg), void *acc, void *arg); + +/* + * Slapi_DN types + */ + +/** + * Represents a distinguished name in a directory entry. + * + * #Slapi_DN is the data type for an opaque structure that represents a distinguished + * name in the server plug-in. + */ +typedef struct slapi_dn slapi_v4_dn; +void slapi_v4_sdn_free(slapi_v4_dn *sdn); +slapi_v4_dn * slapi_v4_sdn_new_from_char_dn(const char *dn); +slapi_v4_dn * slapi_v4_sdn_dup(const slapi_v4_dn *sdn); + +/* + * TLS and certificate handling. + */ + +typedef struct CERTCertificateStr slapi_v4_cert; +char * slapi_v4_cert_get_subjectdn(slapi_v4_cert *cert); +char * slapi_v4_cert_get_issuerdn(slapi_v4_cert *cert); +struct berval *slapi_v4_cert_get_der_berval(slapi_v4_cert *cert); +char ** slapi_v4_cert_get_subject_ava_val(slapi_v4_cert *cert, const char *attr); + +/* + * PBLOCKS and related option passing code + */ + +/* We only have empty pblock declarations */ + +typedef struct _slapi_v4_certmap_pblock slapi_v4_certmap_pblock; + +slapi_v4_certmap_pblock * slapi_v4_certmap_pblock_init(void); +void slapi_v4_certmap_pblock_destroy(slapi_v4_certmap_pblock *pbc); + +void slapi_v4_certmap_pblock_set_clientdn(slapi_v4_certmap_pblock *pbc, slapi_v4_dn *sdn); +slapi_v4_dn * slapi_v4_certmap_pblock_get_clientdn(slapi_v4_certmap_pblock *pbc); + +slapi_v4_cert * slapi_v4_certmap_pblock_get_clientcert(slapi_v4_certmap_pblock *pbc); +void slapi_v4_certmap_pblock_set_clientcert(slapi_v4_certmap_pblock *pbc, slapi_v4_cert *clientcert); + +/* + * Entry interaction code. + */ +typedef struct slapi_entry Slapi_Entry; + +const slapi_v4_dn * slapi_v4_entry_get_sdn(Slapi_Entry *e); + +char **slapi_v4_entry_attr_get_charray(const Slapi_Entry *e, const char *type); + +struct berval **slapi_v4_entry_attr_get_bervals(const Slapi_Entry *e, const char *type); + +/* + * Search pblock. This is based on the v3 search pblock. + */ +typedef struct _slapi_pblock_intop slapi_v4_search_pblock; + +void slapi_v4_search_pblock_destroy(slapi_v4_search_pblock *pbs); +/* execute a search, and result the result pb */ +slapi_v4_search_pblock * slapi_v4_search_internal(slapi_v4_dn *basedn, + int scope, + const char *filter, + char **attrs, + int attrsonly, + LDAPControl **controls, + const char *uniqueid, + int operation_flags); + +slapi_v4_search_pblock * slapi_v4_search_internal_all_contexts(int scope, + const char *filter, + char **attrs, + int attrsonly, + LDAPControl **controls, + const char *uniqueid, + int operation_flags); + +slapi_v4_search_pblock * slapi_v4_add_internal_entry(Slapi_Entry *entry, const char *modifier_name); + +slapi_v4_plugin_result * slapi_v4_entry_exists_or_create(slapi_v4_dn *dn, const char *filter, const char *entry, const char *modifier_name); + +uint64_t slapi_v4_search_pblock_get_num_results(slapi_v4_search_pblock *pbs); +Slapi_Entry **slapi_v4_search_pblock_get_entries(slapi_v4_search_pblock *pbs); +char **slapi_v4_search_pblogk_get_referrals(slapi_v4_search_pblock *pbs); + +int slapi_v4_search_pblock_get_ldapresult(slapi_v4_search_pblock *pbs); + + + +/* + * PLUGIN REGISTRATION COMPONENTS + */ + +/* Forward declare this empty type */ +typedef struct _slapi_v4_plugin_registration slapi_v4_plugin_registration; + +#define SV4_PLUGIN_PRECEDENCE_DEFAULT 50 + +void slapi_v4_plugin_register_name(slapi_v4_plugin_registration *pr, char *name); +void slapi_v4_plugin_register_precedence(slapi_v4_plugin_registration *pr, uint64_t order); +void slapi_v4_plugin_register_start_fn(slapi_v4_plugin_registration *pr, slapi_v4_plugin_result *(*sv4_start_fn)(void **ctx)); +void slapi_v4_plugin_register_close_fn(slapi_v4_plugin_registration *pr, slapi_v4_plugin_result *(*sv4_close_fn)(void **ctx)); +void slapi_v4_plugin_register_bind_certmap_fn(slapi_v4_plugin_registration *pr, slapi_v4_plugin_result *(*sv4_bind_certmap_fn)(void *ctx, slapi_v4_certmap_pblock *pbc)); + +/* + * RESULT MANAGEMENT + */ + +slapi_v4_plugin_result *slapi_v4_plugin_result_ok(void); +slapi_v4_plugin_result *slapi_v4_plugin_result_err(SV4_PLUGIN_RESULT_CODE result, int ldap_code, char *msg); +void slapi_v4_plugin_result_destroy(slapi_v4_plugin_result *r); + +/* + * CONFIGURATION + * Access to configurations. These should always stay private as plugins should + * never need to access this content. + */ + +char *config_get_configdir(void); + +char *config_get_certmap_basedn(void); + +/* + * Filter management + */ + +char * slapi_v4_escape_filter_value(char *filter_str, int len); + +/* + * Char arrays and manipulation. + */ + +char ** slapi_v4_charray_from_str(char *str, char *brkstr, int allow_dups); +char ** slapi_v4_charray_append(char **a, char *s); +void slapi_v4_charray_free(char **array); + +/* + * BORROW FROM V3 + * + * YOU MUST NOT CHANGE THESE LINES, AND THEY MAY NOT REMAIN STABLE + */ + +/* + * UTF8 string handling + */ + +unsigned char * slapi_utf8StrToLower(unsigned char *s); +unsigned char * ldap_utf8strip(unsigned char *s); +char * ldap_utf8strtok_r(char *sp, const char *brk, char **next); + + diff --git a/ldap/servers/slapd/slapi_pal.h b/ldap/servers/slapd/slapi_pal.h index a6d9453..301e13b 100644 --- a/ldap/servers/slapd/slapi_pal.h +++ b/ldap/servers/slapd/slapi_pal.h @@ -20,6 +20,12 @@ #pragma once #include +/* malloc and size_t */ +#include + +void * spal_calloc(size_t size); +void * spal_realloc(void *ptr, size_t size); +void spal_free(void *ptr); /** * Structure that contains our system memory information in bytes and pages. -- 1.8.3.1