+
+int
+load_extop(
+ const char *ext_oid,
+ SLAP_EXTOP_MAIN_FN *ext_main )
+{
+ struct extop_list *ext;
+
+ if( ext_oid == NULL || *ext_oid == '\0' ) return -1;
+ if(!ext_main) return -1;
+
+ ext = ch_calloc(1, sizeof(struct extop_list));
+ if (ext == NULL)
+ return(-1);
+
+ ber_str2bv( ext_oid, 0, 1, &ext->oid );
+ if (ext->oid.bv_val == NULL) {
+ free(ext);
+ return(-1);
+ }
+
+ ext->ext_main = ext_main;
+ ext->next = supp_ext_list;
+
+ supp_ext_list = ext;
+
+ return(0);
+}
+
+int
+extops_init (void)
+{
+ int i;
+
+ for (i = 0; builtin_extops[i].oid.bv_val != NULL; i++) {
+ load_extop(builtin_extops[i].oid.bv_val, builtin_extops[i].ext_main);
+ }
+ return(0);
+}
+
+int
+extops_kill (void)
+{
+ struct extop_list *ext;
+
+ /* we allocated the memory, so we have to free it, too. */
+ while ((ext = supp_ext_list) != NULL) {
+ supp_ext_list = ext->next;
+ if (ext->oid.bv_val != NULL)
+ ch_free(ext->oid.bv_val);
+ ch_free(ext);
+ }
+ return(0);
+}
+
+static struct extop_list *
+find_extop( struct extop_list *list, struct berval *oid )
+{
+ struct extop_list *ext;
+
+ for (ext = list; ext; ext = ext->next) {
+ if (ber_bvcmp(&ext->oid, oid) == 0)
+ return(ext);
+ }
+ return(NULL);
+}
+
+
+static int
+whoami_extop (
+ Connection *conn,
+ Operation *op,
+ const char * reqoid,
+ struct berval * reqdata,
+ char ** rspoid,
+ struct berval ** rspdata,
+ LDAPControl ***rspctrls,
+ const char ** text,
+ BerVarray * refs )
+{
+ int rc;
+ struct berval *bv;
+
+ if ( reqdata != NULL ) {
+ /* no request data should be provided */
+ *text = "no request data expected";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ {
+ int rc;
+ struct berval whoami = BER_BVC( LDAP_EXOP_X_WHO_AM_I );
+
+ rc = backend_check_restrictions( conn->c_authz_backend,
+ conn, op, &whoami, text );
+
+ if( rc != LDAP_SUCCESS ) return rc;
+ }
+
+ bv = (struct berval *) ch_malloc( sizeof(struct berval) );
+ if( op->o_dn.bv_len ) {
+ bv->bv_len = op->o_dn.bv_len + sizeof("dn:")-1;
+ bv->bv_val = ch_malloc( bv->bv_len + 1 );
+ AC_MEMCPY( bv->bv_val, "dn:", sizeof("dn:")-1 );
+ AC_MEMCPY( &bv->bv_val[sizeof("dn:")-1], op->o_dn.bv_val,
+ op->o_dn.bv_len );
+ bv->bv_val[bv->bv_len] = '\0';
+
+ } else {
+ bv->bv_len = 0;
+ bv->bv_val = NULL;
+ }
+
+ *rspdata = bv;
+ return LDAP_SUCCESS;
+}