예제 #1
0
static int verify_single_result(LDAP *l, int always_log, char *reason, LDAPMessage *messages)
{
  int rc, erc, num_entries;
  char *errmsg;

  rc = ldap_parse_result(l, messages, &erc, NULL, &errmsg,
			 NULL, NULL, 0);
  if (rc != LDAP_SUCCESS) {
    prtmsg("Failed to %s (parse_result): %s", reason, ldap_err2string(rc));
    return 0;
  }
  if (erc != LDAP_SUCCESS) {
    prtmsg("Failed to %s (server response): %s%s%s", reason, ldap_err2string(erc),
	   (errmsg?", ":""), (errmsg?errmsg:""));
    if (errmsg)
      ldap_memfree(errmsg);
    return 0;
  }
  if (errmsg)
    ldap_memfree(errmsg);
  num_entries=ldap_count_entries(l, messages);
  if (num_entries == 0) {
    if (always_log) 
      prtmsg("Failed to %s (no entries returned)", reason);
    return 0;
  }
  if (num_entries > 1) {
    prtmsg("Failed to %s (too many entries: %d)", reason, num_entries);
    return 0;
  }
  return 1;
}
예제 #2
0
파일: parse.c 프로젝트: howard5888/wineT
ULONG CDECL ldap_parse_resultW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result,
    ULONG *retcode, PWCHAR *matched, PWCHAR *error, PWCHAR **referrals,
    PLDAPControlW **serverctrls, BOOLEAN free )
{
    ULONG ret = LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    char **matchedU = NULL, **errorU = NULL, **referralsU = NULL;
    LDAPControl **serverctrlsU = NULL;

    TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld, result, retcode,
           matched, error, referrals, serverctrls, free );

    if (!ld) return ~0UL;

    ret = ldap_parse_result( ld, result, (int *)retcode, matchedU, errorU,
                             &referralsU, &serverctrlsU, free );

    matched = strarrayUtoW( matchedU );
    error = strarrayUtoW( errorU );

    *referrals = strarrayUtoW( referralsU );
    *serverctrls = controlarrayUtoW( serverctrlsU );

    ldap_memfree( matchedU );
    ldap_memfree( errorU );
    ldap_memfree( referralsU );
    ldap_controls_free( serverctrlsU );

