]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/saslauthz.c
Fix pkiUser
[openldap] / servers / slapd / saslauthz.c
index d196a4f084ba1d4c1de2e9278fccc3d43d3dc513..601d0245c8481102d6792be533e960c3f3d9ca06 100644 (file)
 
 #include <ldap_pvt.h>
 
+#define SASLREGEX_REPLACE 10
+
+typedef struct sasl_uri {
+  struct berval dn;
+  struct berval filter;
+  int scope;
+} SaslUri_t;
+
+typedef struct sasl_regexp {
+  char *sr_match;                                                      /* regexp match pattern */
+  SaslUri_t sr_replace;                                                /* regexp replace pattern */
+  regex_t sr_workspace;                                                /* workspace for regexp engine */
+  regmatch_t sr_strings[SASLREGEX_REPLACE];    /* strings matching $1,$2 ... */
+  int sr_dn_offset[SASLREGEX_REPLACE+2];               /* offsets of $1,$2... in *replace */
+  int sr_fi_offset[SASLREGEX_REPLACE+2];               /* offsets of $1,$2... in *replace */
+} SaslRegexp_t;
+
+static int nSaslRegexp = 0;
+static SaslRegexp_t *SaslRegexp = NULL;
+
+/* What SASL proxy authorization policies are allowed? */
+#define        SASL_AUTHZ_NONE 0
+#define        SASL_AUTHZ_FROM 1
+#define        SASL_AUTHZ_TO   2
+
+static int authz_policy = SASL_AUTHZ_NONE;
+
+int slap_sasl_setpolicy( const char *arg )
+{
+       int rc = LDAP_SUCCESS;
+
+       if ( strcasecmp( arg, "none" ) == 0 )
+               authz_policy = SASL_AUTHZ_NONE;
+       else if ( strcasecmp( arg, "from" ) == 0 )
+               authz_policy = SASL_AUTHZ_FROM;
+       else if ( strcasecmp( arg, "to" ) == 0 )
+               authz_policy = SASL_AUTHZ_TO;
+       else if ( strcasecmp( arg, "both" ) == 0 )
+               authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO;
+       else
+               rc = LDAP_OTHER;
+       return rc;
+}
+
 /* URI format: ldap://<host>/<base>[?[<attrs>][?[<scope>][?[<filter>]]]] */
 
 static int slap_parseURI( struct berval *uri,
@@ -81,7 +125,10 @@ is_dn:              bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
                return( LDAP_PROTOCOL_ERROR );
        }
 
-       /* could check the hostname here */
+       if ( ludp->lud_host && *ludp->lud_host ) {
+               /* host part should be empty */
+               return( LDAP_PROTOCOL_ERROR );
+       }
 
        /* Grab the scope */
        *scope = ludp->lud_scope;
@@ -357,21 +404,22 @@ static int sasl_sc_sasl2dn( BackendDB *be, Connection *conn, Operation *o,
        struct berval *ndn = o->o_callback->sc_private;
 
        /* We only want to be called once */
-       if (ndn->bv_val) {
+       if( ndn->bv_val ) {
                free(ndn->bv_val);
                ndn->bv_val = NULL;
+
 #ifdef NEW_LOGGING
-       LDAP_LOG(( "sasl", LDAP_LEVEL_DETAIL1,
-                  "slap_sasl2dn: search DN returned more than 1 entry\n" ));
+               LDAP_LOG(( "sasl", LDAP_LEVEL_DETAIL1,
+                       "slap_sasl2dn: search DN returned more than 1 entry\n" ));
 #else
-       Debug( LDAP_DEBUG_TRACE,
-          "slap_sasl2dn: search DN returned more than 1 entry\n", 0,0,0 );
+               Debug( LDAP_DEBUG_TRACE,
+                       "slap_sasl2dn: search DN returned more than 1 entry\n", 0,0,0 );
 #endif
                return -1;
-       } else {
-               ber_dupbv(ndn, &e->e_nname);
-               return 0;
        }
+
+       ber_dupbv(ndn, &e->e_nname);
+       return 0;
 }
 
 /*
@@ -396,9 +444,10 @@ void slap_sasl2dn( Connection *conn, struct berval *saslname, struct berval *dn
        LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
                "slap_sasl2dn: converting SASL name %s to DN.\n", saslname->bv_val ));
 #else
-       Debug( LDAP_DEBUG_TRACE,
-               "==>slap_sasl2dn: Converting SASL name %s to a DN\n", saslname->bv_val, 0,0 );
+       Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
+               "converting SASL name %s to a DN\n", saslname->bv_val, 0,0 );
 #endif
+
        dn->bv_val = NULL;
        dn->bv_len = 0;
        cb.sc_private = dn;
@@ -414,8 +463,6 @@ void slap_sasl2dn( Connection *conn, struct berval *saslname, struct berval *dn
 
        be = select_backend( &uri.dn, 0, 1 );
 
-       conn->c_authz_backend = be;
-
        /* Massive shortcut: search scope == base */
        if( uri.scope == LDAP_SCOPE_BASE ) {
                *dn = uri.dn;
@@ -426,16 +473,17 @@ void slap_sasl2dn( Connection *conn, struct berval *saslname, struct berval *dn
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "sasl", LDAP_LEVEL_DETAIL1,
-                  "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
-                  uri.dn.bv_val, uri.scope ));
+               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+               uri.dn.bv_val, uri.scope ));
 #else
        Debug( LDAP_DEBUG_TRACE,
           "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
           uri.dn.bv_val, uri.scope, 0 );
 #endif
 
