From 271fff13defea6a173d125cd9ed0cba68da4324b Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 17 Dec 2003 17:55:27 +0000 Subject: [PATCH] Sync with HEAD --- clients/tools/ldapsearch.c | 19 ++-- include/ldap.h | 208 ++++++++++++++++++++---------------- libraries/libldap/request.c | 24 +++-- libraries/libldap/search.c | 14 ++- libraries/libldap/test.c | 11 +- libraries/libldap/url.c | 17 ++- servers/slapd/backend.c | 12 ++- servers/slapd/backglue.c | 7 +- servers/slapd/config.c | 4 + servers/slapd/root_dse.c | 12 ++- servers/slapd/saslauthz.c | 1 + servers/slapd/search.c | 7 +- servers/slapd/slap.h | 21 ++-- 13 files changed, 219 insertions(+), 138 deletions(-) diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index 355b5d5ed4..c5b6f57e47 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -406,12 +406,16 @@ handle_private_option( int i ) ++ldif; break; case 's': /* search scope */ - if ( strcasecmp( optarg, "base" ) == 0 ) { - scope = LDAP_SCOPE_BASE; + if ( strncasecmp( optarg, "base", sizeof("base"-1) ) == 0 ) { + scope = LDAP_SCOPE_BASE; } else if ( strncasecmp( optarg, "one", sizeof("one")-1 ) == 0 ) { - scope = LDAP_SCOPE_ONELEVEL; + scope = LDAP_SCOPE_ONELEVEL; + } else if (( strcasecmp( optarg, "subordinate" ) == 0 ) + || ( strcasecmp( optarg, "children" ) == 0 )) + { + scope = LDAP_SCOPE_SUBORDINATE; } else if ( strncasecmp( optarg, "sub", sizeof("sub")-1 ) == 0 ) { - scope = LDAP_SCOPE_SUBTREE; + scope = LDAP_SCOPE_SUBTREE; } else { fprintf( stderr, _("scope should be base, one, or sub\n") ); usage(); @@ -716,8 +720,11 @@ getNextPage: printf( "#\n" ); printf(_("# LDAPv%d\n"), protocol); printf(_("# base <%s> with scope %s\n"), - base ? base : "", (scope == LDAP_SCOPE_BASE) ? "base" - : ((scope == LDAP_SCOPE_ONELEVEL) ? "one" : "sub")); + base ? base : "", + ((scope == LDAP_SCOPE_BASE) ? "baseObject" + : ((scope == LDAP_SCOPE_ONELEVEL) ? "oneLevel" + : ((scope == LDAP_SCOPE_SUBORDINATE) ? "children" + : "subtree")))); printf(_("# filter%s: %s\n"), infile != NULL ? _(" pattern") : "", filtpattern); printf(_("# requesting: ")); diff --git a/include/ldap.h b/include/ldap.h index 7586b6b576..260bfbb408 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -74,39 +74,39 @@ LDAP_BEGIN_DECL #define LDAP_ROOT_DSE "" #define LDAP_NO_ATTRS "1.1" #define LDAP_ALL_USER_ATTRIBUTES "*" -#define LDAP_ALL_OPERATIONAL_ATTRIBUTES "+" /* OpenLDAP extension */ +#define LDAP_ALL_OPERATIONAL_ATTRIBUTES "+" /* RFC 3673 */ /* - * LDAP_OPTions defined by draft-ldapext-ldap-c-api-02 - * 0x0000 - 0x0fff reserved for api options - * 0x1000 - 0x3fff reserved for api extended options - * 0x4000 - 0x7fff reserved for private and experimental options + * LDAP_OPTions + * 0x0000 - 0x0fff reserved for api options + * 0x1000 - 0x3fff reserved for api extended options + * 0x4000 - 0x7fff reserved for private and experimental options */ + #define LDAP_OPT_API_INFO 0x0000 -#define LDAP_OPT_DESC 0x0001 /* deprecated */ +#define LDAP_OPT_DESC 0x0001 /* historic */ #define LDAP_OPT_DEREF 0x0002 #define LDAP_OPT_SIZELIMIT 0x0003 #define LDAP_OPT_TIMELIMIT 0x0004 -/* 0x05 - 0x07 not defined by current draft */ +/* 0x05 - 0x07 not defined */ #define LDAP_OPT_REFERRALS 0x0008 #define LDAP_OPT_RESTART 0x0009 -/* 0x0a - 0x10 not defined by current draft */ +/* 0x0a - 0x10 not defined */ #define LDAP_OPT_PROTOCOL_VERSION 0x0011 #define LDAP_OPT_SERVER_CONTROLS 0x0012 #define LDAP_OPT_CLIENT_CONTROLS 0x0013 -/* 0x14 not defined by current draft */ +/* 0x14 not defined */ #define LDAP_OPT_API_FEATURE_INFO 0x0015 - -/* 0x16 - 0x2f not defined by current draft */ +/* 0x16 - 0x2f not defined */ #define LDAP_OPT_HOST_NAME 0x0030 #define LDAP_OPT_RESULT_CODE 0x0031 #define LDAP_OPT_ERROR_NUMBER LDAP_OPT_RESULT_CODE #define LDAP_OPT_ERROR_STRING 0x0032 #define LDAP_OPT_MATCHED_DN 0x0033 +/* 0x0034 - 0x3fff not defined */ -/* 0x34 - 0x0fff not defined by current draft */ - -#define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x4000 /* to 0x7FFF inclusive */ +/* API Extensions */ +#define LDAP_OPT_API_EXTENSION_BASE 0x4000 /* API extensions */ /* private and experimental options */ /* OpenLDAP specific options */ @@ -130,10 +130,10 @@ LDAP_BEGIN_DECL #define LDAP_OPT_X_TLS_RANDOM_FILE 0x6009 #define LDAP_OPT_X_TLS_SSL_CTX 0x600a -#define LDAP_OPT_X_TLS_NEVER 0 +#define LDAP_OPT_X_TLS_NEVER 0 #define LDAP_OPT_X_TLS_HARD 1 -#define LDAP_OPT_X_TLS_DEMAND 2 -#define LDAP_OPT_X_TLS_ALLOW 3 +#define LDAP_OPT_X_TLS_DEMAND 2 +#define LDAP_OPT_X_TLS_ALLOW 3 #define LDAP_OPT_X_TLS_TRY 4 /* OpenLDAP SASL options */ @@ -148,9 +148,8 @@ LDAP_BEGIN_DECL #define LDAP_OPT_X_SASL_SSF_MAX 0x6108 #define LDAP_OPT_X_SASL_MAXBUFSIZE 0x6109 -/* on/off values */ -#define LDAP_OPT_ON ((void *) &ber_pvt_opt_on) -#define LDAP_OPT_OFF ((void *) 0) +/* Private API Extensions -- reserved for application use */ +#define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x7000 /* Private API inclusive */ /* * ldap_get_option() and ldap_set_option() return values. @@ -161,9 +160,13 @@ LDAP_BEGIN_DECL #define LDAP_OPT_SUCCESS 0 #define LDAP_OPT_ERROR (-1) -#define LDAP_API_INFO_VERSION (1) +/* option on/off values */ +#define LDAP_OPT_ON ((void *) &ber_pvt_opt_on) +#define LDAP_OPT_OFF ((void *) 0) + typedef struct ldapapiinfo { - int ldapai_info_version; /* version of LDAPAPIInfo (1) */ + int ldapai_info_version; /* version of LDAPAPIInfo */ +#define LDAP_API_INFO_VERSION (1) int ldapai_api_version; /* revision of API supported */ int ldapai_protocol_version; /* highest LDAP version supported */ char **ldapai_extensions; /* names of API extensions */ @@ -171,39 +174,35 @@ typedef struct ldapapiinfo { int ldapai_vendor_version; /* supplier-specific version * 100 */ } LDAPAPIInfo; -#define LDAP_FEATURE_INFO_VERSION (1) /* version of api feature structure */ typedef struct ldap_apifeature_info { - int ldapaif_info_version; /* version of this struct (1) */ - char* ldapaif_name; /* matches LDAP_API_FEATURE_... less the prefix */ - int ldapaif_version; /* matches the value LDAP_API_FEATURE_... */ + int ldapaif_info_version; /* version of LDAPAPIFeatureInfo */ +#define LDAP_FEATURE_INFO_VERSION (1) /* apifeature_info struct version */ + char* ldapaif_name; /* LDAP_API_FEATURE_* (less prefix) */ + int ldapaif_version; /* value of LDAP_API_FEATURE_... */ } LDAPAPIFeatureInfo; +/* + * LDAP Control structure + */ typedef struct ldapcontrol { - char * ldctl_oid; - struct berval ldctl_value; - char ldctl_iscritical; + char * ldctl_oid; /* numericoid of control */ + struct berval ldctl_value; /* encoded value of control */ + char ldctl_iscritical; /* criticality */ } LDAPControl; /* LDAP Controls */ -#define LDAP_CONTROL_ASSERT "1.3.6.1.4.1.4203.666.5.9" -#define LDAP_CONTROL_PRE_READ "1.3.6.1.4.1.4203.666.5.10.1" -#define LDAP_CONTROL_POST_READ "1.3.6.1.4.1.4203.666.5.10.2" -#define LDAP_CONTROL_MODIFY_INCREMENT "1.3.6.1.4.1.4203.666.5.11" +#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2" /* RFC 3296 */ +#define LDAP_CONTROL_SUBENTRIES "1.3.6.1.4.1.4203.1.10.1" /* RFC 3672 */ +#define LDAP_CONTROL_PAGEDRESULTS "1.2.840.113556.1.4.319" /* RFC 2696 */ -#define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3" -#define LDAP_CONTROL_SUBENTRIES "1.3.6.1.4.1.4203.1.10.1" #define LDAP_CONTROL_NOOP "1.3.6.1.4.1.4203.1.10.2" -#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2" #define LDAP_CONTROL_PROXY_AUTHZ "2.16.840.1.113730.3.4.18" +#define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3" -#if 0 -#define LDAP_CONTROL_DUPENT_REQUEST "2.16.840.1.113719.1.27.101.1" -#define LDAP_CONTROL_DUPENT_RESPONSE "2.16.840.1.113719.1.27.101.2" -#define LDAP_CONTROL_DUPENT_ENTRY "2.16.840.1.113719.1.27.101.3" -#define LDAP_CONTROL_DUPENT LDAP_CONTROL_DUPENT_REQUEST -#endif - -#define LDAP_CONTROL_PAGEDRESULTS "1.2.840.113556.1.4.319" +#define LDAP_CONTROL_ASSERT "1.3.6.1.4.1.4203.666.5.9" +#define LDAP_CONTROL_PRE_READ "1.3.6.1.4.1.4203.666.5.10.1" +#define LDAP_CONTROL_POST_READ "1.3.6.1.4.1.4203.666.5.10.2" +#define LDAP_CONTROL_MODIFY_INCREMENT "1.3.6.1.4.1.4203.666.5.11" #define LDAP_CONTROL_SYNC "1.3.6.1.4.1.4203.666.5.6" #define LDAP_CONTROL_SYNC_STATE "1.3.6.1.4.1.4203.666.5.7" @@ -233,23 +232,33 @@ typedef struct ldapcontrol { #define LDAP_SYNC_MODIFY 2 #define LDAP_SYNC_DELETE 3 -#define LDAP_CONTROL_SORTREQUEST "1.2.840.113556.1.4.473" -#define LDAP_CONTROL_SORTRESPONSE "1.2.840.113556.1.4.474" -#define LDAP_CONTROL_VLVREQUEST "2.16.840.1.113730.3.4.9" -#define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10" +#if 0 +#define LDAP_CONTROL_DUPENT_REQUEST "2.16.840.1.113719.1.27.101.1" +#define LDAP_CONTROL_DUPENT_RESPONSE "2.16.840.1.113719.1.27.101.2" +#define LDAP_CONTROL_DUPENT_ENTRY "2.16.840.1.113719.1.27.101.3" +#define LDAP_CONTROL_DUPENT LDAP_CONTROL_DUPENT_REQUEST +#endif /* controls for MSAD compatibility */ -#define LDAP_CONTROL_X_DOMAIN_SCOPE "1.2.840.113556.1.4.1339" -#define LDAP_CONTROL_X_PERMISSIVE_MODIFY "1.2.840.113556.1.4.1413" +#define LDAP_CONTROL_X_DOMAIN_SCOPE "1.2.840.113556.1.4.1339" +#define LDAP_CONTROL_X_PERMISSIVE_MODIFY "1.2.840.113556.1.4.1413" + +/* not implemented in slapd(8) */ +#define LDAP_CONTROL_SORTREQUEST "1.2.840.113556.1.4.473" /* RFC 2891 */ +#define LDAP_CONTROL_SORTRESPONSE "1.2.840.113556.1.4.474" /* RFC 2891 */ + +/* not implemented in slapd(8) */ +#define LDAP_CONTROL_VLVREQUEST "2.16.840.1.113730.3.4.9" +#define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10" /* LDAP Unsolicited Notifications */ -#define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036" +#define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036" /* RFC 2251 */ #define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION /* LDAP Extended Operations */ -#define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037" +#define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037" /* RFC 2830 */ -#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1" +#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1" /* RFC 3062 */ #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U) #define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U) #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U) @@ -259,13 +268,17 @@ typedef struct ldapcontrol { #define LDAP_EXOP_X_CANCEL "1.3.6.1.4.1.4203.666.6.3" /* LDAP Features */ -#define LDAP_FEATURE_ALL_OPERATIONAL_ATTRS "1.3.6.1.4.1.4203.1.5.1" /* + */ +#define LDAP_FEATURE_ALL_OP_ATTRS "1.3.6.1.4.1.4203.1.5.1" /* RFC 3673 */ #define LDAP_FEATURE_OBJECTCLASS_ATTRS \ "1.3.6.1.4.1.4203.1.5.2" /* @objectClass - new number to be assigned */ #define LDAP_FEATURE_ABSOLUTE_FILTERS "1.3.6.1.4.1.4203.1.5.3" /* (&) (|) */ #define LDAP_FEATURE_LANGUAGE_TAG_OPTIONS "1.3.6.1.4.1.4203.1.5.4" #define LDAP_FEATURE_LANGUAGE_RANGE_OPTIONS "1.3.6.1.4.1.4203.1.5.5" -#define LDAP_FEATURE_MODIFY_INCREMENT "1.3.6.1.4.1.4203.666.5.6" + +#define LDAP_FEATURE_SUBORDINATE_SCOPE \ + "1.3.6.1.4.1.4203.666.8.1" /* "children" */ +#define LDAP_FEATURE_CHILDREN_SCOPE LDAP_FEATURE_SUBORDINATE_SCOPE +#define LDAP_FEATURE_MODIFY_INCREMENT "1.3.6.1.4.1.4203.666.8.2" /* * specific LDAP instantiations of BER types we know about @@ -346,24 +359,24 @@ typedef struct ldapcontrol { /* authentication methods available */ -#define LDAP_AUTH_NONE ((ber_tag_t) 0x00U) /* no authentication */ -#define LDAP_AUTH_SIMPLE ((ber_tag_t) 0x80U) /* context specific + primitive */ -#define LDAP_AUTH_SASL ((ber_tag_t) 0xa3U) /* context specific + constructed */ -#define LDAP_AUTH_KRBV4 ((ber_tag_t) 0xffU) /* means do both of the following */ -#define LDAP_AUTH_KRBV41 ((ber_tag_t) 0x81U) /* context specific + primitive */ -#define LDAP_AUTH_KRBV42 ((ber_tag_t) 0x82U) /* context specific + primitive */ +#define LDAP_AUTH_NONE ((ber_tag_t) 0x00U) /* no authentication */ +#define LDAP_AUTH_SIMPLE ((ber_tag_t) 0x80U) /* context specific + primitive */ +#define LDAP_AUTH_SASL ((ber_tag_t) 0xa3U) /* context specific + constructed */ +#define LDAP_AUTH_KRBV4 ((ber_tag_t) 0xffU) /* means do both of the following */ +#define LDAP_AUTH_KRBV41 ((ber_tag_t) 0x81U) /* context specific + primitive */ +#define LDAP_AUTH_KRBV42 ((ber_tag_t) 0x82U) /* context specific + primitive */ /* filter types */ #define LDAP_FILTER_AND ((ber_tag_t) 0xa0U) /* context specific + constructed */ #define LDAP_FILTER_OR ((ber_tag_t) 0xa1U) /* context specific + constructed */ #define LDAP_FILTER_NOT ((ber_tag_t) 0xa2U) /* context specific + constructed */ -#define LDAP_FILTER_EQUALITY ((ber_tag_t) 0xa3U) /* context specific + constructed */ -#define LDAP_FILTER_SUBSTRINGS ((ber_tag_t) 0xa4U) /* context specific + constructed */ -#define LDAP_FILTER_GE ((ber_tag_t) 0xa5U) /* context specific + constructed */ -#define LDAP_FILTER_LE ((ber_tag_t) 0xa6U) /* context specific + constructed */ -#define LDAP_FILTER_PRESENT ((ber_tag_t) 0x87U) /* context specific + primitive */ -#define LDAP_FILTER_APPROX ((ber_tag_t) 0xa8U) /* context specific + constructed */ +#define LDAP_FILTER_EQUALITY ((ber_tag_t) 0xa3U) /* context specific + constructed */ +#define LDAP_FILTER_SUBSTRINGS ((ber_tag_t) 0xa4U) /* context specific + constructed */ +#define LDAP_FILTER_GE ((ber_tag_t) 0xa5U) /* context specific + constructed */ +#define LDAP_FILTER_LE ((ber_tag_t) 0xa6U) /* context specific + constructed */ +#define LDAP_FILTER_PRESENT ((ber_tag_t) 0x87U) /* context specific + primitive */ +#define LDAP_FILTER_APPROX ((ber_tag_t) 0xa8U) /* context specific + constructed */ #define LDAP_FILTER_EXT ((ber_tag_t) 0xa9U) /* context specific + constructed */ /* extended filter component types */ @@ -378,10 +391,15 @@ typedef struct ldapcontrol { #define LDAP_SUBSTRING_FINAL ((ber_tag_t) 0x82U) /* context specific */ /* search scopes */ -#define LDAP_SCOPE_DEFAULT ((ber_int_t) -1) -#define LDAP_SCOPE_BASE ((ber_int_t) 0x0000) -#define LDAP_SCOPE_ONELEVEL ((ber_int_t) 0x0001) -#define LDAP_SCOPE_SUBTREE ((ber_int_t) 0x0002) +#define LDAP_SCOPE_DEFAULT ((ber_int_t) -1) /* OpenLDAP extension */ +#define LDAP_SCOPE_BASE ((ber_int_t) 0x0000) +#define LDAP_SCOPE_BASEOBJECT LDAP_SCOPE_BASE +#define LDAP_SCOPE_ONELEVEL ((ber_int_t) 0x0001) +#define LDAP_SCOPE_ONE LDAP_SCOPE_ONELEVEL +#define LDAP_SCOPE_SUBTREE ((ber_int_t) 0x0002) +#define LDAP_SCOPE_SUB LDAP_SCOPE_SUBTREE +#define LDAP_SCOPE_SUBORDINATE ((ber_int_t) 0x0003) /* OpenLDAP extension */ +#define LDAP_SCOPE_CHILDREN LDAP_SCOPE_SUBORDINATE /* substring filter component types */ #define LDAP_SUBSTRING_INITIAL ((ber_tag_t) 0x80U) /* context specific */ @@ -478,7 +496,7 @@ typedef struct ldapcontrol { /* API Error Codes * * Based on draft-ietf-ldap-c-api-xx - * but with new (negative) codes + * but with new negative code values */ #define LDAP_API_ERROR(n) ((n)<0) #define LDAP_API_RESULT(n) ((n)<=0) @@ -518,7 +536,7 @@ typedef struct ldapmod { #define LDAP_MOD_ADD (0x0000) #define LDAP_MOD_DELETE (0x0001) #define LDAP_MOD_REPLACE (0x0002) -#define LDAP_MOD_INCREMENT (0x0003) +#define LDAP_MOD_INCREMENT (0x0003) /* OpenLDAP extension */ #define LDAP_MOD_BVALUES (0x0080) /* IMPORTANT: do not use code 0x1000 (or above), * it is used internally by the backends! @@ -869,24 +887,6 @@ ldap_kerberos_bind2_s LDAP_P(( /* deprecated */ #endif -/* - * LDAP Cancel Extended Operation - */ - -LDAP_F( int ) -ldap_cancel LDAP_P(( LDAP *ld, - int cancelid, - LDAPControl **sctrls, - LDAPControl **cctrls, - int *msgidp )); - -LDAP_F( int ) -ldap_cancel_s LDAP_P(( - LDAP *ld, - int cancelid, - LDAPControl **sctrl, - LDAPControl **cctrl )); - /* * in compare.c: */ @@ -1223,8 +1223,8 @@ typedef struct ldap_ava { #define LDAP_AVA_STRING 0x0001U #define LDAP_AVA_BINARY 0x0002U #define LDAP_AVA_NONPRINTABLE 0x0004U -#define LDAP_AVA_FREE_ATTR 0x0010U -#define LDAP_AVA_FREE_VALUE 0x0020U +#define LDAP_AVA_FREE_ATTR 0x0010U +#define LDAP_AVA_FREE_VALUE 0x0020U void *la_private; } LDAPAVA; @@ -1614,6 +1614,26 @@ ldap_free_urldesc LDAP_P(( LDAPURLDesc *ludp )); +/* + * LDAP Cancel Extended Operation + * in cancel.c + */ +#define LDAP_API_FEATURE_CANCEL 1000 + +LDAP_F( int ) +ldap_cancel LDAP_P(( LDAP *ld, + int cancelid, + LDAPControl **sctrls, + LDAPControl **cctrls, + int *msgidp )); + +LDAP_F( int ) +ldap_cancel_s LDAP_P(( + LDAP *ld, + int cancelid, + LDAPControl **sctrl, + LDAPControl **cctrl )); + /* * LDAP Server Side Sort * in sortctrl.c @@ -1688,6 +1708,7 @@ ldap_parse_vlv_control LDAP_P(( * LDAP Who Am I? * in whoami.c */ +#define LDAP_API_FEATURE_WHOAMI 1000 LDAP_F( int ) ldap_parse_whoami LDAP_P(( @@ -1712,6 +1733,7 @@ ldap_whoami_s LDAP_P(( * LDAP Password Modify * in passwd.c */ +#define LDAP_API_FEATURE_PASSWD_MODIFY 1000 LDAP_F( int ) ldap_parse_passwd LDAP_P(( diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index bd832cf131..ba77cc8b0b 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -1215,12 +1215,24 @@ re_encode_request( LDAP *ld, /* use the scope provided in reference */ scope = srv->lud_scope; - } else if ( sref && scope != LDAP_SCOPE_SUBTREE ) { - /* use scope implied by previous operation */ - /* base -> base */ - /* one -> base */ - /* subtree -> subtree */ - scope = LDAP_SCOPE_BASE; + } else if ( sref ) { + /* use scope implied by previous operation + * base -> base + * one -> base + * subtree -> subtree + * subordinate -> subtree + */ + switch( scope ) { + default: + case LDAP_SCOPE_BASE: + case LDAP_SCOPE_ONELEVEL: + scope = LDAP_SCOPE_BASE; + break; + case LDAP_SCOPE_SUBTREE: + case LDAP_SCOPE_SUBORDINATE: + scope = LDAP_SCOPE_SUBTREE; + break; + } } } else { diff --git a/libraries/libldap/search.c b/libraries/libldap/search.c index b926982c7d..54ac85da4a 100644 --- a/libraries/libldap/search.c +++ b/libraries/libldap/search.c @@ -36,8 +36,11 @@ * * ld LDAP descriptor * base DN of the base object - * scope the search scope - one of LDAP_SCOPE_BASE, - * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE + * scope the search scope - one of + * LDAP_SCOPE_BASE (baseObject), + * LDAP_SCOPE_ONELEVEL (oneLevel), + * LDAP_SCOPE_SUBTREE (subtree), or + * LDAP_SCOPE_SUBORDINATE (children) -- OpenLDAP extension * filter a string containing the search filter * (e.g., "(|(cn=bob)(sn=bob))") * attrs list of attribute types to return for matches @@ -160,8 +163,11 @@ ldap_search_ext_s( * * ld LDAP descriptor * base DN of the base object - * scope the search scope - one of LDAP_SCOPE_BASE, - * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE + * scope the search scope - one of + * LDAP_SCOPE_BASE (baseObject), + * LDAP_SCOPE_ONELEVEL (oneLevel), + * LDAP_SCOPE_SUBTREE (subtree), or + * LDAP_SCOPE_SUBORDINATE (children) -- OpenLDAP extension * filter a string containing the search filter * (e.g., "(|(cn=bob)(sn=bob))") * attrs list of attribute types to return for matches diff --git a/libraries/libldap/test.c b/libraries/libldap/test.c index 62308a070d..821f73c443 100644 --- a/libraries/libldap/test.c +++ b/libraries/libldap/test.c @@ -587,7 +587,7 @@ main( int argc, char **argv ) get_line( dn, sizeof(dn), stdin, "searchbase? " ); strcat( dn, dnsuffix ); get_line( line, sizeof(line), stdin, - "scope (0=Base, 1=One Level, 2=Subtree)? " ); + "scope (0=baseObject, 1=oneLevel, 2=subtree, 3=children)? " ); scope = atoi( line ); get_line( filter, sizeof(filter), stdin, "search filter (e.g. sn=jones)? " ); @@ -636,9 +636,12 @@ main( int argc, char **argv ) printf( " <%s>", ludp->lud_attrs[ i ] ); } } - printf( "\n\t scope: %s\n", ludp->lud_scope == LDAP_SCOPE_ONELEVEL ? - "ONE" : ludp->lud_scope == LDAP_SCOPE_BASE ? "BASE" : - ludp->lud_scope == LDAP_SCOPE_SUBTREE ? "SUB" : "**invalid**" ); + printf( "\n\t scope: %s\n", + ludp->lud_scope == LDAP_SCOPE_BASE ? "baseObject" + : ludp->lud_scope == LDAP_SCOPE_ONELEVEL ? "oneLevel" + : ludp->lud_scope == LDAP_SCOPE_SUBTREE ? "subtree" + : ludp->lud_scope == LDAP_SCOPE_SUBORDINATE ? "children" + : "**invalid**" ); printf( "\tfilter: <%s>\n", ludp->lud_filter ); ldap_free_urldesc( ludp ); } diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index b597a0c604..c5e284bb96 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -234,7 +234,7 @@ static int str2scope( const char *p ) if ( strcasecmp( p, "one" ) == 0 ) { return LDAP_SCOPE_ONELEVEL; - } else if ( strcasecmp( p, "onetree" ) == 0 ) { + } else if ( strcasecmp( p, "onelevel" ) == 0 ) { return LDAP_SCOPE_ONELEVEL; } else if ( strcasecmp( p, "base" ) == 0 ) { @@ -245,6 +245,12 @@ static int str2scope( const char *p ) } else if ( strcasecmp( p, "subtree" ) == 0 ) { return LDAP_SCOPE_SUBTREE; + + } else if ( strcasecmp( p, "subordinate" ) == 0 ) { + return LDAP_SCOPE_SUBORDINATE; + + } else if ( strcasecmp( p, "children" ) == 0 ) { + return LDAP_SCOPE_SUBORDINATE; } return( -1 ); @@ -341,10 +347,11 @@ char * ldap_url_desc2str( LDAPURLDesc *u ) if ( len ) len++; /* ? */ switch( u->lud_scope ) { + case LDAP_SCOPE_BASE: case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: - case LDAP_SCOPE_BASE: - len += sizeof("base"); + case LDAP_SCOPE_SUBORDINATE: + len += sizeof("subordinate"); if( !sep ) sep = 3; break; @@ -413,6 +420,10 @@ char * ldap_url_desc2str( LDAPURLDesc *u ) strcpy( &s[sofar], "sub" ); sofar += sizeof("sub") - 1; break; + case LDAP_SCOPE_SUBORDINATE: + strcpy( &s[sofar], "children" ); + sofar += sizeof("children") - 1; + break; } if( sep < 4 ) goto done; diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 5ec84fd975..79eb82d7c9 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -1233,15 +1233,21 @@ backend_group( goto loopit; switch(ludp->lud_scope) { case LDAP_SCOPE_BASE: - if ( !dn_match(&nbase, op_ndn)) goto loopit; + if ( !dn_match( &nbase, op_ndn )) goto loopit; break; case LDAP_SCOPE_ONELEVEL: dnParent(op_ndn, &bv ); - if ( !dn_match(&nbase, &bv)) goto loopit; + if ( !dn_match( &nbase, &bv )) goto loopit; break; case LDAP_SCOPE_SUBTREE: - if ( !dnIsSuffix(op_ndn, &nbase)) goto loopit; + if ( !dnIsSuffix( op_ndn, &nbase )) goto loopit; break; + case LDAP_SCOPE_SUBORDINATE: + if ( dn_match( &nbase, op_ndn ) && + !dnIsSuffix(op_ndn, &nbase )) + { + goto loopit; + } } filter = str2filter_x( op, ludp->lud_filter ); if ( filter ) { diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index be2b7e93d1..24492c1294 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -269,6 +269,7 @@ glue_back_search ( Operation *op, SlapReply *rs ) case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: + case LDAP_SCOPE_SUBORDINATE: /* FIXME */ op->o_callback = &cb; rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM; scope0 = op->ors_scope; @@ -306,14 +307,16 @@ glue_back_search ( Operation *op, SlapReply *rs ) } op->o_bd = gi->n[i].be; if (scope0 == LDAP_SCOPE_ONELEVEL && - dn_match(&gi->n[i].pdn, &ndn)) { + dn_match(&gi->n[i].pdn, &ndn)) + { op->ors_scope = LDAP_SCOPE_BASE; op->o_req_dn = op->o_bd->be_suffix[0]; op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search(op, rs); } else if (scope0 == LDAP_SCOPE_SUBTREE && - dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn)) { + dnIsSuffix(&op->o_bd->be_nsuffix[0], &ndn)) + { op->o_req_dn = op->o_bd->be_suffix[0]; op->o_req_ndn = op->o_bd->be_nsuffix[0]; rs->sr_err = op->o_bd->be_search( op, rs ); diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 56295fed6f..584c8eff72 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -3079,6 +3079,10 @@ parse_syncrepl_line( si->si_scope = LDAP_SCOPE_BASE; } else if ( !strncasecmp( val, "one", sizeof( "one" ) - 1 )) { si->si_scope = LDAP_SCOPE_ONELEVEL; + } else if ( !strcasecmp( val, "subordinate" ) || + !strcasecmp( val, "children" )) + { + si->si_scope = LDAP_SCOPE_SUBORDINATE; } else if ( !strncasecmp( val, "sub", sizeof( "sub" ) - 1 )) { si->si_scope = LDAP_SCOPE_SUBTREE; } else { diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index 4038dfb7cf..91db21e13d 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -29,13 +29,15 @@ #endif static struct berval supportedFeatures[] = { - BER_BVC(LDAP_FEATURE_ALL_OPERATIONAL_ATTRS), /* All Op Attrs (+) */ - BER_BVC(LDAP_FEATURE_OBJECTCLASS_ATTRS), /* OCs in Attrs List (+person) */ - BER_BVC(LDAP_FEATURE_ABSOLUTE_FILTERS), /* (&) and (|) search filters */ + BER_BVC(LDAP_FEATURE_ALL_OP_ATTRS), /* All Op Attrs (+) */ + BER_BVC(LDAP_FEATURE_OBJECTCLASS_ATTRS), /* OCs in Attrs List (@class) */ + BER_BVC(LDAP_FEATURE_ABSOLUTE_FILTERS), /* (&) and (|) search filters */ BER_BVC(LDAP_FEATURE_LANGUAGE_TAG_OPTIONS), /* Language Tag Options */ - BER_BVC(LDAP_FEATURE_LANGUAGE_RANGE_OPTIONS), /* Language Range Options */ + BER_BVC(LDAP_FEATURE_LANGUAGE_RANGE_OPTIONS),/* Language Range Options */ + #ifdef LDAP_DEVEL - BER_BVC(LDAP_FEATURE_MODIFY_INCREMENT), /* Modify/increment */ + BER_BVC(LDAP_FEATURE_SUBORDINATE_SCOPE), /* "children" search scope */ + BER_BVC(LDAP_FEATURE_MODIFY_INCREMENT), /* Modify/increment */ #endif {0,NULL} }; diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index a2f7fe0221..4ad85482eb 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -859,6 +859,7 @@ void slap_sasl2dn( Operation *opx, case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: + case LDAP_SCOPE_SUBORDINATE: /* do a search */ break; diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 2dfa2b9948..73f82a0043 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -70,7 +70,8 @@ do_search( * scope ENUMERATED { * baseObject (0), * singleLevel (1), - * wholeSubtree (2) + * wholeSubtree (2), + * subordinate (3) -- OpenLDAP extension * }, * derefAliases ENUMERATED { * neverDerefaliases (0), @@ -100,6 +101,7 @@ do_search( case LDAP_SCOPE_BASE: case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: + case LDAP_SCOPE_SUBORDINATE: break; default: send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" ); @@ -355,7 +357,8 @@ do_search( be_manageDSAit = manageDSAit; } - if ( (op->o_bd = select_backend( &op->o_req_ndn, be_manageDSAit, 1 )) == NULL ) { + op->o_bd = select_backend( &op->o_req_ndn, be_manageDSAit, 1 ); + if ( op->o_bd == NULL ) { rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, op->ors_scope ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 07eef92ae4..99beb433f9 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -871,9 +871,10 @@ typedef struct slap_mr_assertion { */ typedef struct slap_filter { ber_tag_t f_choice; /* values taken from ldap.h, plus: */ -#define SLAPD_FILTER_COMPUTED ((ber_tag_t) -1) -#define SLAPD_FILTER_DN_ONE ((ber_tag_t) -2) -#define SLAPD_FILTER_DN_SUBTREE ((ber_tag_t) -3) +#define SLAPD_FILTER_COMPUTED ((ber_tag_t) -1) +#define SLAPD_FILTER_DN_ONE ((ber_tag_t) -2) +#define SLAPD_FILTER_DN_SUBTREE ((ber_tag_t) -3) +#define SLAPD_FILTER_DN_CHILDREN ((ber_tag_t) -4) union f_un_u { /* precomputed result */ @@ -1281,15 +1282,15 @@ struct slap_limits_set { struct slap_limits { int lm_type; /* type of pattern */ #define SLAP_LIMITS_UNDEFINED 0x0000 -#define SLAP_LIMITS_EXACT 0x0001 -#define SLAP_LIMITS_BASE SLAP_LIMITS_EXACT -#define SLAP_LIMITS_ONE 0x0002 -#define SLAP_LIMITS_SUBTREE 0x0003 +#define SLAP_LIMITS_EXACT 0x0001 +#define SLAP_LIMITS_BASE SLAP_LIMITS_EXACT +#define SLAP_LIMITS_ONE 0x0002 +#define SLAP_LIMITS_SUBTREE 0x0003 #define SLAP_LIMITS_CHILDREN 0x0004 -#define SLAP_LIMITS_REGEX 0x0005 +#define SLAP_LIMITS_REGEX 0x0005 #define SLAP_LIMITS_ANONYMOUS 0x0006 -#define SLAP_LIMITS_USERS 0x0007 -#define SLAP_LIMITS_ANY 0x0008 +#define SLAP_LIMITS_USERS 0x0007 +#define SLAP_LIMITS_ANY 0x0008 regex_t lm_dn_regex; /* regex data for REGEX */ /* -- 2.39.5