#endif
    return ret;
}
예제 #3
0
파일: bind.c 프로젝트: LiptonB/freeipa
static void on_bind_readable(verto_ctx *vctx, verto_ev *ev)
{
    const char *errstr = "error";
    LDAPMessage *results;
    struct otpd_queue_item *item = NULL;
    int i, rslt;
    (void)vctx;

    rslt = ldap_result(verto_get_private(ev), LDAP_RES_ANY, 0, NULL, &results);
    if (rslt != LDAP_RES_BIND) {
        if (rslt <= 0)
            results = NULL;
        ldap_msgfree(results);
        otpd_log_err(EIO, "IO error received on bind socket");
        verto_break(ctx.vctx);
        ctx.exitstatus = 1;
        return;
    }

    item = otpd_queue_pop_msgid(&ctx.bind.responses, ldap_msgid(results));
    if (item == NULL) {
        ldap_msgfree(results);
        return;
    }
    item->msgid = -1;

    rslt = ldap_parse_result(verto_get_private(ev), results, &i,
                             NULL, NULL, NULL, NULL, 0);
    if (rslt != LDAP_SUCCESS) {
        errstr = ldap_err2string(rslt);
        goto error;
    }

    rslt = i;
    if (rslt != LDAP_SUCCESS) {
        errstr = ldap_err2string(rslt);
        goto error;
    }

    item->sent = 0;
    i = krad_packet_new_response(ctx.kctx, SECRET,
                                 krad_code_name2num("Access-Accept"),
                                 NULL, item->req, &item->rsp);
    if (i != 0) {
        errstr = krb5_get_error_message(ctx.kctx, i);
        goto error;
    }

error:
    if (item != NULL)
        otpd_log_req(item->req, "bind end: %s",
                item->rsp != NULL ? "success" : errstr);

    ldap_msgfree(results);
    otpd_queue_push(&ctx.stdio.responses, item);
    verto_set_flags(ctx.stdio.writer, VERTO_EV_FLAG_PERSIST |
                                      VERTO_EV_FLAG_IO_ERROR |
                                      VERTO_EV_FLAG_IO_READ |
                                      VERTO_EV_FLAG_IO_WRITE);
}
예제 #4
0
/* Called when results come in for a key send */
static gboolean
on_import_add_completed (LDAPMessage *result,
                         gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_import_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data));
	GError *error = NULL;
	char *message;
	int code;
	int rc;

	g_return_val_if_fail (ldap_msgtype (result) == LDAP_RES_ADD, FALSE);

	rc = ldap_parse_result (closure->ldap, result, &code, NULL,
	                        &message, NULL, NULL, 0);
	g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE);

	/* TODO: Somehow communicate this to the user */
	if (code == LDAP_ALREADY_EXISTS)
		code = LDAP_SUCCESS;

	ldap_memfree (message);

	if (seahorse_ldap_source_propagate_error (self, code, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete (res);
		return FALSE; /* don't call for this source again */
	}

	import_send_key (self, res);
	return FALSE; /* don't call for this source again */
}
예제 #5
0
파일: ldap.c 프로젝트: LuaDist/lua-apr
static int result_message(lua_State *L)
{
  struct timeval *timeout = NULL; /* ??? function parameter ??? */
  LDAPMessage *res;
  int rc;
  lua_apr_ldap_object *object = check_ldap_connection(L, lua_upvalueindex(1));
  int msgid = (int)lua_tonumber(L, lua_upvalueindex(2));
  /*int res_code = (int)lua_tonumber(L, lua_upvalueindex(3));*/

  luaL_argcheck(L, object->ldap, 1, "LDAP connection is closed");
  rc = ldap_result(object->ldap, msgid, LDAP_MSG_ONE, timeout, &res);

  if (rc == 0) {
    return push_error_message(L, "result timeout expired");
  } else if (rc < 0) {
    ldap_msgfree(res);
    return push_error_message(L, "result error");
  } else {
    int err, ret = 1;
    char *mdn, *msg1, *msg2;
    rc = ldap_parse_result(object->ldap, res, &err, &mdn, &msg1, NULL, NULL, 1);
    if (rc != LDAP_SUCCESS)
      return push_error_message(L, ldap_err2string(rc));
    switch (err) {
      case LDAP_SUCCESS:
      case LDAP_COMPARE_TRUE:
        lua_pushboolean(L, 1);
        break;
      case LDAP_COMPARE_FALSE:
        lua_pushboolean(L, 0);
        break;
      default:
        lua_pushnil(L);
        /* Either error message string may be NULL. */
        msg2 = ldap_err2string(err);
        if (msg1 == NULL && msg2 == NULL) {
          ret = 1;
        } else if (msg1 != NULL && msg2 == NULL) {
          lua_pushstring(L, msg1);
          ret = 2;
        } else if (msg1 == NULL && msg2 != NULL) {
          lua_pushstring(L, msg2);
          ret = 2;
        } else {
          lua_pushstring(L, msg1);
          lua_pushliteral(L, " (");
          lua_pushstring(L, msg2);
          lua_pushliteral(L, ")");
          lua_concat(L, 4);
          ret = 2;
        }
    }
    ldap_memfree(mdn);
    ldap_memfree(msg1);
    return ret;
  }
}
예제 #6
0
static gboolean
on_connect_bind_completed (LDAPMessage *result,
                           gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_connect_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data));
	LDAPServerInfo *sinfo;
	GError *error = NULL;
	char *message;
	int ldap_op;
	int code;
	int rc;

	g_return_val_if_fail (ldap_msgtype (result) == LDAP_RES_BIND, FALSE);

	/* The result of the bind operation */
	rc = ldap_parse_result (closure->ldap, result, &code, NULL, &message, NULL, NULL, 0);
	g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE);
	ldap_memfree (message);

	if (seahorse_ldap_source_propagate_error (self, rc, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete_in_idle (res);
		return FALSE; /* don't call this callback again */
	}

	/* Check if we need server info */
	sinfo = get_ldap_server_info (self, FALSE);
	if (sinfo != NULL) {
		g_simple_async_result_complete_in_idle (res);
		seahorse_progress_end (closure->cancellable, res);
		return FALSE; /* don't call this callback again */
	}

	/* Retrieve the server info */
	rc = ldap_search_ext (closure->ldap, "cn=PGPServerInfo", LDAP_SCOPE_BASE,
	                      "(objectclass=*)", (char **)SERVER_ATTRIBUTES, 0,
	                      NULL, NULL, NULL, 0, &ldap_op);

	if (seahorse_ldap_source_propagate_error (self, rc, &error)) {
		g_simple_async_result_take_error (res, error);
		g_simple_async_result_complete_in_idle (res);
		return FALSE; /* don't call this callback again */

	} else {
		GSource *gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op,
		                                              closure->cancellable);
		g_source_set_callback (gsource, (GSourceFunc)on_connect_server_info_completed,
		                       g_object_ref (res), g_object_unref);
		g_source_attach (gsource, g_main_context_default ());
		g_source_unref (gsource);
	}

	return FALSE; /* don't call this callback again */
}
예제 #7
0
/* deprecated */
int
ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
{
	int rc, err;

	rc = ldap_parse_result( ld, r, &err,
		NULL, NULL, NULL, NULL, freeit );

	return err != LDAP_SUCCESS ? err : rc;
}
예제 #8
0
static gboolean
on_search_search_completed (LDAPMessage *result,
                            gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_search_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data));
	GError *error = NULL;
	char *message;
	int code;
	int type;
	int rc;

	type = ldap_msgtype (result);
	g_return_val_if_fail (type == LDAP_RES_SEARCH_ENTRY || type == LDAP_RES_SEARCH_RESULT, FALSE);

	/* An LDAP entry */
	if (type == LDAP_RES_SEARCH_ENTRY) {
		g_debug ("Retrieved Key Entry");
#ifdef WITH_DEBUG
		dump_ldap_entry (closure->ldap, result);
#endif

		search_parse_key_from_ldap_entry (self, closure->results,
		                                  closure->ldap, result);
		return TRUE; /* keep calling this callback */

	/* All entries done */
	} else {
		rc = ldap_parse_result (closure->ldap, result, &code, NULL,
		                        &message, NULL, NULL, 0);
		g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE);

		/* Error codes that we ignore */
		switch (code) {
		case LDAP_SIZELIMIT_EXCEEDED:
			code = LDAP_SUCCESS;
			break;
		};

		/* Failure */
		if (code != LDAP_SUCCESS)
			g_simple_async_result_set_error (res, LDAP_ERROR_DOMAIN,
			                                 code, "%s", message);
		else if (seahorse_ldap_source_propagate_error (self, code, &error))
			g_simple_async_result_take_error (res, error);

		ldap_memfree (message);
		seahorse_progress_end (closure->cancellable, res);
		g_simple_async_result_complete (res);
		return FALSE;
	}
}
예제 #9
0
static int ipa_ldap_extended_op(LDAP *ld, const char *reqoid,
                                struct berval *control,
                                LDAPControl ***srvctrl)
{
    struct berval *retdata = NULL;
    LDAPMessage *res = NULL;
    char *retoid = NULL;
    struct timeval tv;
    char *err = NULL;
    int msgid;
    int ret, rc;

    ret = ldap_extended_operation(ld, reqoid, control,
                                  NULL, NULL, &msgid);
    if (ret != LDAP_SUCCESS) {
        fprintf(stderr, _("Operation failed: %s\n"), ldap_err2string(ret));
        return ret;
    }

    /* wait max 100 secs for the answer */
    tv.tv_sec = 100;
    tv.tv_usec = 0;
    ret = ldap_result(ld, msgid, 1, &tv, &res);
    if (ret == -1) {
        fprintf(stderr, _("Failed to get result: %s\n"), ldap_err2string(ret));
        goto done;
    }
    else if (res == NULL) {
        fprintf(stderr, _("Timeout exceeded."));
        goto done;
    }

    ret = ldap_parse_extended_result(ld, res, &retoid, &retdata, 0);
    if (ret != LDAP_SUCCESS) {
        fprintf(stderr, _("Failed to parse extended result: %s\n"),
                        ldap_err2string(ret));
        goto done;
    }

    ret = ldap_parse_result(ld, res, &rc, NULL, &err, NULL, srvctrl, 0);
    if (ret != LDAP_SUCCESS || rc != LDAP_SUCCESS) {
        fprintf(stderr, _("Failed to parse result: %s\n"),
                        err ? err : ldap_err2string(ret));
        if (ret == LDAP_SUCCESS) ret = rc;
        goto done;
    }

done:
    if (err) ldap_memfree(err);
    if (res) ldap_msgfree(res);
    return ret;
}
예제 #10
0
static gboolean
on_connect_server_info_completed (LDAPMessage *result,
                                  gpointer user_data)
{
	GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
	source_connect_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
	SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data));
	LDAPServerInfo *sinfo;
	char *message;
	int code;
	int type;
	int rc;

	type = ldap_msgtype (result);
	g_return_val_if_fail (type == LDAP_RES_SEARCH_ENTRY || type == LDAP_RES_SEARCH_RESULT, FALSE);

	/* If we have results then fill in the server info */
	if (type == LDAP_RES_SEARCH_ENTRY) {

		g_debug ("Server Info Result");
#ifdef WITH_DEBUG
		dump_ldap_entry (closure->ldap, result);
#endif

		/* NOTE: When adding attributes here make sure to add them to kServerAttributes */
		sinfo = g_new0 (LDAPServerInfo, 1);
		sinfo->version = get_int_attribute (closure->ldap, result, "version");
		sinfo->base_dn = get_string_attribute (closure->ldap, result, "basekeyspacedn");
		if (!sinfo->base_dn)
			sinfo->base_dn = get_string_attribute (closure->ldap, result, "pgpbasekeyspacedn");
		sinfo->key_attr = g_strdup (sinfo->version > 1 ? "pgpkeyv2" : "pgpkey");
		set_ldap_server_info (self, sinfo);

		return TRUE; /* callback again */

	} else {
		rc = ldap_parse_result (closure->ldap, result, &code, NULL,
		                        &message, NULL, NULL, 0);
		g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE);

		if (code != LDAP_SUCCESS)
			g_warning ("operation to get LDAP server info failed: %s", message);

		ldap_memfree (message);

		g_simple_async_result_complete_in_idle (res);
		seahorse_progress_end (closure->cancellable, res);
		return FALSE; /* don't callback again */
	}
}
예제 #11
0
static int
nsldapi_sasl_bind_s(
    LDAP                *ld,
    const char          *dn,
    const char          *mechanism,
    const struct berval *cred,
    LDAPControl         **serverctrls,
    LDAPControl         **clientctrls,
    struct berval       **servercredp,
    LDAPControl         ***responsectrls
)
{
        int             err, msgid;
        LDAPMessage     *result;

        LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_sasl_bind_s\n", 0, 0, 0 );

        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
                return( LDAP_PARAM_ERROR );
        }

        if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
                LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
                return( LDAP_NOT_SUPPORTED );
        }

        if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
            clientctrls, &msgid )) != LDAP_SUCCESS )
                return( err );

        if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
                return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );

        /* Get the controls sent by the server if requested */
        if ( responsectrls ) {
                if ( ( err = ldap_parse_result( ld, result, &err, NULL, NULL,
                       NULL, responsectrls, 0 )) != LDAP_SUCCESS )
                    return( err );
        }

        err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 );
        if (err != LDAP_SUCCESS  && err != LDAP_SASL_BIND_IN_PROGRESS) {
                ldap_msgfree( result );
                return( err );
        }

        return( ldap_result2error( ld, result, 1 ) );
}
예제 #12
0
/*
** Get the result message of an operation.
** #1 upvalue == connection
** #2 upvalue == msgid
** #3 upvalue == result code of the message (ADD, DEL etc.) to be received.
*/
static int result_message (lua_State *L) {
	struct timeval *timeout = NULL; /* ??? function parameter ??? */
	LDAPMessage *res;
	int rc;
	conn_data *conn = (conn_data *)lua_touserdata (L, lua_upvalueindex (1));
	int msgid = (int)lua_tonumber (L, lua_upvalueindex (2));
	/*int res_code = (int)lua_tonumber (L, lua_upvalueindex (3));*/

	luaL_argcheck (L, conn->ld, 1, LUALDAP_PREFIX"LDAP connection is closed");
	rc = ldap_result (conn->ld, msgid, LDAP_MSG_ONE, timeout, &res);
	if (rc == 0)
		return faildirect (L, LUALDAP_PREFIX"result timeout expired");
	else if (rc < 0) {
		ldap_msgfree (res);
		return faildirect (L, LUALDAP_PREFIX"result error");
	} else {
		int err, ret = 1;
		char *mdn, *msg;
		rc = ldap_parse_result (conn->ld, res, &err, &mdn, &msg, NULL, NULL, 1);
		if (rc != LDAP_SUCCESS)
			return faildirect (L, ldap_err2string (rc));
		switch (err) {
			case LDAP_SUCCESS:
			case LDAP_COMPARE_TRUE:
				lua_pushboolean (L, 1);
				break;
			case LDAP_COMPARE_FALSE:
				lua_pushboolean (L, 0);
				break;
			default:
				lua_pushnil (L);
				lua_pushliteral (L, LUALDAP_PREFIX);
				lua_pushstring (L, msg);
				lua_pushliteral (L, " ");
				lua_pushstring (L, ldap_err2string(err));
				lua_concat (L, 4);
				ret = 2;
		}
		ldap_memfree (mdn);
		ldap_memfree (msg);
		return ret;
	}
}
예제 #13
0
파일: error.c 프로젝트: howard5888/wineT
/***********************************************************************
 *      ldap_result2error     (WLDAP32.@)
 *
 * Parse an LDAP message and return the error obtained from it.
 *
 * PARAMS
 *  ld    [I] Pointer to an LDAP context.
 *  res   [I] Pointer to an LDAPMessage structure.
 *  free  [I] Ask for the LDAPMessage structure to be freed.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  If not asked for, use ldap_msgfree to free the LDAPMessage.
 */