-       if(( be == NULL ) || ( be->be_search == NULL))
+       if(( be == NULL ) || ( be->be_search == NULL)) {
                goto FINISHED;
+       }
        suffix_alias( be, &uri.dn );
 
        op.o_tag = LDAP_REQ_SEARCH;
@@ -444,10 +492,14 @@ void slap_sasl2dn( Connection *conn, struct berval *saslname, struct berval *dn
        op.o_callback = &cb;
        op.o_time = slap_get_time();
 
-       (*be->be_search)( be, /*conn*/NULL, &op, /*base*/NULL, &uri.dn,
-          uri.scope, /*deref=*/1, /*sizelimit=*/1, /*time=*/0, filter, /*fstr=*/NULL,
-          /*attrs=*/NULL, /*attrsonly=*/0 );
+       (*be->be_search)( be, NULL, &op, NULL, &uri.dn,
+               uri.scope, LDAP_DEREF_NEVER, 1, 0,
+               filter, NULL, NULL, 1 );
        
+       if( dn->bv_len ) {
+               conn->c_authz_backend = be;
+       }
+
 FINISHED:
        if( uri.dn.bv_len ) ch_free( uri.dn.bv_val );
        if( uri.filter.bv_len ) ch_free( uri.filter.bv_val );
@@ -593,27 +645,21 @@ CONCLUDED:
  * The DNs should not have the dn: prefix
  */
 static int
-slap_sasl_check_authz(struct berval *searchDN, struct berval *assertDN, struct berval *attr, struct berval *authc)
+slap_sasl_check_authz(struct berval *searchDN, struct berval *assertDN, AttributeDescription *ad, struct berval *authc)
 {
-       const char *errmsg;
        int i, rc;
        BerVarray vals=NULL;
-       AttributeDescription *ad=NULL;
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
                   "slap_sasl_check_authz: does %s match %s rule in %s?\n",
-                  assertDN->bv_val, attr->bv_val, searchDN->bv_val ));
+                  assertDN->bv_val, ad->ad_cname.bv_val, searchDN->bv_val ));
 #else
        Debug( LDAP_DEBUG_TRACE,
           "==>slap_sasl_check_authz: does %s match %s rule in %s?\n",
-          assertDN->bv_val, attr->bv_val, searchDN->bv_val);
+          assertDN->bv_val, ad->ad_cname.bv_val, searchDN->bv_val);
 #endif
 
-       rc = slap_bv2ad( attr, &ad, &errmsg );
-       if( rc != LDAP_SUCCESS )
-               goto COMPLETE;
-
        rc = backend_attribute( NULL, NULL, NULL, NULL, searchDN, ad, &vals );
        if( rc != LDAP_SUCCESS )
                goto COMPLETE;
@@ -631,10 +677,10 @@ COMPLETE:
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
-                  "slap_sasl_check_authz: %s check returning %s\n", attr->bv_val, rc ));
+                  "slap_sasl_check_authz: %s check returning %s\n", ad->ad_cname.bv_val, rc ));
 #else
        Debug( LDAP_DEBUG_TRACE,
-          "<==slap_sasl_check_authz: %s check returning %d\n", attr->bv_val, rc, 0);
+          "<==slap_sasl_check_authz: %s check returning %d\n", ad->ad_cname.bv_val, rc, 0);
 #endif
 
        return( rc );
@@ -646,12 +692,6 @@ COMPLETE:
  * The DNs should not have the dn: prefix
  */
 
-static struct berval sasl_authz_src = {
-       sizeof(SASL_AUTHZ_SOURCE_ATTR)-1, SASL_AUTHZ_SOURCE_ATTR };
-
-static struct berval sasl_authz_dst = {
-       sizeof(SASL_AUTHZ_DEST_ATTR)-1, SASL_AUTHZ_DEST_ATTR };
-
 int slap_sasl_authorized( struct berval *authcDN, struct berval *authzDN )
 {
        int rc = LDAP_INAPPROPRIATE_AUTH;
@@ -678,17 +718,21 @@ int slap_sasl_authorized( struct berval *authcDN, struct berval *authzDN )
        }
 
        /* Check source rules */
-       rc = slap_sasl_check_authz( authcDN, authzDN, &sasl_authz_src,
-          authcDN );
-       if( rc == LDAP_SUCCESS ) {
-               goto DONE;
+       if( authz_policy & SASL_AUTHZ_TO ) {
+               rc = slap_sasl_check_authz( authcDN, authzDN,
+                       slap_schema.si_ad_saslAuthzTo, authcDN );
+               if( rc == LDAP_SUCCESS ) {
+                       goto DONE;
+               }
        }
 
        /* Check destination rules */
-       rc = slap_sasl_check_authz( authzDN, authcDN, &sasl_authz_dst,
-          authcDN );
-       if( rc == LDAP_SUCCESS ) {
-               goto DONE;
+       if( authz_policy & SASL_AUTHZ_FROM ) {
+               rc = slap_sasl_check_authz( authzDN, authcDN,
+                       slap_schema.si_ad_saslAuthzFrom, authcDN );
+               if( rc == LDAP_SUCCESS ) {
+                       goto DONE;
+               }
        }
 
        rc = LDAP_INAPPROPRIATE_AUTH;