SRCS = init.c config.c search.c bind.c unbind.c add.c compare.c \
delete.c modify.c modrdn.c group.c attribute.c \
- suffixmassage.c map.c
+ suffixmassage.c map.c extended.c
OBJS = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \
delete.lo modify.lo modrdn.lo group.lo attribute.lo \
- suffixmassage.lo map.lo
+ suffixmassage.lo map.lo extended.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
#endif /* !NEW_LOGGING */
lc = ldap_back_getconn(li, conn, op);
- if ( !lc || !ldap_back_dobind( lc, conn, op ) ) {
+ if ( !lc || !ldap_back_dobind( li, lc, conn, op ) ) {
return( -1 );
}
free( mdn.bv_val );
}
- return( ldap_back_op_result( lc, conn, op, msgid, j ) );
+ return( ldap_back_op_result( li, lc, conn, op, msgid, j ) );
}
#ifdef ENABLE_REWRITE
is_oc = op->o_do_not_cache;
op->o_do_not_cache = 1;
lc = ldap_back_getconn(li, conn, op);
- if ( !lc || !ldap_back_dobind(lc, NULL, op) ) {
+ if ( !lc || !ldap_back_dobind(li, lc, NULL, op) ) {
op->o_do_not_cache = is_oc;
return 1;
}
struct ldapconn *ldap_back_getconn(struct ldapinfo *li, struct slap_conn *conn,
struct slap_op *op);
-int ldap_back_dobind(struct ldapconn *lc, Connection *conn, Operation *op);
+int ldap_back_dobind(struct ldapinfo *li, struct ldapconn *lc, Connection *conn, Operation *op);
int ldap_back_map_result(int err);
-int ldap_back_op_result(struct ldapconn *lc, Connection *conn, Operation *op,
+int ldap_back_op_result(struct ldapinfo *li, struct ldapconn *lc, Connection *conn, Operation *op,
ber_int_t msgid, int rc);
int back_ldap_LTX_init_module(int argc, char *argv[]);
/* method is always LDAP_AUTH_SIMPLE if we got here */
rc = ldap_sasl_bind(lc->ld, mdn.bv_val, LDAP_SASL_SIMPLE,
cred, op->o_ctrls, NULL, &msgid);
- rc = ldap_back_op_result( lc, conn, op, msgid, rc );
+ rc = ldap_back_op_result( li, lc, conn, op, msgid, rc );
if (rc == LDAP_SUCCESS) {
lc->bound = 1;
if ( mdn.bv_val != dn->bv_val ) {
* it can be used to simplify the check.
*/
int
-ldap_back_dobind( struct ldapconn *lc, Connection *conn, Operation *op )
+ldap_back_dobind( struct ldapinfo *li, struct ldapconn *lc, Connection *conn, Operation *op )
{
int rc;
ber_int_t msgid;
if ( !lc->bound ) {
rc = ldap_sasl_bind(lc->ld, lc->bound_dn.bv_val,
LDAP_SASL_SIMPLE, &lc->cred, NULL, NULL, &msgid);
- rc = ldap_back_op_result( lc, conn, op, msgid, rc );
+ rc = ldap_back_op_result( li, lc, conn, op, msgid, rc );
if (rc == LDAP_SUCCESS) {
lc->bound = 1;
}
}
int
-ldap_back_op_result(struct ldapconn *lc, Connection *conn, Operation *op,
- ber_int_t msgid, int err)
+ldap_back_op_result(struct ldapinfo *li, struct ldapconn *lc,
+ Connection *conn, Operation *op, ber_int_t msgid, int err)
{
char *msg = NULL;
char *match = NULL;
if (rc != LDAP_SUCCESS) err = rc;
}
}
- err = ldap_back_map_result(err);
-
- /* internal ops must not reply to client */
- if ( !conn || op->o_do_not_cache ) goto quiet;
+ if (err != LDAP_SUCCESS) {
+ err = ldap_back_map_result(err);
+ /* internal ops must not reply to client */
+ if ( conn && !op->o_do_not_cache ) {
+ char *mmatch = NULL;
#ifdef ENABLE_REWRITE
-
- /*
- * FIXME: need rewrite info for match; mmmh ...
- */
- send_ldap_result( conn, op, err, match, msg, NULL, NULL );
- /* better test the pointers before freeing? */
- if ( match ) {
- free( match );
- }
-
-#else /* !ENABLE_REWRITE */
-
- send_ldap_result( conn, op, err, match, msg, NULL, NULL );
- /* better test the pointers before freeing? */
- if ( match ) {
- free( match );
+ if (match) {
+
+ switch(rewrite_session(li->rwinfo, "matchedDn", match, conn,
+ &mmatch)) {
+ case REWRITE_REGEXEC_OK:
+ if (!mmatch) mmatch = match; break;
+ case REWRITE_REGEXEC_UNWILLING:
+ case REWRITE_REGEXEC_ERR:
+ break;
+ }
+ }
+#else
+ struct berval dn, mdn;
+ if (match) {
+ ber_str2bv(match, 0, 0, &dn);
+ ldap_back_dn_massage(li, &dn, &mdn, 0, 0);
+ mmatch = mdn.bv_val;
+ }
+#endif
+ send_ldap_result( conn, op, err, mmatch, msg, NULL, NULL );
+ if (mmatch != match) free(mmatch);
+ }
}
-
-#endif /* !ENABLE_REWRITE */
-
+ if ( match ) free( match );
if ( msg ) free( msg );
-quiet:
return( (err==LDAP_SUCCESS) ? 0 : -1 );
}
ber_int_t msgid;
lc = ldap_back_getconn(li, conn, op);
- if (!lc || !ldap_back_dobind( lc, conn, op ) ) {
+ if (!lc || !ldap_back_dobind( li, lc, conn, op ) ) {
return( -1 );
}
free( mdn.bv_val );
}
- return( ldap_back_op_result( lc, conn, op, msgid, rc ) );
+ return( ldap_back_op_result( li, lc, conn, op, msgid, rc ) );
}
lc = ldap_back_getconn( li, conn, op );
- if ( !lc || !ldap_back_dobind( lc, conn, op ) ) {
+ if ( !lc || !ldap_back_dobind( li, lc, conn, op ) ) {
return( -1 );
}
free( mdn.bv_val );
}
- return( ldap_back_op_result( lc, conn, op, msgid, rc ) );
+ return( ldap_back_op_result( li, lc, conn, op, msgid, rc ) );
}
--- /dev/null
+/* extended.c - ldap backend extended routines */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-ldap.h"
+#include "lber_pvt.h"
+
+BI_op_extended ldap_back_exop_passwd;
+
+static struct exop {
+ struct berval *oid;
+ BI_op_extended *extended;
+} exop_table[] = {
+ { (struct berval *)&slap_EXOP_MODIFY_PASSWD, ldap_back_exop_passwd },
+ { NULL, NULL }
+};
+
+int
+ldap_back_extended(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ struct berval *reqoid,
+ struct berval *reqdata,
+ char **rspoid,
+ struct berval **rspdata,
+ LDAPControl *** rspctrls,
+ const char** text,
+ BerVarray *refs
+)
+{
+ int i;
+
+ for( i=0; exop_table[i].extended != NULL; i++ ) {
+ if( ber_bvcmp( exop_table[i].oid, reqoid ) == 0 ) {
+ return (exop_table[i].extended)(
+ be, conn, op,
+ reqoid, reqdata,
+ rspoid, rspdata, rspctrls,
+ text, refs );
+ }
+ }
+
+ *text = "not supported within naming context";
+ return LDAP_UNWILLING_TO_PERFORM;
+}
+
+int
+ldap_back_exop_passwd(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ struct berval *reqoid,
+ struct berval *reqdata,
+ char **rspoid,
+ struct berval **rspdata,
+ LDAPControl *** rspctrls,
+ const char **text,
+ BerVarray *refs )
+{
+ struct ldapinfo *li = (struct ldapinfo *) be->be_private;
+ struct ldapconn *lc;
+ struct berval id = { 0, NULL };
+ struct berval old = { 0, NULL };
+ struct berval new = { 0, NULL };
+ struct berval dn, mdn = { 0, NULL }, *newpw = NULL;
+ LDAPMessage *res;
+ ber_int_t msgid;
+ char *msg = NULL, *match = NULL;
+ int rc;
+
+ lc = ldap_back_getconn(li, conn, op);
+ if (!lc || !ldap_back_dobind(li, lc, conn, op) ) {
+ return -1;
+ }
+
+ rc = slap_passwd_parse( reqdata, &id, &old, &new, text );
+ if (rc != LDAP_SUCCESS)
+ return rc;
+
+ if (id.bv_len) {
+ dn = id;
+ } else {
+ dn = op->o_dn;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG ( ACL, DETAIL1, "ldap_back_exop_passwd: \"%s\"%s\"\n",
+ dn.bv_val, id.bv_len ? " (proxy)" : "", 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "ldap_back_exop_passwd: \"%s\"%s\n",
+ dn.bv_val, id.bv_len ? " (proxy)" : "", 0 );
+#endif
+
+ if (dn.bv_len == 0) {
+ *text = "No password is associated with the Root DSE";
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+ if (id.bv_len) {
+#ifdef ENABLE_REWRITE
+ switch ( rewrite_session( li->rwinfo, "modifyPwd", dn.bv_val, conn, &mdn.bv_val ) ) {
+ case REWRITE_REGEXEC_OK:
+ if ( mdn.bv_val == NULL ) {
+ mdn.bv_val = dn.bv_val;
+ }
+ mdn.bv_len = strlen(mdn.bv_val);
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_LDAP, DETAIL1,
+ "[rw] modifyPwd: \"%s\" -> \"%s\"\n", dn.bv_val, mdn.bv_val, 0 );
+#else /* !NEW_LOGGING */
+ Debug( LDAP_DEBUG_ARGS, "rw> modifyPwd: \"%s\" -> \"%s\"\n%s",
+ dn.bv_val, mdn.bv_val, "" );
+#endif /* !NEW_LOGGING */
+ break;
+
+ case REWRITE_REGEXEC_UNWILLING:
+ send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
+ NULL, "Operation not allowed", NULL, NULL );
+ return( -1 );
+
+ case REWRITE_REGEXEC_ERR:
+ send_ldap_result( conn, op, LDAP_OTHER,
+ NULL, "Rewrite error", NULL, NULL );
+ return( -1 );
+ }
+#else /* !ENABLE_REWRITE */
+ ldap_back_dn_massage( li, &dn, &mdn, 0, 1 );
+#endif /* !ENABLE_REWRITE */
+ }
+
+ rc = ldap_passwd(lc->ld, id.bv_len ? &mdn : NULL, old.bv_len ? &old : NULL,
+ new.bv_len ? &new : NULL, op->o_ctrls, NULL, &msgid);
+#ifdef ENABLE_REWRITE
+ if (mdn.bv_val != dn.bv_val)
+#endif
+ free(mdn.bv_val);
+ if (rc == LDAP_SUCCESS) {
+ if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) {
+ ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc);
+ } else {
+ /* sigh. parse twice, because parse_passwd doesn't give
+ * us the err / match / msg info.
+ */
+ int err;
+ rc = ldap_parse_result(lc->ld, res, &err, &match, &msg,
+ NULL, NULL, 0);
+ if (rc == LDAP_SUCCESS) {
+ if (err == LDAP_SUCCESS) {
+ rc = ldap_parse_passwd(lc->ld, res, &newpw);
+ if (rc == LDAP_SUCCESS && newpw) {
+ *rspdata = slap_passwd_return(newpw);
+ ber_bvfree(newpw);
+ }
+ } else {
+ rc = err;
+ }
+ }
+ ldap_msgfree(res);
+ }
+ }
+ if (rc != LDAP_SUCCESS) {
+ rc = ldap_back_map_result(rc);
+ send_ldap_result(conn, op, rc, match, msg, NULL, NULL);
+ if (match) free(match);
+ if (msg) free(msg);
+ rc = -1;
+ }
+ return rc;
+}
extern BI_op_abandon ldap_back_abandon;
+extern BI_op_extended ldap_back_extended;
+
extern BI_acl_group ldap_back_group;
extern BI_acl_attribute ldap_back_attribute;
oc = op->o_do_not_cache;
op->o_do_not_cache = 1;
lc = ldap_back_getconn(li, conn, op);
- if ( !lc || !ldap_back_dobind( lc, NULL, op ) ) {
+ if ( !lc || !ldap_back_dobind( li, lc, NULL, op ) ) {
op->o_do_not_cache = oc;
goto cleanup;
}
bi->bi_op_delete = ldap_back_delete;
bi->bi_op_abandon = 0;
- bi->bi_extended = 0;
+ bi->bi_extended = ldap_back_extended;
bi->bi_acl_group = ldap_back_group;
bi->bi_acl_attribute = ldap_back_attribute;
ber_int_t msgid;
lc = ldap_back_getconn(li, conn, op);
- if ( !lc || !ldap_back_dobind( lc, conn, op ) ) {
+ if ( !lc || !ldap_back_dobind( li, lc, conn, op ) ) {
return( -1 );
}
ch_free(modv[i]->mod_bvalues);
ch_free(mods);
ch_free(modv);
- return( ldap_back_op_result( lc, conn, op, msgid, rc ));
+ return( ldap_back_op_result( li, lc, conn, op, msgid, rc ));
}
struct berval mdn = { 0, NULL }, mnewSuperior = { 0, NULL };
lc = ldap_back_getconn( li, conn, op );
- if ( !lc || !ldap_back_dobind(lc, conn, op) ) {
+ if ( !lc || !ldap_back_dobind(li, lc, conn, op) ) {
return( -1 );
}
free( mnewSuperior.bv_val );
}
- return( ldap_back_op_result( lc, conn, op, msgid, rc ) );
+ return( ldap_back_op_result( li, lc, conn, op, msgid, rc ) );
}
* FIXME: in case of values return filter, we might want
* to map attrs and maybe rewrite value
*/
- if ( !ldap_back_dobind( lc, conn, op ) ) {
+ if ( !ldap_back_dobind( li, lc, conn, op ) ) {
return( -1 );
}
: NULL, slimit, &msgid);
if ( rc != LDAP_SUCCESS ) {
fail:;
- rc = ldap_back_op_result(lc, conn, op, msgid, rc);
+ rc = ldap_back_op_result(li, lc, conn, op, msgid, rc);
goto finish;
}