ULONG CDECL WLDAP32_ldap_result2error( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res, ULONG free )
{
    ULONG ret = LDAP_NOT_SUPPORTED;
#ifdef HAVE_LDAP
    int error;

    TRACE( "(%p, %p, 0x%08lx)\n", ld, res, free );

    if (!ld || !res) return ~0UL;

    ret = ldap_parse_result( ld, res, &error, NULL, NULL, NULL, NULL, free );

    if (ret == LDAP_SUCCESS)
        ret = error;
    else
        ret = ~0UL;

#endif
    return ret;
}
예제 #14
0
파일: eldap.c 프로젝트: hroptatyr/sxemacs
static void signal_ldap_error(LDAP * ld, LDAPMessage * res, int ldap_err)
{
	if (ldap_err <= 0) {
#if defined HAVE_LDAP_PARSE_RESULT
		int err;
		ldap_err = ldap_parse_result(ld, res,
					     &err, NULL, NULL, NULL, NULL, 0);
		if (ldap_err == LDAP_SUCCESS)
			ldap_err = err;
#elif defined HAVE_LDAP_GET_LDERRNO
		ldap_err = ldap_get_lderrno(ld, NULL, NULL);
#elif defined HAVE_LDAP_RESULT2ERROR
		ldap_err = ldap_result2error(ld, res, 0);
#else
		ldap_err = ld->ld_errno;
#endif
	}
	signal_simple_error("LDAP error",
			    build_string(ldap_err2string(ldap_err)));
}
예제 #15
0
/// connects and binds to LDAP server
/// @param[in] ld    refernce to LDAP socket data
/// @param[in] cnf   reference to common configuration struct
int ldaputils_search(LDAP * ld, LdapUtilsConfig * cnf, LDAPMessage ** resp)
{
   int rc;
   int err;
   int msgid;

   if ((err = ldap_search_ext(ld, cnf->basedn, cnf->scope, cnf->filter, cnf->attrs, 0, NULL, NULL, NULL, -1, &msgid)))
   {
      fprintf(stderr, "%s: ldap_search_ext_s(): %s\n", PROGRAM_NAME, ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(-1);
   };

   switch((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, resp)))
   {
      case 0:
         break;
      case -1:
         fprintf(stderr, "%s: ldap_result(): %s\n", PROGRAM_NAME, ldap_err2string(err));
         ldap_unbind_ext_s(ld, NULL, NULL);
         return(-1);
      default:
         break;
   };

   rc = ldap_parse_result(ld, *resp, &err, NULL, NULL, NULL, NULL, 0);
   if (rc != LDAP_SUCCESS)
   {
      fprintf(stderr, "%s: ldap_parse_result(): %s\n", PROGRAM_NAME, ldap_err2string(rc));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(-1);
   };
   if (err != LDAP_SUCCESS)
   {
      fprintf(stderr, "%s: ldap_parse_result(): %s\n", PROGRAM_NAME, ldap_err2string(err));
      ldap_unbind_ext_s(ld, NULL, NULL);
      return(-1);
   };
   
   return(0);
}
예제 #16
0
static int verify_op_success(LDAP *l, char *reason, LDAPMessage *messages)
{
  int rc, erc;
  char *errmsg;

  rc = ldap_parse_result(l, messages, &erc, NULL, &errmsg,
			 NULL, NULL, 0);
  if (rc != LDAP_SUCCESS) {
    prtmsg("Failed to %s (parse_result): %s", reason, ldap_err2string(rc));
    return 0;
  }
  if (erc != LDAP_SUCCESS) {
    prtmsg("Failed to %s (server response): %s%s%s", reason, ldap_err2string(erc),
	   (errmsg?", ":""), (errmsg?errmsg:""));
    if (errmsg)
      ldap_memfree(errmsg);
    return 0;
  }
  if (errmsg)
    ldap_memfree(errmsg);
  return 1;
}
예제 #17
0
/* wrappers to some depricated functions */
static void
ldaplookup_parse_result (
	LDAP *ld,
	LDAPMessage *res
) {
	static const int freeit = 0;
	int result;
#ifdef HAVE_LDAP_PARSE_RESULT
	int ret;
	char *matcheddn;
	char *errmsg;

	ret = ldap_parse_result(ld, res, &result, &matcheddn, &errmsg, NULL, NULL, freeit);
	if (ret == LDAP_SUCCESS) {
		if (errmsg) ERR_add_error_data(1, errmsg);
	}
	if (matcheddn) ldap_memfree(matcheddn);
	if (errmsg)    ldap_memfree(errmsg);
#else
	result = ldap_result2error(ld, res, freeit);
	openssl_add_ldap_error(result);
#endif
}
예제 #18
0
int ldap_compare_ext_s(LDAP *ld, char *dn, char *attr, struct berval *bvalue,
					   LDAPControl ** serverctrls, LDAPControl **clientctrls)
{
	int		msgid, retcode = LDAP_SUCCESS;
	LDAPMessage	*res;

	if ( (retcode = ldap_compare_ext( ld, dn, attr, bvalue, serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS )
		return( retcode );

	if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
		return( ld->ld_errno );

#ifdef _REENTRANT
	LOCK_LDAP(ld);
#endif
	retcode = ldap_parse_result( ld, res,  &ld->ld_errno, &ld->ld_matched, &ld->ld_error,
								 &ld->ld_referrals, &ld->ld_ret_ctrls, 1);
	if (retcode == LDAP_SUCCESS)
		retcode = ld->ld_errno;
#ifdef _REENTRANT
	UNLOCK_LDAP(ld);
#endif
	return (retcode);
}
예제 #19
0
파일: ldap.cpp 프로젝트: monnerat/undervest
extern "C" std::string
getRecipient(void * vh, Source * source)

{
	ldap_handle * h = (ldap_handle *) vh;
	int msgtype;
	int code;
	int rc;
	struct berval bv;
	std::string result;

	if (!h)
		return "";

	for (;;) {
		if (h->value && h->value->bv_val) {
			result = std::string(h->value->bv_val,
			    h->value->bv_len);
			h->value++;

			if (result.length() > 5 &&
			    !strncasecmp(result.c_str(), "smtp:", 5))
				result = result.substr(5);

			if (result.find_first_not_of(mailchars) !=
			    std::string::npos)
				continue;

			return result;
			}

		if (h->ber) {
			rc = ldap_get_attribute_ber(h->ldap, h->msg, h->ber,
			    &bv, &h->values);
			h->value = h->values;

			if (rc == LDAP_SUCCESS && bv.bv_val)
				continue;
			}

		h->release_message();

		rc = ldap_result(h->ldap,
		    LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &h->msg);

		if (!h->msg)
			throw ldap_error(rc);

		msgtype = ldap_msgtype(h->msg);

		switch (msgtype) {

		case LDAP_RES_SEARCH_RESULT:
			rc = ldap_parse_result(h->ldap, h->msg, &code,
			    NULL, NULL, NULL, NULL, 0);

			if (rc != LDAP_SUCCESS)
				throw ldap_error(rc);

			if (code != LDAP_SUCCESS)
				throw ldap_error(code);

			return "";

		case LDAP_RES_SEARCH_ENTRY:
			break;

		default:
			continue;
			}

		rc = ldap_get_dn_ber(h->ldap, h->msg, &h->ber, &bv);

		if (rc != LDAP_SUCCESS)
			throw ldap_error(rc);
		}

	return "";
}
예제 #20
0
static int domodrdn(
    LDAP	*ld,
    char	*dn,
    char	*rdn,
    char	*newSuperior,
    int		remove ) /* flag: remove old RDN */
{
    int rc, code, id;
    char *matcheddn=NULL, *text=NULL, **refs=NULL;
    LDAPMessage *res;

    if ( verbose ) {
        printf( "Renaming \"%s\"\n", dn );
        printf( "\tnew rdn=\"%s\" (%s old rdn)\n",
                rdn, remove ? "delete" : "keep" );
        if( newSuperior != NULL ) {
            printf("\tnew parent=\"%s\"\n", newSuperior);
        }
    }

    if( not ) return LDAP_SUCCESS;

    rc = ldap_rename( ld, dn, rdn, newSuperior, remove,
                      NULL, NULL, &id );

    if ( rc != LDAP_SUCCESS ) {
        fprintf( stderr, "%s: ldap_rename: %s (%d)\n",
                 prog, ldap_err2string( rc ), rc );
        return rc;
    }

    rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
    if ( rc < 0 ) {
        ldap_perror( ld, "ldapmodrdn: ldap_result" );
        return rc;
    }

    rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 );

    if( rc != LDAP_SUCCESS ) {
        fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
                 prog, ldap_err2string( rc ), rc );
        return rc;
    }

    if( verbose || code != LDAP_SUCCESS ||
            (matcheddn && *matcheddn) || (text && *text) || (refs && *refs) )
    {
        printf( "Rename Result: %s (%d)\n",
                ldap_err2string( code ), code );

        if( text && *text ) {
            printf( "Additional info: %s\n", text );
        }

        if( matcheddn && *matcheddn ) {
            printf( "Matched DN: %s\n", matcheddn );
        }

        if( refs ) {
            int i;
            for( i=0; refs[i]; i++ ) {
                printf("Referral: %s\n", refs[i] );
            }
        }
    }

    ber_memfree( text );
    ber_memfree( matcheddn );
    ber_memvfree( (void **) refs );

    return code;
}
예제 #21
0
파일: ldap_sync.c 프로젝트: Leeios/NodeJS
/*
 * handle the LDAP_RES_SEARCH_RESULT response
 */
