SlapReply *rs,
LDAPControl *ctrl )
{
- int rc;
- struct berval dn = { 0, NULL };
+ int rc;
+ struct berval dn = { 0, NULL };
if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
rs->sr_text = "proxy authorization control specified multiple times";
return LDAP_SUCCESS;
}
- rc = slap_sasl_getdn( op->o_conn, op,
- ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
- NULL, &dn, SLAP_GETDN_AUTHZID );
+ /* FIXME: how can we get the realm? */
+ {
+ int rc;
+ char buf[ SLAP_LDAPDN_MAXLEN ];
+ struct berval id = { ctrl->ldctl_value.bv_len, (char *)buf },
+ user = { 0, NULL },
+ realm = { 0, NULL },
+ mech = { 0, NULL };
+
+ strncpy( buf, ctrl->ldctl_value.bv_val, sizeof( buf ) );
+
+ rc = slap_parse_user( &id, &user, &realm, &mech );
+ if ( rc == LDAP_SUCCESS ) {
+ if ( mech.bv_len ) {
+ rs->sr_text = "mech not allowed in authzId";
+ return LDAP_PROXY_AUTHZ_FAILURE;
+ }
+ } else {
+ user = ctrl->ldctl_value;
+ }
+
+ rc = slap_sasl_getdn( op->o_conn, op,
+ user.bv_val, user.bv_len,
+ realm.bv_val, &dn, SLAP_GETDN_AUTHZID );
- if( rc != LDAP_SUCCESS || !dn.bv_len ) {
- if ( dn.bv_val ) {
- ch_free( dn.bv_val );
+ if( rc != LDAP_SUCCESS || !dn.bv_len ) {
+ if ( dn.bv_val ) {
+ ch_free( dn.bv_val );
+ }
+ rs->sr_text = "authzId mapping failed";
+ return LDAP_PROXY_AUTHZ_FAILURE;
}
- rs->sr_text = "authzId mapping failed";
- return LDAP_PROXY_AUTHZ_FAILURE;
}
#ifdef NEW_LOGGING
/*
* saslauthz.c
*/
+LDAP_SLAPD_F (int) slap_parse_user LDAP_P((
+ struct berval *id, struct berval *user,
+ struct berval *realm, struct berval *mech ));
LDAP_SLAPD_F (void) slap_sasl2dn LDAP_P((
Operation *op,
struct berval *saslname,
int slap_sasl_getdn( Connection *conn, Operation *op, char *id, int len,
char *user_realm, struct berval *dn, int flags )
{
- char *c1;
int rc, is_dn = SET_NONE, do_norm = 1;
struct berval dn2, *mech;
/* Username strings */
if( is_dn == SET_U ) {
- char *p, *realm;
+ char *p;
+ struct berval realm = { 0, NULL }, c1 = *dn;
+
len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
+#if 0
/* username may have embedded realm name */
/* FIXME:
- * 1) userids can legally have embedded '@' chars
- * 2) we're mucking with memory we do not possess
- * 3) this should not be required, since we're
- * mostly doing strncpy's so we know how much
- * memory to copy ...
+ * userids can legally have embedded '@' chars;
+ * the relm should be set by those mechanisms
+ * that support it by means of the user_realm
+ * variable
*/
- if( ( realm = strrchr( dn->bv_val, '@') ) ) {
- *realm++ = '\0';
- len += sizeof(",cn=")-2;
- } else if( user_realm && *user_realm ) {
- len += strlen( user_realm ) + sizeof(",cn=")-1;
+ if( ( realm.bv_val = strrchr( dn->bv_val, '@') ) ) {
+ char *r = realm.bv_val;
+
+ realm.bv_val++;
+ realm.bv_len = dn->bv_len - ( realm.bv_val - dn->bv_val );
+ len += sizeof( ",cn=" ) - 2;
+ c1.bv_len -= realm.bv_len + 1;
+
+ if ( strchr( dn->bv_val, '@') == r ) {
+ /* FIXME: ambiguity, is it the realm
+ * or something else? */
+ }
+
+ } else
+#endif
+ if( user_realm && *user_realm ) {
+ realm.bv_val = user_realm;
+ realm.bv_len = strlen( user_realm );
+ len += realm.bv_len + sizeof(",cn=") - 1;
}
if( mech->bv_len ) {
}
/* Build the new dn */
- c1 = dn->bv_val;
dn->bv_val = sl_malloc( len+1, op->o_tmpmemctx );
if( dn->bv_val == NULL ) {
#ifdef NEW_LOGGING
return LDAP_OTHER;
}
p = lutil_strcopy( dn->bv_val, "uid=" );
- p = lutil_strncopy( p, c1, dn->bv_len );
+ p = lutil_strncopy( p, c1.bv_val, c1.bv_len );
- if( realm ) {
- int rlen = dn->bv_len - ( realm - c1 );
- p = lutil_strcopy( p, ",cn=" );
- p = lutil_strncopy( p, realm, rlen );
- realm[-1] = '@';
- } else if( user_realm && *user_realm ) {
+ if( realm.bv_len ) {
p = lutil_strcopy( p, ",cn=" );
- p = lutil_strcopy( p, user_realm );
+ p = lutil_strncopy( p, realm.bv_val, realm.bv_len );
}
if( mech->bv_len ) {
return rc;
}
+int slap_parse_user( struct berval *id, struct berval *user,
+ struct berval *realm, struct berval *mech )
+{
+ char u;
+
+ assert( id );
+ assert( id->bv_val );
+ assert( user );
+ assert( realm );
+ assert( mech );
+
+ u = id->bv_val[ 0 ];
+
+ assert( u == 'u' || u == 'U' );
+
+ user->bv_val = strrchr( id->bv_val, ':' );
+ if ( user->bv_val == NULL ) {
+ return LDAP_PROTOCOL_ERROR;
+ }
+ user->bv_val[ 0 ] = '\0';
+ user->bv_val++;
+ user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );
+
+ realm->bv_val = strchr( id->bv_val, '/' );
+ if ( realm->bv_val != NULL ) {
+ realm->bv_val[ 0 ] = '\0';
+ realm->bv_val++;
+ realm->bv_len = user->bv_val - realm->bv_val - 1;
+ }
+
+ mech->bv_val = strchr( id->bv_val, '.' );
+ if ( mech->bv_val != NULL ) {
+ mech->bv_val[ 0 ] = '\0';
+ mech->bv_val++;
+ if ( realm->bv_val ) {
+ mech->bv_len = realm->bv_val - mech->bv_val - 1;
+ } else {
+ mech->bv_len = user->bv_val - mech->bv_val - 1;
+ }
+ }
+
+ if ( id->bv_val[ 1 ] != '\0' ) {
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if ( mech->bv_val != NULL ) {
+ assert( mech->bv_val == id->bv_val + 2 );
+
+ memmove( mech->bv_val - 2, mech->bv_val, mech->bv_len + 1 );
+ mech->bv_val -= 2;
+ }
+
+ if ( realm->bv_val ) {
+ assert( realm->bv_val >= id->bv_val + 2 );
+
+ memmove( realm->bv_val - 2, realm->bv_val, realm->bv_len + 1 );
+ realm->bv_val -= 2;
+ }
+
+ if ( user->bv_val > id->bv_val + 2 ) {
+ user->bv_val -= 2;
+ user->bv_len += 2;
+ user->bv_val[ 0 ] = u;
+ user->bv_val[ 1 ] = ':';
+ }
+
+ return LDAP_SUCCESS;
+}
+
static int slap_parseURI( Operation *op, struct berval *uri,
struct berval *base, struct berval *nbase,
int *scope, Filter **filter, struct berval *fstr )
"slap_parseURI: parsing %s\n", uri->bv_val, 0, 0 );
#endif
+ rc = LDAP_PROTOCOL_ERROR;
if ( !strncasecmp( uri->bv_val, "dn", sizeof( "dn" ) - 1 ) ) {
- rc = LDAP_PROTOCOL_ERROR;
bv.bv_val = uri->bv_val + sizeof( "dn" ) - 1;
if ( bv.bv_val[ 0 ] == '.' ) {
break;
}
- return( rc );
+ return rc;
- } else if ( !strncasecmp( uri->bv_val, "u:", sizeof( "u:" ) - 1 ) ) {
- /* FIXME: I'll handle this later ... */
- return LDAP_PROTOCOL_ERROR;
+ } else if ( ( uri->bv_val[ 0 ] == 'u' || uri->bv_val[ 0 ] == 'U' )
+ && ( uri->bv_val[ 1 ] == ':'
+ || uri->bv_val[ 1 ] == '/'
+ || uri->bv_val[ 1 ] == '.' ) )
+ {
+ Connection c = *op->o_conn;
+ char buf[ SLAP_LDAPDN_MAXLEN ];
+ struct berval id = { uri->bv_len, (char *)buf },
+ user = { 0, NULL },
+ realm = { 0, NULL },
+ mech = { 0, NULL };
+
+ if ( sizeof( buf ) <= uri->bv_len ) {
+ return LDAP_INVALID_SYNTAX;
+ }
+
+ strncpy( buf, uri->bv_val, sizeof( buf ) );
+
+ rc = slap_parse_user( &id, &user, &realm, &mech );
+ if ( rc != LDAP_SUCCESS ) {
+ return rc;
+ }
+
+ if ( mech.bv_val ) {
+ c.c_sasl_bind_mech = mech;
+ } else {
+ c.c_sasl_bind_mech.bv_val = "AUTHZ";
+ c.c_sasl_bind_mech.bv_len = sizeof( "AUTHZ" ) - 1;
+ }
+
+ rc = slap_sasl_getdn( &c, op, user.bv_val, user.bv_len,
+ realm.bv_val, nbase, SLAP_GETDN_AUTHZID );
+
+ if ( rc == LDAP_SUCCESS ) {
+ *scope = LDAP_X_SCOPE_EXACT;
+ }
+
+ return rc;
}
rc = ldap_url_parse( uri->bv_val, &ludp );
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, DETAIL1,
- "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
+ "slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
+ "slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
#endif
return -1;
}
volatile sig_atomic_t slapd_abrupt_shutdown;
int slap_mods_check( Modifications *ml, int update, const char **text,
- char *textbuf, size_t textlen, void *ctx )
+ char *textbuf, size_t textlen, void *ctx )
{
return -1;
}
int slap_mods2entry( Modifications *mods, Entry **e, int repl_user,
- int dup, const char **text, char *textbuf, size_t textlen )
+ int dup, const char **text, char *textbuf, size_t textlen )
{
return -1;
}
int slap_mods_opattrs( Operation *op, Modifications *mods,
- Modifications **modtail, const char **text,
- char *textbuf, size_t textlen )
+ Modifications **modtail, const char **text,
+ char *textbuf, size_t textlen )
{
return -1;
}
+int slap_parse_user( struct berval *id, struct berval *user,
+ struct berval *realm, struct berval *mech )
+{
+ return -1;
+}