static int
ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
{
	int		err;
	char		*matched = NULL,
			*msg = NULL;
	LDAPControl	**ctrls = NULL;
	int		rc;
	int		refreshDeletes = -1;

#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "\tgot LDAP_RES_SEARCH_RESULT\n" );
#endif /* LDAP_SYNC_TRACE */

	assert( ls != NULL );
	assert( res != NULL );

	/* should not happen in refreshAndPersist... */
	rc = ldap_parse_result( ls->ls_ld,
		res, &err, &matched, &msg, NULL, &ctrls, 0 );
#ifdef LDAP_SYNC_TRACE
	fprintf( stderr,
		"\tldap_parse_result(%d, \"%s\", \"%s\") == %d\n",
		err,
		matched ? matched : "",
		msg ? msg : "",
		rc );
#endif /* LDAP_SYNC_TRACE */
	if ( rc == LDAP_SUCCESS ) {
		rc = err;
	}

	ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;

	switch ( rc ) {
	case LDAP_SUCCESS: {
		int		i;
		BerElement	*ber = NULL;
		ber_len_t	len;
		struct berval	cookie = { 0 };

		rc = LDAP_OTHER;

		/* deal with control; then fallthru to handler */
		if ( ctrls == NULL ) {
			goto done;
		}

		/* lookup the sync state control */
		for ( i = 0; ctrls[ i ] != NULL; i++ ) {
			if ( strcmp( ctrls[ i ]->ldctl_oid,
				LDAP_CONTROL_SYNC_DONE ) == 0 )
			{
				break;
			}
		}

		/* control must be present; there might be other... */
		if ( ctrls[ i ] == NULL ) {
			goto done;
		}

		/* extract data */
		ber = ber_init( &ctrls[ i ]->ldctl_value );
		if ( ber == NULL ) {
			goto done;
		}

		if ( ber_scanf( ber, "{" /*"}"*/) == LBER_ERROR ) {
			goto ber_done;
		}
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
			if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
				goto ber_done;
			}
			if ( cookie.bv_val != NULL ) {
				ber_bvreplace( &ls->ls_cookie, &cookie );
			}
#ifdef LDAP_SYNC_TRACE
			fprintf( stderr, "\t\tgot cookie=%s\n",
				cookie.bv_val ? cookie.bv_val : "(null)" );
#endif /* LDAP_SYNC_TRACE */
		}

		refreshDeletes = 0;
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
			if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) {
				goto ber_done;
			}
			if ( refreshDeletes ) {
				refreshDeletes = 1;
			}
		}

		if ( ber_scanf( ber, /*"{"*/ "}" ) != LBER_ERROR ) {
			rc = LDAP_SUCCESS;
		}

	ber_done:;
		ber_free( ber, 1 );
		if ( rc != LDAP_SUCCESS ) {
			break;
		}

#ifdef LDAP_SYNC_TRACE
		fprintf( stderr, "\t\tgot refreshDeletes=%s\n",
			refreshDeletes ? "TRUE" : "FALSE" );
#endif /* LDAP_SYNC_TRACE */

		/* FIXME: what should we do with the refreshDelete? */
		switch ( refreshDeletes ) {
		case 0:
			ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS;
			break;

		default:
			ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES;
			break;
		}

		} /* fallthru */

	case LDAP_SYNC_REFRESH_REQUIRED:
		/* TODO: check for Sync Done Control */
		/* FIXME: perhaps the handler should be called
		 * also in case of failure; we'll deal with this
		 * later when implementing refreshOnly */
		if ( ls->ls_search_result ) {
			err = ls->ls_search_result( ls, res, refreshDeletes );
		}
		break;
	}

done:;
	if ( matched != NULL ) {
		ldap_memfree( matched );
	}

	if ( msg != NULL ) {
		ldap_memfree( msg );
	}

	if ( ctrls != NULL ) {
		ldap_controls_free( ctrls );
	}

	ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;

	return rc;
}
예제 #22
0
/** 
 * Initializes a message.
 *
 * @param aConnection           The nsLDAPConnection this message is on
 * @param aMsgHandle            The native LDAPMessage to be wrapped.
 * 
 * @exception NS_ERROR_ILLEGAL_VALUE        null pointer passed in
 * @exception NS_ERROR_UNEXPECTED           internal err; shouldn't happen
 * @exception NS_ERROR_LDAP_DECODING_ERROR  problem during BER decoding
 * @exception NS_ERROR_OUT_OF_MEMORY        ran out of memory
 */
nsresult 
nsLDAPMessage::Init(nsILDAPConnection *aConnection, LDAPMessage *aMsgHandle)
{
    int parseResult; 

    if (!aConnection || !aMsgHandle) {
        NS_WARNING("Null pointer passed in to nsLDAPMessage::Init()");
        return NS_ERROR_ILLEGAL_VALUE;
    }

    // initialize the appropriate member vars
    //
    mConnection = aConnection;
    mMsgHandle = aMsgHandle;

    // cache the connection handle.  we're violating the XPCOM type-system
    // here since we're a friend of the connection class and in the 
    // same module.
    //
    mConnectionHandle = static_cast<nsLDAPConnection *>(aConnection)->mConnectionHandle;

    // do any useful message parsing
    //
    const int msgType = ldap_msgtype(mMsgHandle);
    if ( msgType == -1) {
        NS_ERROR("nsLDAPMessage::Init(): ldap_msgtype() failed");
        return NS_ERROR_UNEXPECTED;
    }

    switch (msgType) {

    case LDAP_RES_SEARCH_REFERENCE:
        // XXX should do something here?
        break;

    case LDAP_RES_SEARCH_ENTRY:
        // nothing to do here
        break;

    case LDAP_RES_EXTENDED:
        // XXX should do something here?
        break;

    case LDAP_RES_BIND:
    case LDAP_RES_SEARCH_RESULT:
    case LDAP_RES_MODIFY:
    case LDAP_RES_ADD:
    case LDAP_RES_DELETE:
    case LDAP_RES_MODRDN:
    case LDAP_RES_COMPARE:
        parseResult = ldap_parse_result(mConnectionHandle, 
                                        mMsgHandle, &mErrorCode, &mMatchedDn,
                                        &mErrorMessage,&mReferrals, 
                                        &mServerControls, 0);
        switch (parseResult) {
        case LDAP_SUCCESS: 
            // we're good
            break;

        case LDAP_DECODING_ERROR:
            NS_WARNING("nsLDAPMessage::Init(): ldap_parse_result() hit a "
                       "decoding error");
            return NS_ERROR_LDAP_DECODING_ERROR;

        case LDAP_NO_MEMORY:
            NS_WARNING("nsLDAPMessage::Init(): ldap_parse_result() ran out " 
                       "of memory");
            return NS_ERROR_OUT_OF_MEMORY;

        case LDAP_PARAM_ERROR:
        case LDAP_MORE_RESULTS_TO_RETURN:
        case LDAP_NO_RESULTS_RETURNED:
        default:
            NS_ERROR("nsLDAPMessage::Init(): ldap_parse_result returned "
                     "unexpected return code");
            return NS_ERROR_UNEXPECTED;
        }

        break;

    default:
        NS_ERROR("nsLDAPMessage::Init(): unexpected message type");
        return NS_ERROR_UNEXPECTED;
    }

    return NS_OK;
}
예제 #23
0
파일: ldap.c 프로젝트: Distrotech/mailutils
static int
_mu_ldap_bind (LDAP *ld)
{
  int msgid, err, rc;
  LDAPMessage *result;
  LDAPControl **ctrls;
  char msgbuf[256];
  char *matched = NULL;
  char *info = NULL;
  char **refs = NULL;
  static struct berval passwd;

  passwd.bv_val = ldap_param.passwd;
  passwd.bv_len = passwd.bv_val ? strlen (passwd.bv_val) : 0;


  msgbuf[0] = 0;

  rc = ldap_sasl_bind (ld, ldap_param.binddn, LDAP_SASL_SIMPLE, &passwd,
		       NULL, NULL, &msgid);
  if (msgid == -1)
    {
      mu_error ("ldap_sasl_bind(SIMPLE) failed: %s", ldap_err2string (rc));
      return 1;
    }

  if (ldap_result (ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1)
    {
      mu_error ("ldap_result failed");
      return 1;
    }

  rc = ldap_parse_result (ld, result, &err, &matched, &info, &refs,
			  &ctrls, 1);
  if (rc != LDAP_SUCCESS)
    {
      mu_error ("ldap_parse_result failed: %s", ldap_err2string (rc));
      return 1;
    }

  if (ctrls)
    ldap_controls_free (ctrls);

  if (err != LDAP_SUCCESS
      || msgbuf[0]
      || (matched && matched[0])
      || (info && info[0])
      || refs)
    {
      /* FIXME: Use debug output for that */
      mu_error ("ldap_bind: %s (%d)%s", ldap_err2string (err), err, msgbuf);

      if (matched && *matched) 
	mu_error ("matched DN: %s", matched);

      if (info && *info)
	mu_error ("additional info: %s", info);

      if (refs && *refs)
	{
	  int i;
	  mu_error ("referrals:");
	  for (i = 0; refs[i]; i++) 
	    mu_error ("%s", refs[i]);
	}

    }

  if (matched)
    ber_memfree (matched);
  if (info)
    ber_memfree (info);
  if (refs)
    ber_memvfree ((void **)refs);

  return err == LDAP_SUCCESS ? 0 : MU_ERR_FAILURE;
}
예제 #24
0
int
asyncmeta_handle_search_msg(LDAPMessage *res, a_metaconn_t *mc, bm_context_t *bc, int candidate)
{
	a_metainfo_t	*mi;
	a_metatarget_t	*mt;
	a_metasingleconn_t *msc;
	Operation *op = bc->op;
	SlapReply *rs;
	int	   i, rc = LDAP_SUCCESS, sres;
	SlapReply *candidates;
	char		**references = NULL;
	LDAPControl	**ctrls = NULL;
	a_dncookie dc;
	LDAPMessage *msg;
	ber_int_t id;

	rs = &bc->rs;
	mi = mc->mc_info;
	mt = mi->mi_targets[ candidate ];
	msc = &mc->mc_conns[ candidate ];
	dc.op = op;
	dc.target = mt;
	dc.to_from = MASSAGE_REP;
	id = ldap_msgid(res);


	candidates = bc->candidates;
	i = candidate;

	while (res && !META_BACK_CONN_INVALID(msc)) {
	for (msg = ldap_first_message(msc->msc_ldr, res); msg; msg = ldap_next_message(msc->msc_ldr, msg)) {
		switch(ldap_msgtype(msg)) {
		case LDAP_RES_SEARCH_ENTRY:
			Debug( LDAP_DEBUG_TRACE,
				"%s asyncmeta_handle_search_msg: msc %p entry\n",
				op->o_log_prefix, msc );
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			/* count entries returned by target */
			candidates[ i ].sr_nentries++;
			if (bc->c_peer_name.bv_val == op->o_conn->c_peer_name.bv_val && !op->o_abandon) {
				rs->sr_err = asyncmeta_send_entry( &bc->copy_op, rs, mc, i, msg );
			} else {
				goto err_cleanup;
			}
			switch ( rs->sr_err ) {
			case LDAP_SIZELIMIT_EXCEEDED:
				asyncmeta_send_ldap_result(bc, op, rs);
				rs->sr_err = LDAP_SUCCESS;
				goto err_cleanup;
			case LDAP_UNAVAILABLE:
				rs->sr_err = LDAP_OTHER;
				break;
			default:
				break;
			}
			bc->is_ok++;
			break;

		case LDAP_RES_SEARCH_REFERENCE:
			if ( META_BACK_TGT_NOREFS( mt ) ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;
			rc = ldap_parse_reference( msc->msc_ldr, msg,
				   &references, &rs->sr_ctrls, 0 );

			if ( rc != LDAP_SUCCESS || references == NULL ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			/* FIXME: merge all and return at the end */

			{
				int cnt;
				for ( cnt = 0; references[ cnt ]; cnt++ )
					;

				rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

				for ( cnt = 0; references[ cnt ]; cnt++ ) {
					ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ],
							  op->o_tmpmemctx );
				}
				BER_BVZERO( &rs->sr_ref[ cnt ] );
			}

			{
				dc.memctx = op->o_tmpmemctx;
				( void )asyncmeta_referral_result_rewrite( &dc, rs->sr_ref );
			}

			if ( rs->sr_ref != NULL ) {
				if (!BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {
					/* ignore return value by now */
					( void )send_search_reference( op, rs );
				}

				ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx );
				rs->sr_ref = NULL;
			}

			/* cleanup */
			if ( references ) {
				ber_memvfree( (void **)references );
			}

			if ( rs->sr_ctrls ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_INTERMEDIATE:
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;

			/* FIXME: response controls
			 * are passed without checks */
			rs->sr_err = ldap_parse_intermediate( msc->msc_ldr,
								  msg,
								  (char **)&rs->sr_rspoid,
								  &rs->sr_rspdata,
								  &rs->sr_ctrls,
								  0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_type = REP_RESULT;
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			slap_send_ldap_intermediate( op, rs );

			if ( rs->sr_rspoid != NULL ) {
				ber_memfree( (char *)rs->sr_rspoid );
				rs->sr_rspoid = NULL;
			}

			if ( rs->sr_rspdata != NULL ) {
				ber_bvfree( rs->sr_rspdata );
				rs->sr_rspdata = NULL;
			}

			if ( rs->sr_ctrls != NULL ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_SEARCH_RESULT:
			if ( mi->mi_idle_timeout != 0 ) {
				asyncmeta_set_msc_time(msc);
			}
			Debug( LDAP_DEBUG_TRACE,
			       "%s asyncmeta_handle_search_msg: msc %p result\n",
			       op->o_log_prefix, msc );
			candidates[ i ].sr_type = REP_RESULT;
			candidates[ i ].sr_msgid = META_MSGID_IGNORE;
			/* NOTE: ignores response controls
			 * (and intermediate response controls
			 * as well, except for those with search
			 * references); this may not be correct,
			 * but if they're not ignored then
			 * back-meta would need to merge them
			 * consistently (think of pagedResults...)
			 */
			/* FIXME: response controls? */
			rs->sr_err = ldap_parse_result( msc->msc_ldr,
							msg,
							&candidates[ i ].sr_err,
								(char **)&candidates[ i ].sr_matched,
							(char **)&candidates[ i ].sr_text,
							&references,
							&ctrls /* &candidates[ i ].sr_ctrls (unused) */ ,
							0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_err = rs->sr_err;
				sres = slap_map_api2result( &candidates[ i ] );
				candidates[ i ].sr_type = REP_RESULT;
				goto finish;
			}

			rs->sr_err = candidates[ i ].sr_err;

			/* massage matchedDN if need be */
			if ( candidates[ i ].sr_matched != NULL ) {
				struct berval	match, mmatch;

				ber_str2bv( candidates[ i ].sr_matched,
						0, 0, &match );
				candidates[ i ].sr_matched = NULL;

				dc.memctx = NULL;
				asyncmeta_dn_massage( &dc, &match, &mmatch );
				if ( mmatch.bv_val == match.bv_val ) {
					candidates[ i ].sr_matched
						= ch_strdup( mmatch.bv_val );

				} else {
					candidates[ i ].sr_matched = mmatch.bv_val;
				}

				bc->candidate_match++;
				ldap_memfree( match.bv_val );
			}

			/* add references to array */
			/* RFC 4511: referrals can only appear
			 * if result code is LDAP_REFERRAL */
			if ( references != NULL
				 && references[ 0 ] != NULL
				 && references[ 0 ][ 0 ] != '\0' )
			{
				if ( rs->sr_err != LDAP_REFERRAL ) {
					Debug( LDAP_DEBUG_ANY,
						   "%s asncmeta_search_result[%d]: "
						   "got referrals with err=%d\n",
						   op->o_log_prefix,
						   i, rs->sr_err );

				} else {
					BerVarray	sr_ref;
					int		cnt;

					for ( cnt = 0; references[ cnt ]; cnt++ )
						;

					sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

					for ( cnt = 0; references[ cnt ]; cnt++ ) {
						ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ],
								  op->o_tmpmemctx );
					}
					BER_BVZERO( &sr_ref[ cnt ] );

					dc.memctx = op->o_tmpmemctx;
					( void )asyncmeta_referral_result_rewrite( &dc, sr_ref );

					if ( rs->sr_v2ref == NULL ) {
						rs->sr_v2ref = sr_ref;

					} else {
						for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {
							ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ],
									   op->o_tmpmemctx );
						}
						ber_memfree_x( sr_ref, op->o_tmpmemctx );
					}
				}

			} else if ( rs->sr_err == LDAP_REFERRAL ) {
				Debug( LDAP_DEBUG_TRACE,
					   "%s asyncmeta_search_result[%d]: "
					   "got err=%d with null "
					   "or empty referrals\n",
					   op->o_log_prefix,
					   i, rs->sr_err );

				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}

			/* cleanup */
			ber_memvfree( (void **)references );

			sres = slap_map_api2result( rs );

			if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
				       (long) candidates[ i ].sr_err );
			} else {
					Debug( LDAP_DEBUG_ANY,  "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld (%s)",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
					       (long) candidates[ i ].sr_err, ldap_err2string( candidates[ i ].sr_err ) );
			}

			switch ( sres ) {
			case LDAP_NO_SUCH_OBJECT:
				/* is_ok is touched any time a valid
				 * (even intermediate) result is
				 * returned; as a consequence, if
				 * a candidate returns noSuchObject
				 * it is ignored and the candidate
				 * is simply demoted. */
				if ( bc->is_ok ) {
					sres = LDAP_SUCCESS;
				}
				break;

			case LDAP_SUCCESS:
				if ( ctrls != NULL && ctrls[0] != NULL ) {
#ifdef SLAPD_META_CLIENT_PR
					LDAPControl *pr_c;

					pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
					if ( pr_c != NULL ) {
						BerElementBuffer berbuf;
						BerElement *ber = (BerElement *)&berbuf;
						ber_tag_t tag;
						ber_int_t prsize;
						struct berval prcookie;

						/* unsolicited, do not accept */
						if ( mt->mt_ps == 0 ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER );

						tag = ber_scanf( ber, "{im}", &prsize, &prcookie );
						if ( tag == LBER_ERROR ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						/* more pages? new search request */
						if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) {
							if ( mt->mt_ps > 0 ) {
								/* ignore size if specified */
								prsize = 0;

							} else if ( prsize == 0 ) {
								/* guess the page size from the entries returned so far */
								prsize = candidates[ i ].sr_nentries;
							}

							candidates[ i ].sr_nentries = 0;
							candidates[ i ].sr_msgid = META_MSGID_IGNORE;
							candidates[ i ].sr_type = REP_INTERMEDIATE;

							assert( candidates[ i ].sr_matched == NULL );
							assert( candidates[ i ].sr_text == NULL );
							assert( candidates[ i ].sr_ref == NULL );

							switch ( asyncmeta_back_search_start( &bc->copy_op, rs, mc, bc, i, &prcookie, prsize, 1 ) )
							{
							case META_SEARCH_CANDIDATE:
								assert( candidates[ i ].sr_msgid >= 0 );
								ldap_controls_free( ctrls );
								//	goto free_message;

							case META_SEARCH_ERR:
							case META_SEARCH_NEED_BIND:
err_pr:;
								candidates[ i ].sr_err = rs->sr_err;
								candidates[ i ].sr_type = REP_RESULT;
								if ( META_BACK_ONERR_STOP( mi ) ) {
									asyncmeta_send_ldap_result(bc, op, rs);
									ldap_controls_free( ctrls );
									goto err_cleanup;
								}
								/* fallthru */

							case META_SEARCH_NOT_CANDIDATE:
								/* means that asyncmeta_back_search_start()
								 * failed but onerr == continue */
								candidates[ i ].sr_msgid = META_MSGID_IGNORE;
								candidates[ i ].sr_type = REP_RESULT;
								break;

							default:
								/* impossible */
								assert( 0 );
								break;
							}
							break;
						}
					}
#endif /* SLAPD_META_CLIENT_PR */

					ldap_controls_free( ctrls );
				}
				/* fallthru */

			case LDAP_REFERRAL:
				bc->is_ok++;
				break;

			case LDAP_SIZELIMIT_EXCEEDED:
				/* if a target returned sizelimitExceeded
				 * and the entry count is equal to the
				 * proxy's limit, the target would have
				 * returned more, and the error must be
				 * propagated to the client; otherwise,
				 * the target enforced a limit lower
				 * than what requested by the proxy;
				 * ignore it */
				candidates[ i ].sr_err = rs->sr_err;
				if ( rs->sr_nentries == op->ors_slimit
					 || META_BACK_ONERR_STOP( mi ) )
				{
					const char *save_text;
got_err:
					save_text = rs->sr_text;
					rs->sr_text = candidates[ i ].sr_text;
					asyncmeta_send_ldap_result(bc, op, rs);
					if (candidates[ i ].sr_text != NULL) {
						ch_free( (char *)candidates[ i ].sr_text );
						candidates[ i ].sr_text = NULL;
					}
					rs->sr_text = save_text;
					ldap_controls_free( ctrls );
					goto err_cleanup;
				}
				break;

			default:
				candidates[ i ].sr_err = rs->sr_err;
				if ( META_BACK_ONERR_STOP( mi ) ) {
					goto got_err;
				}
				break;
			}
			/* if this is the last result we will ever receive, send it back  */
			rc = rs->sr_err;
			if (asyncmeta_is_last_result(mc, bc, i) == 0) {
				Debug( LDAP_DEBUG_TRACE,
					"%s asyncmeta_handle_search_msg: msc %p last result\n",
					op->o_log_prefix, msc );
				asyncmeta_search_last_result(mc, bc, i, sres);
err_cleanup:
				rc = rs->sr_err;
				ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
				asyncmeta_drop_bc( mc, bc);
				asyncmeta_clear_bm_context(bc);
				ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
				ldap_msgfree(res);
				return rc;
			}
finish:
			break;

		default:
			continue;
		}
	}
		ldap_msgfree(res);
		res = NULL;
		if (candidates[ i ].sr_type != REP_RESULT) {
			struct timeval	tv = {0};
			rc = ldap_result( msc->msc_ldr, id, LDAP_MSG_RECEIVED, &tv, &res );
			if (res != NULL) {
				msc->msc_result_time = slap_get_time();
			}
		}
	}
	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	bc->bc_active--;
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	return rc;
}
예제 #25
0
meta_search_candidate_t
asyncmeta_dobind_result(
	a_metaconn_t		*mc,
	int			candidate,
	SlapReply		*bind_result,
	LDAPMessage		*res )
{
	a_metainfo_t		*mi = mc->mc_info;
	a_metatarget_t		*mt = mi->mi_targets[ candidate ];
	a_metasingleconn_t	*msc = &mc->mc_conns[ candidate ];

	meta_search_candidate_t	retcode = META_SEARCH_NOT_CANDIDATE;
	int			rc;

	assert( msc->msc_ldr != NULL );

	if ( mi->mi_idle_timeout != 0 ) {
		asyncmeta_set_msc_time(msc);
	}

	if ( LogTest( asyncmeta_debug ) ) {
		char	time_buf[ SLAP_TEXT_BUFLEN ];
		asyncmeta_get_timestamp(time_buf);
		Debug( asyncmeta_debug, "[%x] [%s] asyncmeta_dobind_result msc: %p, "
		       "msc->msc_binding_time: %x, msc->msc_flags:%x\n ",
		       (unsigned int)slap_get_time(), time_buf, msc,
		       (unsigned int)msc->msc_binding_time, msc->msc_mscflags );
	}
	/* FIXME: matched? referrals? response controls? */
	rc = ldap_parse_result( msc->msc_ldr, res,
				&(bind_result->sr_err),
				(char **)&(bind_result->sr_matched),
				(char **)&(bind_result->sr_text),
				NULL, NULL, 0 );

	if ( LogTest( asyncmeta_debug ) ) {
		char	time_buf[ SLAP_TEXT_BUFLEN ];
		asyncmeta_get_timestamp(time_buf);
		Debug( asyncmeta_debug,
		       "[%s] asyncmeta_dobind_result error=%d msc: %p\n",
		       time_buf,bind_result->sr_err, msc );
	}

	if ( rc != LDAP_SUCCESS ) {
		bind_result->sr_err = rc;
	}
	rc = slap_map_api2result( bind_result );

	LDAP_BACK_CONN_BINDING_CLEAR( msc );
	if ( rc != LDAP_SUCCESS ) {
		bind_result->sr_err = rc;
	} else {
		/* FIXME: check if bound as idassert authcDN! */
		if ( BER_BVISNULL( &msc->msc_bound_ndn )
			|| BER_BVISEMPTY( &msc->msc_bound_ndn ) )
		{
			LDAP_BACK_CONN_ISANON_SET( msc );
			if ( LogTest( asyncmeta_debug ) ) {
				char	time_buf[ SLAP_TEXT_BUFLEN ];
				asyncmeta_get_timestamp(time_buf);
				Debug( asyncmeta_debug, "[%s] asyncmeta_dobind_result anonymous msc: %p\n",
				      time_buf, msc );
			}

		} else {
			if ( META_BACK_TGT_SAVECRED( mt ) &&
				!BER_BVISNULL( &msc->msc_cred ) &&
				!BER_BVISEMPTY( &msc->msc_cred ) )
			{
				ldap_set_rebind_proc( msc->msc_ldr, mt->mt_rebind_f, msc );
			}
			if ( LogTest( asyncmeta_debug ) ) {
				char	time_buf[ SLAP_TEXT_BUFLEN ];
				asyncmeta_get_timestamp(time_buf);
				Debug( asyncmeta_debug, "[%s] asyncmeta_dobind_result success msc: %p\n",
				      time_buf, msc );
			}
			LDAP_BACK_CONN_ISBOUND_SET( msc );
		}
		retcode = META_SEARCH_CANDIDATE;
	}
	return retcode;
}
예제 #26
0
파일: ldap_misc.c 프로젝트: Akasurde/krb5
/*
 * Get the number of times an object has been referred to in a realm.  This is
 * needed to find out if deleting the attribute will cause dangling links.
 *
 * An LDAP handle may be optionally specified to prevent race condition - there
 * are a limited number of LDAP handles.
 */
krb5_error_code
krb5_ldap_get_reference_count(krb5_context context, char *dn, char *refattr,
                              int *count, LDAP *ld)
{
    int n, st, tempst, gothandle = 0;
    unsigned int i, ntrees = 0;
    char *refcntattr[2];
    char *filter = NULL, *corrected = NULL, **subtree = NULL;
    kdb5_dal_handle *dal_handle = NULL;
    krb5_ldap_context *ldap_context = NULL;
    krb5_ldap_server_handle *ldap_server_handle = NULL;
    LDAPMessage *result = NULL;

    if (dn == NULL || refattr == NULL) {
        st = EINVAL;
        goto cleanup;
    }

    SETUP_CONTEXT();
    if (ld == NULL) {
        GET_HANDLE();
        gothandle = 1;
    }

    refcntattr[0] = refattr;
    refcntattr[1] = NULL;

    corrected = ldap_filter_correct(dn);
    if (corrected == NULL) {
        st = ENOMEM;
        goto cleanup;
    }

    if (asprintf(&filter, "%s=%s", refattr, corrected) < 0) {
        filter = NULL;
        st = ENOMEM;
        goto cleanup;
    }

    st = krb5_get_subtree_info(ldap_context, &subtree, &ntrees);
    if (st)
        goto cleanup;

    for (i = 0, *count = 0; i < ntrees; i++) {
        LDAP_SEARCH(subtree[i], LDAP_SCOPE_SUBTREE, filter, refcntattr);
        n = ldap_count_entries(ld, result);
        if (n == -1) {
            int ret, errcode = 0;
            ret = ldap_parse_result(ld, result, &errcode, NULL, NULL, NULL,
                                    NULL, 0);
            if (ret != LDAP_SUCCESS)
                errcode = ret;
            st = translate_ldap_error(errcode, OP_SEARCH);
            goto cleanup;
        }

        ldap_msgfree(result);
        result = NULL;

        *count += n;
    }

cleanup:
    free(filter);
    ldap_msgfree(result);
    for (i = 0; i < ntrees; i++)
        free(subtree[i]);
    free(subtree);
    free(corrected);
    if (gothandle)
        krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
    return st;
}
예제 #27
0
/*
 * always protected by conn_mutex
 * optionally protected by req_mutex and res_mutex
 */
LDAPConn *
ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb,
	int connect, LDAPreqinfo *bind, int m_req, int m_res )
{
	LDAPConn	*lc;
	int		async = 0;

	LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex );
	Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n",
		use_ldsb, connect, (bind != NULL) );
	/*
	 * make a new LDAP server connection
	 * XXX open connection synchronously for now
	 */
	lc = (LDAPConn *)LDAP_CALLOC( 1, sizeof( LDAPConn ) );
	if ( lc == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( NULL );
	}
	
	if ( use_ldsb ) {
		assert( ld->ld_sb != NULL );
		lc->lconn_sb = ld->ld_sb;

	} else {
		lc->lconn_sb = ber_sockbuf_alloc();
		if ( lc->lconn_sb == NULL ) {
			LDAP_FREE( (char *)lc );
			ld->ld_errno = LDAP_NO_MEMORY;
			return( NULL );
		}
	}

	if ( connect ) {
		LDAPURLDesc	**srvp, *srv = NULL;

		async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC );

		for ( srvp = srvlist; *srvp != NULL; srvp = &(*srvp)->lud_next ) {
			int		rc;

			rc = ldap_int_open_connection( ld, lc, *srvp, async );
			if ( rc != -1 ) {
				srv = *srvp;

				if ( ld->ld_urllist_proc && ( !async || rc != -2 ) ) {
					ld->ld_urllist_proc( ld, srvlist, srvp, ld->ld_urllist_params );
				}

				break;
			}
		}

		if ( srv == NULL ) {
			if ( !use_ldsb ) {
				ber_sockbuf_free( lc->lconn_sb );
			}
			LDAP_FREE( (char *)lc );
			ld->ld_errno = LDAP_SERVER_DOWN;
			return( NULL );
		}

		lc->lconn_server = ldap_url_dup( srv );
	}

	lc->lconn_status = async ? LDAP_CONNST_CONNECTING : LDAP_CONNST_CONNECTED;
	lc->lconn_next = ld->ld_conns;
	ld->ld_conns = lc;

	if ( connect ) {
#ifdef HAVE_TLS
		if ( lc->lconn_server->lud_exts ) {
			int rc, ext = find_tls_ext( lc->lconn_server );
			if ( ext ) {
				LDAPConn	*savedefconn;

				savedefconn = ld->ld_defconn;
				++lc->lconn_refcnt;	/* avoid premature free */
				ld->ld_defconn = lc;

				LDAP_REQ_UNLOCK_IF(m_req);
				LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
				LDAP_RES_UNLOCK_IF(m_res);
				rc = ldap_start_tls_s( ld, NULL, NULL );
				LDAP_RES_LOCK_IF(m_res);
				LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
				LDAP_REQ_LOCK_IF(m_req);
				ld->ld_defconn = savedefconn;
				--lc->lconn_refcnt;

				if ( rc != LDAP_SUCCESS && ext == 2 ) {
					ldap_free_connection( ld, lc, 1, 0 );
					return NULL;
				}
			}
		}
#endif
	}

	if ( bind != NULL ) {
		int		err = 0;
		LDAPConn	*savedefconn;

		/* Set flag to prevent additional referrals
		 * from being processed on this
		 * connection until the bind has completed
		 */
		lc->lconn_rebind_inprogress = 1;
		/* V3 rebind function */
		if ( ld->ld_rebind_proc != NULL) {
			LDAPURLDesc	*srvfunc;

			srvfunc = ldap_url_dup( *srvlist );
			if ( srvfunc == NULL ) {
				ld->ld_errno = LDAP_NO_MEMORY;
				err = -1;
			} else {
				savedefconn = ld->ld_defconn;
				++lc->lconn_refcnt;	/* avoid premature free */
				ld->ld_defconn = lc;

				Debug( LDAP_DEBUG_TRACE, "Call application rebind_proc\n", 0, 0, 0);
				LDAP_REQ_UNLOCK_IF(m_req);
				LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
				LDAP_RES_UNLOCK_IF(m_res);
				err = (*ld->ld_rebind_proc)( ld,
					bind->ri_url, bind->ri_request, bind->ri_msgid,
					ld->ld_rebind_params );
				LDAP_RES_LOCK_IF(m_res);
				LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
				LDAP_REQ_LOCK_IF(m_req);

				ld->ld_defconn = savedefconn;
				--lc->lconn_refcnt;

				if ( err != 0 ) {
					err = -1;
					ldap_free_connection( ld, lc, 1, 0 );
					lc = NULL;
				}
				ldap_free_urldesc( srvfunc );
			}

		} else {
			int		msgid, rc;
			struct berval	passwd = BER_BVNULL;

			savedefconn = ld->ld_defconn;
			++lc->lconn_refcnt;	/* avoid premature free */
			ld->ld_defconn = lc;

			Debug( LDAP_DEBUG_TRACE,
				"anonymous rebind via ldap_sasl_bind(\"\")\n",
				0, 0, 0);

			LDAP_REQ_UNLOCK_IF(m_req);
			LDAP_MUTEX_UNLOCK( &ld->ld_conn_mutex );
			LDAP_RES_UNLOCK_IF(m_res);
			rc = ldap_sasl_bind( ld, "", LDAP_SASL_SIMPLE, &passwd,
				NULL, NULL, &msgid );
			if ( rc != LDAP_SUCCESS ) {
				err = -1;

			} else {
				for ( err = 1; err > 0; ) {
					struct timeval	tv = { 0, 100000 };
					LDAPMessage	*res = NULL;

					switch ( ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) {
					case -1:
						err = -1;
						break;

					case 0:
#ifdef LDAP_R_COMPILE
						ldap_pvt_thread_yield();
#endif
						break;

					case LDAP_RES_BIND:
						rc = ldap_parse_result( ld, res, &err, NULL, NULL, NULL, NULL, 1 );
						if ( rc != LDAP_SUCCESS ) {
							err = -1;

						} else if ( err != LDAP_SUCCESS ) {
							err = -1;
						}
						/* else err == LDAP_SUCCESS == 0 */
						break;

					default:
						Debug( LDAP_DEBUG_TRACE,
							"ldap_new_connection %p: "
							"unexpected response %d "
							"from BIND request id=%d\n",
							(void *) ld, ldap_msgtype( res ), msgid );
						err = -1;
						break;
					}
				}
			}
			LDAP_RES_LOCK_IF(m_res);
			LDAP_MUTEX_LOCK( &ld->ld_conn_mutex );
			LDAP_REQ_LOCK_IF(m_req);
			ld->ld_defconn = savedefconn;
			--lc->lconn_refcnt;

			if ( err != 0 ) {
				ldap_free_connection( ld, lc, 1, 0 );
				lc = NULL;
			}
		}
		if ( lc != NULL )
			lc->lconn_rebind_inprogress = 0;
	}
	return( lc );
}
예제 #28
0
static int
ldap_back_exop_passwd(
	Operation	*op,
	SlapReply	*rs,
	ldapconn_t	**lcp )
{
	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;

	ldapconn_t	*lc = *lcp;
	req_pwdexop_s	*qpw = &op->oq_pwdexop;
	LDAPMessage	*res;
	ber_int_t	msgid;
	int		rc, isproxy, freedn = 0;
	int		do_retry = 1;
	char		*text = NULL;
	struct berval	dn = op->o_req_dn,
			ndn = op->o_req_ndn;

	assert( lc != NULL );
	assert( rs->sr_ctrls == NULL );

	if ( BER_BVISNULL( &ndn ) && op->ore_reqdata != NULL ) {
		/* NOTE: most of this code is mutated
		 * from slap_passwd_parse();
		 * But here we only need
		 * the first berval... */

		ber_tag_t tag;
		ber_len_t len = -1;
		BerElementBuffer berbuf;
		BerElement *ber = (BerElement *)&berbuf;

		struct berval	tmpid = BER_BVNULL;

		if ( op->ore_reqdata->bv_len == 0 ) {
			return LDAP_PROTOCOL_ERROR;
		}

		/* ber_init2 uses reqdata directly, doesn't allocate new buffers */
		ber_init2( ber, op->ore_reqdata, 0 );

		tag = ber_scanf( ber, "{" /*}*/ );

		if ( tag == LBER_ERROR ) {
			return LDAP_PROTOCOL_ERROR;
		}

		tag = ber_peek_tag( ber, &len );
		if ( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) {
			tag = ber_get_stringbv( ber, &tmpid, LBER_BV_NOTERM );

			if ( tag == LBER_ERROR ) {
				return LDAP_PROTOCOL_ERROR;
			}
		}

		if ( !BER_BVISEMPTY( &tmpid ) ) {
			char idNull = tmpid.bv_val[tmpid.bv_len];
			tmpid.bv_val[tmpid.bv_len] = '\0';
			rs->sr_err = dnPrettyNormal( NULL, &tmpid, &dn,
				&ndn, op->o_tmpmemctx );
			tmpid.bv_val[tmpid.bv_len] = idNull;
			if ( rs->sr_err != LDAP_SUCCESS ) {
				/* should have been successfully parsed earlier! */
				return rs->sr_err;
			}
			freedn = 1;

		} else {
			dn = op->o_dn;
			ndn = op->o_ndn;
		}
	}

	isproxy = ber_bvcmp( &ndn, &op->o_ndn );

	Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n",
		dn.bv_val, isproxy ? " (proxy)" : "", 0 );

retry:
	rc = ldap_passwd( lc->lc_ld,  &dn,
		qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
		qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
		op->o_ctrls, NULL, &msgid );

	if ( rc == LDAP_SUCCESS ) {
		/* TODO: set timeout? */
		/* by now, make sure no timeout is used (ITS#6282) */
		struct timeval tv = { -1, 0 };
		if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) == -1 ) {
			ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
			rs->sr_err = rc;

		} else {
			/* only touch when activity actually took place... */
			if ( li->li_idle_timeout ) {
				lc->lc_time = op->o_time;
			}

			/* sigh. parse twice, because parse_passwd
			 * doesn't give us the err / match / msg info.
			 */
			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
					(char **)&rs->sr_matched,
					&text,
					NULL, &rs->sr_ctrls, 0 );

			if ( rc == LDAP_SUCCESS ) {
				if ( rs->sr_err == LDAP_SUCCESS ) {
					struct berval	newpw;

					/* this never happens because 
					 * the frontend	is generating 
					 * the new password, so when
					 * the passwd exop is proxied,
					 * it never delegates password
					 * generation to the remote server
					 */
					rc = ldap_parse_passwd( lc->lc_ld, res,
							&newpw );
					if ( rc == LDAP_SUCCESS &&
							!BER_BVISNULL( &newpw ) )
					{
						rs->sr_type = REP_EXTENDED;
						rs->sr_rspdata = slap_passwd_return( &newpw );
						free( newpw.bv_val );
					}

				} else {
					rc = rs->sr_err;
				}
			}
			ldap_msgfree( res );
		}
	}

	if ( rc != LDAP_SUCCESS ) {
		rs->sr_err = slap_map_api2result( rs );
		if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
			do_retry = 0;
			if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
				goto retry;
			}
		}

		if ( LDAP_BACK_QUARANTINE( li ) ) {
			ldap_back_quarantine( op, rs );
		}

		if ( text ) rs->sr_text = text;
		send_ldap_extended( op, rs );
		/* otherwise frontend resends result */
		rc = rs->sr_err = SLAPD_ABANDON;

	} else if ( LDAP_BACK_QUARANTINE( li ) ) {
		ldap_back_quarantine( op, rs );
	}

	ldap_pvt_thread_mutex_lock( &li->li_counter_mutex );
	ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_EXTENDED ], 1 );
	ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex );

	if ( freedn ) {
		op->o_tmpfree( dn.bv_val, op->o_tmpmemctx );
		op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
	}

	/* these have to be freed anyway... */
	if ( rs->sr_matched ) {
		free( (char *)rs->sr_matched );
		rs->sr_matched = NULL;
	}

	if ( rs->sr_ctrls ) {
		ldap_controls_free( rs->sr_ctrls );
		rs->sr_ctrls = NULL;
	}

	if ( text ) {
		free( text );
		rs->sr_text = NULL;
	}

	/* in case, cleanup handler */
	if ( lc == NULL ) {
		*lcp = NULL;
	}

	return rc;
}
예제 #29
0
static int process_response(
	LDAP *ld,
	int msgid,
	int op,
	const char *dn )
{
	LDAPMessage	*res;
	int		rc = LDAP_OTHER, msgtype;
	struct timeval	tv = { 0, 0 };
	int		err;
	char		*text = NULL, *matched = NULL, **refs = NULL;
	LDAPControl	**ctrls = NULL;

	for ( ; ; ) {
		tv.tv_sec = 0;
		tv.tv_usec = 100000;

		rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
		if ( tool_check_abandon( ld, msgid ) ) {
			return LDAP_CANCELLED;
		}

		if ( rc == -1 ) {
			ldap_get_option( ld, LDAP_OPT_RESULT_CODE, &rc );
			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
			return rc;
		}

		if ( rc != 0 ) {
			break;
		}
	}

	msgtype = ldap_msgtype( res );

	rc = ldap_parse_result( ld, res, &err, &matched, &text, &refs, &ctrls, 1 );
	if ( rc == LDAP_SUCCESS ) rc = err;

#ifdef LDAP_X_TXN
	if ( rc == LDAP_X_TXN_SPECIFY_OKAY ) {
		rc = LDAP_SUCCESS;
	} else
#endif
	if ( rc != LDAP_SUCCESS ) {
		tool_perror( res2str( op ), rc, NULL, matched, text, refs );
	} else if ( msgtype != op ) {
		fprintf( stderr, "%s: msgtype: expected %d got %d\n",
			res2str( op ), op, msgtype );
		rc = LDAP_OTHER;
	}

	if ( text ) ldap_memfree( text );
	if ( matched ) ldap_memfree( matched );
	if ( text ) ber_memvfree( (void **)refs );

	if ( ctrls ) {
		tool_print_ctrls( ld, ctrls );
		ldap_controls_free( ctrls );
	}

	return rc;
}
예제 #30
0
static int
ldap_back_exop_generic(
	Operation	*op,
	SlapReply	*rs,
	ldapconn_t	**lcp )
{
	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;

	ldapconn_t	*lc = *lcp;
	LDAPMessage	*res;
	ber_int_t	msgid;
	int		rc;
	int		do_retry = 1;
	char		*text = NULL;

	Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_generic(%s, \"%s\")\n",
		op->ore_reqoid.bv_val, op->o_req_dn.bv_val, 0 );
	assert( lc != NULL );
	assert( rs->sr_ctrls == NULL );

retry:
	rc = ldap_extended_operation( lc->lc_ld,
		op->ore_reqoid.bv_val, op->ore_reqdata,
		op->o_ctrls, NULL, &msgid );

	if ( rc == LDAP_SUCCESS ) {
		/* TODO: set timeout? */
		/* by now, make sure no timeout is used (ITS#6282) */
		struct timeval tv = { -1, 0 };
		if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) == -1 ) {
			ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
			rs->sr_err = rc;

		} else {
			/* only touch when activity actually took place... */
			if ( li->li_idle_timeout ) {
				lc->lc_time = op->o_time;
			}

			/* sigh. parse twice, because parse_passwd
			 * doesn't give us the err / match / msg info.
			 */
			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
					(char **)&rs->sr_matched,
					&text,
					NULL, &rs->sr_ctrls, 0 );
			if ( rc == LDAP_SUCCESS ) {
				if ( rs->sr_err == LDAP_SUCCESS ) {
					rc = ldap_parse_extended_result( lc->lc_ld, res,
							(char **)&rs->sr_rspoid, &rs->sr_rspdata, 0 );
					if ( rc == LDAP_SUCCESS ) {
						rs->sr_type = REP_EXTENDED;
					}

				} else {
					rc = rs->sr_err;
				}
			}
			ldap_msgfree( res );
		}
	}

	if ( rc != LDAP_SUCCESS ) {
		rs->sr_err = slap_map_api2result( rs );
		if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
			do_retry = 0;
			if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
				goto retry;
			}
		}

		if ( LDAP_BACK_QUARANTINE( li ) ) {
			ldap_back_quarantine( op, rs );
		}

		if ( text ) rs->sr_text = text;
		send_ldap_extended( op, rs );
		/* otherwise frontend resends result */
		rc = rs->sr_err = SLAPD_ABANDON;

	} else if ( LDAP_BACK_QUARANTINE( li ) ) {
		ldap_back_quarantine( op, rs );
	}

	ldap_pvt_thread_mutex_lock( &li->li_counter_mutex );
	ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_EXTENDED ], 1 );
	ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex );

	/* these have to be freed anyway... */
	if ( rs->sr_matched ) {
		free( (char *)rs->sr_matched );
		rs->sr_matched = NULL;
	}

	if ( rs->sr_ctrls ) {
		ldap_controls_free( rs->sr_ctrls );
		rs->sr_ctrls = NULL;
	}

	if ( text ) {
		free( text );
		rs->sr_text = NULL;
	}

	/* in case, cleanup handler */
	if ( lc == NULL ) {
		*lcp = NULL;
	}

	return rc;
}