Ejemplo n.º 1
0
static bool
auth_worker_handle_user(struct auth_worker_client *client,
			unsigned int id, const char *const *args)
{
	/* lookup user */
	struct auth_request *auth_request;
	unsigned int userdb_id;

	/* <userdb id> [<args>] */
	if (str_to_uint(args[0], &userdb_id) < 0) {
		i_error("BUG: Auth worker server sent us invalid USER");
		return FALSE;
	}

	auth_request = worker_auth_request_new(client, id, args + 1);
	if (auth_request->user == NULL || auth_request->service == NULL) {
		i_error("BUG: USER had missing parameters");
		auth_request_unref(&auth_request);
		return FALSE;
	}

	auth_request->userdb =
		auth_userdb_find_by_id(auth_request->userdb, userdb_id);
	if (auth_request->userdb == NULL) {
		i_error("BUG: USER had invalid userdb ID");
		auth_request_unref(&auth_request);
		return FALSE;
	}

	auth_request_init_userdb_reply(auth_request);
	auth_request->userdb->userdb->iface->
		lookup(auth_request, lookup_user_callback);
	return TRUE;
}
Ejemplo n.º 2
0
static bool
auth_worker_handle_setcred(struct auth_worker_client *client,
			   unsigned int id, const char *const *args)
{
	struct auth_request *auth_request;
	unsigned int passdb_id;
	const char *creds;

	/* <passdb id> <credentials> [<args>] */
	if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
		i_error("BUG: Auth worker server sent us invalid SETCRED");
		return FALSE;
	}
	creds = args[1];

	auth_request = worker_auth_request_new(client, id, args + 2);
	if (auth_request->user == NULL || auth_request->service == NULL) {
		i_error("BUG: SETCRED had missing parameters");
		auth_request_unref(&auth_request);
		return FALSE;
	}

	while (auth_request->passdb->passdb->id != passdb_id) {
		auth_request->passdb = auth_request->passdb->next;
		if (auth_request->passdb == NULL) {
			i_error("BUG: SETCRED had invalid passdb ID");
			auth_request_unref(&auth_request);
			return FALSE;
		}
	}

	auth_request->passdb->passdb->iface.
		set_credentials(auth_request, creds, set_credentials_callback);
	return TRUE;
}
Ejemplo n.º 3
0
static bool
auth_worker_handle_passv(struct auth_worker_client *client,
			 unsigned int id, const char *const *args)
{
	/* verify plaintext password */
	struct auth_request *auth_request;
        struct auth_passdb *passdb;
	const char *password;
	unsigned int passdb_id;

	/* <passdb id> <password> [<args>] */
	if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
		i_error("BUG: Auth worker server sent us invalid PASSV");
		return FALSE;
	}
	password = args[1];

	auth_request = worker_auth_request_new(client, id, args + 2);
	auth_request->mech_password =
		p_strdup(auth_request->pool, password);

	if (auth_request->user == NULL || auth_request->service == NULL) {
		i_error("BUG: PASSV had missing parameters");
		auth_request_unref(&auth_request);
		return FALSE;
	}

	passdb = auth_request->passdb;
	while (passdb != NULL && passdb->passdb->id != passdb_id)
		passdb = passdb->next;

	if (passdb == NULL) {
		/* could be a masterdb */
		passdb = auth_request_get_auth(auth_request)->masterdbs;
		while (passdb != NULL && passdb->passdb->id != passdb_id)
			passdb = passdb->next;

		if (passdb == NULL) {
			i_error("BUG: PASSV had invalid passdb ID");
			auth_request_unref(&auth_request);
			return FALSE;
		}
	}

	auth_request->passdb = passdb;
	passdb->passdb->iface.
		verify_plain(auth_request, password, verify_plain_callback);
	return TRUE;
}
Ejemplo n.º 4
0
static void
lookup_credentials_callback(enum passdb_result result,
			    const unsigned char *credentials, size_t size,
			    struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	string_t *str;

	if (request->failed && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	str = t_str_new(128);
	str_printfa(str, "%u\t", request->id);

	if (result != PASSDB_RESULT_OK)
		str_printfa(str, "FAIL\t%d", result);
	else {
		str_append(str, "OK\t");
		str_append_tabescaped(str, request->user);
		str_append_c(str, '\t');
		if (request->credentials_scheme[0] != '\0') {
			str_printfa(str, "{%s.b64}", request->credentials_scheme);
			base64_encode(credentials, size, str);
		} else {
			i_assert(size == 0);
		}
		reply_append_extra_fields(str, request);
	}
	str_append_c(str, '\n');
	auth_worker_send_reply(client, request, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Ejemplo n.º 5
0
static void verify_plain_callback(enum passdb_result result,
				  struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	string_t *str;

	if (request->failed && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	str = t_str_new(128);
	str_printfa(str, "%u\t", request->id);

	if (result == PASSDB_RESULT_OK)
		str_append(str, "OK");
	else
		str_printfa(str, "FAIL\t%d", result);
	if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
		str_append_c(str, '\t');
		str_append_tabescaped(str, request->user);
		str_append_c(str, '\t');
		if (request->passdb_password != NULL)
			str_append_tabescaped(str, request->passdb_password);
		reply_append_extra_fields(str, request);
	}
	str_append_c(str, '\n');
	auth_worker_send_reply(client, request, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Ejemplo n.º 6
0
static void checkpassword_request_finish(struct chkpw_auth_request *request,
					 enum userdb_result result)
{
	struct userdb_module *_module = request->request->userdb->userdb;
	struct checkpassword_userdb_module *module =
		(struct checkpassword_userdb_module *)_module;
	userdb_callback_t *callback =
		(userdb_callback_t *)request->callback;

	hash_table_remove(module->clients, POINTER_CAST(request->pid));

	if (result == USERDB_RESULT_OK) {
		if (strchr(str_c(request->input_buf), '\n') != NULL) {
			auth_request_log_error(request->request,
				"userdb-checkpassword",
				"LF characters in checkpassword reply");
			result = USERDB_RESULT_INTERNAL_FAILURE;
		} else {
			auth_request_init_userdb_reply(request->request);
			auth_request_set_fields(request->request,
				t_strsplit(str_c(request->input_buf), "\t"),
				NULL);
		}
	}

	callback(result, request->request);

	auth_request_unref(&request->request);
	checkpassword_request_free(request);
}
Ejemplo n.º 7
0
static void
lookup_user_callback(enum userdb_result result,
		     struct auth_request *auth_request)
{
	struct auth_worker_client *client = auth_request->context;
	string_t *str;

	str = t_str_new(128);
	str_printfa(str, "%u\t", auth_request->id);
	switch (result) {
	case USERDB_RESULT_INTERNAL_FAILURE:
		str_append(str, "FAIL\t");
		break;
	case USERDB_RESULT_USER_UNKNOWN:
		str_append(str, "NOTFOUND\t");
		break;
	case USERDB_RESULT_OK:
		str_append(str, "OK\t");
		str_append_tabescaped(str, auth_request->user);
		str_append_c(str, '\t');
		auth_fields_append(auth_request->userdb_reply, str, 0, 0);
		if (auth_request->userdb_lookup_tempfailed)
			str_append(str, "\ttempfail");
		break;
	}
	str_append_c(str, '\n');

	auth_worker_send_reply(client, auth_request, str);

	auth_request_unref(&auth_request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
void auth_request_handler_flush_failures(bool flush_all)
{
	struct auth_request **auth_requests, *auth_request;
	unsigned int i, count;
	time_t diff;

	count = aqueue_count(auth_failures);
	if (count == 0) {
		if (to_auth_failures != NULL)
			timeout_remove(&to_auth_failures);
		return;
	}

	auth_requests = array_idx_modifiable(&auth_failures_arr, 0);
	for (i = 0; i < count; i++) {
		auth_request = auth_requests[aqueue_idx(auth_failures, 0)];

		/* FIXME: assumess that failure_delay is always the same. */
		diff = ioloop_time - auth_request->last_access;
		if (diff < (time_t)auth_request->set->failure_delay &&
		    !flush_all)
			break;

		aqueue_delete_tail(auth_failures);

		i_assert(auth_request->state == AUTH_REQUEST_STATE_FINISHED);
		auth_request_handler_reply(auth_request,
					   AUTH_CLIENT_RESULT_FAILURE,
					   &uchar_nul, 0);
		auth_request_unref(&auth_request);
	}
}
void auth_request_handler_abort_requests(struct auth_request_handler *handler)
{
	struct hash_iterate_context *iter;
	void *key;
	struct auth_request *auth_request;

	iter = hash_table_iterate_init(handler->requests);
	while (hash_table_iterate(iter, handler->requests, &key, &auth_request)) {
		switch (auth_request->state) {
		case AUTH_REQUEST_STATE_NEW:
		case AUTH_REQUEST_STATE_MECH_CONTINUE:
		case AUTH_REQUEST_STATE_FINISHED:
			auth_request_unref(&auth_request);
			hash_table_remove(handler->requests, key);
			break;
		case AUTH_REQUEST_STATE_PASSDB:
		case AUTH_REQUEST_STATE_USERDB:
			/* can't abort a pending passdb/userdb lookup */
			break;
		case AUTH_REQUEST_STATE_MAX:
			i_unreached();
		}
	}
	hash_table_iterate_deinit(&iter);
}
Ejemplo n.º 10
0
static void
passdb_imap_login_callback(const struct imapc_command_reply *reply,
			   void *context)
{
	struct imap_auth_request *request = context;
	struct imapc_client *client = request->client;
	enum passdb_result result = PASSDB_RESULT_INTERNAL_FAILURE;

	switch (reply->state) {
	case IMAPC_COMMAND_STATE_OK:
		result = PASSDB_RESULT_OK;
		break;
	case IMAPC_COMMAND_STATE_NO:
		result = passdb_imap_get_failure_result(reply);
		auth_request_log_info(request->auth_request, AUTH_SUBSYS_DB,
				      "%s", reply->text_full);
		break;
	case IMAPC_COMMAND_STATE_BAD:
	case IMAPC_COMMAND_STATE_DISCONNECTED:
		auth_request_log_error(request->auth_request, AUTH_SUBSYS_DB,
				       "%s", reply->text_full);
		break;
	}
	request->verify_callback(result, request->auth_request);
	imapc_client_deinit(&client);
	auth_request_unref(&request->auth_request);
}
Ejemplo n.º 11
0
static void
ldap_bind_lookup_dn_fail(struct auth_request *auth_request,
			 struct passdb_ldap_request *request,
			 LDAPMessage *res)
{
	enum passdb_result passdb_result;

	if (res == NULL)
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	else if (request->entries == 0) {
		passdb_result = PASSDB_RESULT_USER_UNKNOWN;
		auth_request_log_info(auth_request, "ldap",
				      "unknown user");
	} else {
		i_assert(request->entries > 1);
		auth_request_log_error(auth_request, "ldap",
			"pass_filter matched multiple objects, aborting");
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	}

	if (auth_request->credentials_scheme != NULL) {
		request->callback.lookup_credentials(passdb_result, NULL, 0,
						     auth_request);
	} else {
		request->callback.verify_plain(passdb_result, auth_request);
	}
	auth_request_unref(&auth_request);
}
Ejemplo n.º 12
0
static bool
auth_worker_handle_passl(struct auth_worker_client *client,
			 unsigned int id, const char *const *args)
{
	/* lookup credentials */
	struct auth_request *auth_request;
	const char *scheme;
	unsigned int passdb_id;

	/* <passdb id> <scheme> [<args>] */
	if (str_to_uint(args[0], &passdb_id) < 0 || args[1] == NULL) {
		i_error("BUG: Auth worker server sent us invalid PASSL");
		return FALSE;
	}
	scheme = args[1];

	auth_request = worker_auth_request_new(client, id, args + 2);
	auth_request->credentials_scheme = p_strdup(auth_request->pool, scheme);

	if (auth_request->user == NULL || auth_request->service == NULL) {
		i_error("BUG: PASSL had missing parameters");
		auth_request_unref(&auth_request);
		return FALSE;
	}

	while (auth_request->passdb->passdb->id != passdb_id) {
		auth_request->passdb = auth_request->passdb->next;
		if (auth_request->passdb == NULL) {
			i_error("BUG: PASSL had invalid passdb ID");
			auth_request_unref(&auth_request);
			return FALSE;
		}
	}

	if (auth_request->passdb->passdb->iface.lookup_credentials == NULL) {
		i_error("BUG: PASSL lookup not supported by given passdb");
		auth_request_unref(&auth_request);
		return FALSE;
	}

	auth_request->prefer_plain_credentials = TRUE;
	auth_request->passdb->passdb->iface.
		lookup_credentials(auth_request, lookup_credentials_callback);
	return TRUE;
}
Ejemplo n.º 13
0
static int userdb_ldap_iterate_deinit(struct userdb_iterate_context *_ctx)
{
	struct ldap_userdb_iterate_context *ctx =
		(struct ldap_userdb_iterate_context *)_ctx;
	int ret = _ctx->failed ? -1 : 0;

	db_ldap_enable_input(ctx->conn, TRUE);
	auth_request_unref(&ctx->request.request.request.auth_request);
	i_free(ctx);
	return ret;
}
Ejemplo n.º 14
0
static bool
set_credentials_callback(const char *reply, void *context)
{
	struct auth_request *request = context;
	bool success;

	success = strcmp(reply, "OK") == 0 || strncmp(reply, "OK\t", 3) == 0;
	request->private_callback.set_credentials(success, request);
	auth_request_unref(&request);
	return TRUE;
}
Ejemplo n.º 15
0
static bool
verify_plain_callback(const char *reply, void *context)
{
	struct auth_request *request = context;
	enum passdb_result result;

	result = auth_worker_reply_parse(request, reply);
	auth_request_verify_plain_callback(result, request);
	auth_request_unref(&request);
	return TRUE;
}
static int
master_input_auth_request(struct auth_master_connection *conn, const char *args,
			  const char *cmd, struct auth_request **request_r,
			  const char **error_r)
{
	struct auth_request *auth_request;
	const char *const *list, *name, *arg, *username;
	unsigned int id;

	/* <id> <userid> [<parameters>] */
	list = t_strsplit_tab(args);
	if (list[0] == NULL || list[1] == NULL ||
	    str_to_uint(list[0], &id) < 0) {
		i_error("BUG: Master sent broken %s", cmd);
		return -1;
	}

	auth_request = auth_request_new_dummy();
	auth_request->id = id;
	auth_request->master = conn;
	auth_master_connection_ref(conn);
	username = list[1];

	for (list += 2; *list != NULL; list++) {
		arg = strchr(*list, '=');
		if (arg == NULL) {
			name = *list;
			arg = "";
		} else {
			name = t_strdup_until(*list, arg);
			arg++;
		}

		(void)auth_request_import_info(auth_request, name, arg);
	}

	if (auth_request->service == NULL) {
		i_error("BUG: Master sent %s request without service", cmd);
		auth_request_unref(&auth_request);
		auth_master_connection_unref(&conn);
		return -1;
	}

	auth_request_init(auth_request);

	if (!auth_request_set_username(auth_request, username, error_r)) {
		*request_r = auth_request;
		return 0;
	}
	*request_r = auth_request;
	return 1;
}
static void
user_callback(enum userdb_result result,
	      struct auth_request *auth_request)
{
	struct auth_master_connection *conn = auth_request->master;
	string_t *str;
	const char *value;

	if (auth_request->userdb_lookup_tempfailed)
		result = USERDB_RESULT_INTERNAL_FAILURE;

	if (result == USERDB_RESULT_OK) {
		if (user_verify_restricted_uid(auth_request) < 0)
			result = USERDB_RESULT_INTERNAL_FAILURE;
	}

	str = t_str_new(128);
	switch (result) {
	case USERDB_RESULT_INTERNAL_FAILURE:
		str_printfa(str, "FAIL\t%u", auth_request->id);
		if (auth_request->userdb_lookup_tempfailed) {
			value = auth_fields_find(auth_request->userdb_reply,
						 "reason");
			if (value != NULL)
				str_printfa(str, "\treason=%s", value);
		}
		break;
	case USERDB_RESULT_USER_UNKNOWN:
		str_printfa(str, "NOTFOUND\t%u", auth_request->id);
		break;
	case USERDB_RESULT_OK:
		str_printfa(str, "USER\t%u\t", auth_request->id);
		str_append_tabescaped(str, auth_request->user);
		str_append_c(str, '\t');
		auth_fields_append(auth_request->userdb_reply, str,
				   AUTH_FIELD_FLAG_HIDDEN, 0);
		break;
	}

	if (conn->auth->set->debug) {
		i_debug("userdb out: %s",
			auth_master_reply_hide_passwords(conn, str_c(str)));
	}

	str_append_c(str, '\n');
	o_stream_nsend(conn->output, str_data(str), str_len(str));

	auth_request_unref(&auth_request);
	auth_master_connection_unref(&conn);
}
Ejemplo n.º 18
0
static void
set_credentials_callback(bool success, struct auth_request *request)
{
	struct auth_worker_client *client = request->context;

	string_t *str;

	str = t_str_new(64);
	str_printfa(str, "%u\t%s\n", request->id, success ? "OK" : "FAIL");
	auth_worker_send_reply(client, request, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Ejemplo n.º 19
0
static void
lookup_credentials_callback(enum passdb_result result,
			    const unsigned char *credentials, size_t size,
			    struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	struct auth_stream_reply *reply;
	string_t *str;

	if (request->passdb_failure && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	reply = auth_stream_reply_init(pool_datastack_create());
	auth_stream_reply_add(reply, NULL, dec2str(request->id));

	if (result != PASSDB_RESULT_OK) {
		auth_stream_reply_add(reply, "FAIL", NULL);
		auth_stream_reply_add(reply, NULL,
				      t_strdup_printf("%d", result));
	} else {
		auth_stream_reply_add(reply, "OK", NULL);
		auth_stream_reply_add(reply, NULL, request->user);

		str = t_str_new(64);
		str_printfa(str, "{%s.b64}", request->credentials_scheme);
		base64_encode(credentials, size, str);
		auth_stream_reply_add(reply, NULL, str_c(str));

		if (request->extra_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_fields);
			auth_stream_reply_import(reply, fields);
		}
		if (request->extra_cache_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_cache_fields);
			auth_stream_reply_import(reply, fields);
		}
	}
	str = auth_stream_reply_get_str(reply);
	str_append_c(str, '\n');
	auth_worker_send_reply(client, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Ejemplo n.º 20
0
static int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx)
{
	struct sql_userdb_iterate_context *ctx =
		(struct sql_userdb_iterate_context *)_ctx;
	int ret = _ctx->failed ? -1 : 0;

	auth_request_unref(&_ctx->auth_request);
	if (ctx->result == NULL) {
		/* sql query hasn't finished yet */
		ctx->freed = TRUE;
	} else {
		if (ctx->result != NULL)
			sql_result_unref(ctx->result);
		i_free(ctx);
	}
	return ret;
}
Ejemplo n.º 21
0
static void pass_callback_finish(struct auth_request *auth_request,
				 enum passdb_result result)
{
	struct auth_master_connection *conn = auth_request->master;
	string_t *str;

	str = t_str_new(128);
	switch (result) {
	case PASSDB_RESULT_OK:
		if (auth_request->failed || !auth_request->passdb_success) {
			str_printfa(str, "FAIL\t%u", auth_request->id);
			break;
		}
		str_printfa(str, "PASS\t%u\tuser="******"NOTFOUND\t%u", auth_request->id);
		break;
	case PASSDB_RESULT_NEXT:
	case PASSDB_RESULT_PASSWORD_MISMATCH:
	case PASSDB_RESULT_INTERNAL_FAILURE:
		str_printfa(str, "FAIL\t%u", auth_request->id);
		break;
	case PASSDB_RESULT_SCHEME_NOT_AVAILABLE:
		str_printfa(str, "FAIL\t%u\treason=Configured passdbs don't support credentials lookups",
			    auth_request->id);
		break;
	}

	if (conn->auth->set->debug)
		i_debug("passdb out: %s", str_c(str));

	str_append_c(str, '\n');
	o_stream_nsend(conn->output, str_data(str), str_len(str));

	auth_request_unref(&auth_request);
	auth_master_connection_unref(&conn);
}
Ejemplo n.º 22
0
static void ldap_bind_lookup_dn_callback(struct ldap_connection *conn,
					 struct ldap_request *ldap_request,
					 LDAPMessage *res)
{
	struct passdb_ldap_request *passdb_ldap_request =
		(struct passdb_ldap_request *)ldap_request;
	struct auth_request *auth_request = ldap_request->auth_request;
	struct passdb_ldap_request *brequest;
	char *dn;

	if (res != NULL && ldap_msgtype(res) == LDAP_RES_SEARCH_ENTRY) {
		if (passdb_ldap_request->entries++ > 0) {
			/* too many replies */
			return;
		}

		/* first entry */
		ldap_query_save_result(conn, auth_request,
				       &passdb_ldap_request->request.search, res);

		/* save dn */
		dn = ldap_get_dn(conn->ld, res);
		passdb_ldap_request->dn = p_strdup(auth_request->pool, dn);
		ldap_memfree(dn);
	} else if (res == NULL || passdb_ldap_request->entries != 1) {
		/* failure */
		ldap_bind_lookup_dn_fail(auth_request, passdb_ldap_request, res);
	} else if (auth_request->skip_password_check) {
		/* we've already verified that the password matched -
		   we just wanted to get any extra fields */
		passdb_ldap_request->callback.
			verify_plain(PASSDB_RESULT_OK, auth_request);
		auth_request_unref(&auth_request);
	} else {
		/* create a new bind request */
		brequest = p_new(auth_request->pool,
				 struct passdb_ldap_request, 1);
		brequest->dn = passdb_ldap_request->dn;
		brequest->callback = passdb_ldap_request->callback;
		brequest->request.bind.dn = brequest->dn;
		brequest->request.bind.request.type = LDAP_REQUEST_TYPE_BIND;
		brequest->request.bind.request.auth_request = auth_request;

		ldap_auth_bind(conn, &brequest->request.bind);
	}
}
static void auth_request_handler_remove(struct auth_request_handler *handler,
					struct auth_request *request)
{
	i_assert(request->handler == handler);

	if (request->removed_from_handler) {
		/* already removed it */
		return;
	}
	request->removed_from_handler = TRUE;

	/* if db lookup is stuck, this call doesn't actually free the auth
	   request, so make sure we don't get back here. */
	timeout_remove(&request->to_abort);

	hash_table_remove(handler->requests, POINTER_CAST(request->id));
	auth_request_unref(&request);
}
Ejemplo n.º 24
0
static int userdb_dict_iterate_deinit(struct userdb_iterate_context *_ctx)
{
	struct dict_userdb_iterate_context *ctx =
		(struct dict_userdb_iterate_context *)_ctx;
	const char *error;
	int ret = _ctx->failed ? -1 : 0;

	if (ctx->iter != NULL) {
		if (dict_iterate_deinit(&ctx->iter, &error) < 0) {
			i_error("dict_iterate(%s) failed: %s",
				ctx->key_prefix, error);
			ret = -1;
		}
	}
	auth_request_unref(&ctx->ctx.auth_request);
	i_free(ctx);
	return ret;
}
Ejemplo n.º 25
0
static void verify_plain_callback(enum passdb_result result,
				  struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	struct auth_stream_reply *reply;
	string_t *str;

	if (request->passdb_failure && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	reply = auth_stream_reply_init(pool_datastack_create());
	auth_stream_reply_add(reply, NULL, dec2str(request->id));

	if (result == PASSDB_RESULT_OK)
		auth_stream_reply_add(reply, "OK", NULL);
	else {
		auth_stream_reply_add(reply, "FAIL", NULL);
		auth_stream_reply_add(reply, NULL,
				      t_strdup_printf("%d", result));
	}
	if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
		auth_stream_reply_add(reply, NULL, request->user);
		auth_stream_reply_add(reply, NULL,
				      request->passdb_password == NULL ? "" :
				      request->passdb_password);
		if (request->extra_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_fields);
			auth_stream_reply_import(reply, fields);
		}
		if (request->extra_cache_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_cache_fields);
			auth_stream_reply_import(reply, fields);
		}
	}
	str = auth_stream_reply_get_str(reply);
	str_append_c(str, '\n');
	auth_worker_send_reply(client, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Ejemplo n.º 26
0
static bool iter_callback(const char *reply, void *context)
{
	struct blocking_userdb_iterate_context *ctx = context;

	if (str_begins(reply, "*\t")) {
		if (ctx->destroyed)
			return TRUE;
		ctx->next = FALSE;
		ctx->ctx.callback(reply + 2, ctx->ctx.context);
		return ctx->next || ctx->destroyed;
	}

	if (strcmp(reply, "OK") != 0)
		ctx->ctx.failed = TRUE;
	if (!ctx->destroyed)
		ctx->ctx.callback(NULL, ctx->ctx.context);
	auth_request_unref(&ctx->ctx.auth_request);
	return TRUE;
}
Ejemplo n.º 27
0
static void
ldap_lookup_pass_callback(struct ldap_connection *conn,
			  struct ldap_request *request, LDAPMessage *res)
{
	struct passdb_ldap_request *ldap_request =
		(struct passdb_ldap_request *)request;
        struct auth_request *auth_request = request->auth_request;

	if (res == NULL || ldap_msgtype(res) == LDAP_RES_SEARCH_RESULT) {
		ldap_lookup_finish(auth_request, ldap_request, res);
		auth_request_unref(&auth_request);
		return;
	}

	if (ldap_request->entries++ == 0) {
		/* first entry */
		ldap_query_save_result(conn, res, auth_request);
	}
}
Ejemplo n.º 28
0
static void
ldap_auth_bind_callback(struct ldap_connection *conn,
			struct ldap_request *ldap_request, LDAPMessage *res)
{
	struct passdb_ldap_request *passdb_ldap_request =
		(struct passdb_ldap_request *)ldap_request;
	struct auth_request *auth_request = ldap_request->auth_request;
	enum passdb_result passdb_result;
	const char *str;
	int ret;

	passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;

	if (res != NULL) {
		ret = ldap_result2error(conn->ld, res, 0);
		if (ret == LDAP_SUCCESS)
			passdb_result = PASSDB_RESULT_OK;
		else if (ret == LDAP_INVALID_CREDENTIALS) {
			str = "invalid credentials";
			if (auth_request->set->debug_passwords) {
				str = t_strconcat(str, " (given password: "******")", NULL);
			}
			auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
					      "%s", str);
			passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
		} else if (ret == LDAP_NO_SUCH_OBJECT) {
			passdb_result = PASSDB_RESULT_USER_UNKNOWN;
			auth_request_log_unknown_user(auth_request,
						      AUTH_SUBSYS_DB);
		} else {
			auth_request_log_error(auth_request, AUTH_SUBSYS_DB,
					       "ldap_bind() failed: %s",
					       ldap_err2string(ret));
		}
	}

	passdb_ldap_request->callback.
		verify_plain(passdb_result, auth_request);
        auth_request_unref(&auth_request);
}
static void
user_callback(enum userdb_result result, struct auth_request *auth_request)
{
	struct auth_postfix_connection *conn = auth_request->context;
	string_t *str;
	const char *value;

	if (auth_request->userdb_lookup_tempfailed)
		result = USERDB_RESULT_INTERNAL_FAILURE;

	str = t_str_new(128);
	switch (result) {
	case USERDB_RESULT_INTERNAL_FAILURE:
		if (auth_request->userdb_lookup_tempfailed)
			value = auth_fields_find(auth_request->userdb_reply, "reason");
		else
			value = NULL;
		str_printfa(str, "400 %s",
			    value != NULL ? value: "Internal failure");
		break;
	case USERDB_RESULT_USER_UNKNOWN:
		str_append(str, "500 User not found");
		break;
	case USERDB_RESULT_OK:
		str_append(str, "200 1");
		break;
	}

	if (conn->auth->set->debug)
		i_debug("postfix out: %s", str_c(str));

	str_append_c(str, '\n');
	o_stream_nsend(conn->output, str_data(str), str_len(str));

	i_assert(conn->io == NULL);
	if (!conn->destroyed)
		conn->io = io_add(conn->fd, IO_READ, postfix_input, conn);

	auth_request_unref(&auth_request);
	auth_postfix_connection_unref(&conn);
}
Ejemplo n.º 30
0
static void userdb_ldap_lookup_callback(struct ldap_connection *conn,
					struct ldap_request *request,
					LDAPMessage *res)
{
	struct userdb_ldap_request *urequest =
		(struct userdb_ldap_request *) request;
	struct auth_request *auth_request =
		urequest->request.request.auth_request;

	if (res == NULL || ldap_msgtype(res) == LDAP_RES_SEARCH_RESULT) {
		userdb_ldap_lookup_finish(auth_request, urequest, res);
		auth_request_unref(&auth_request);
		return;
	}

	if (urequest->entries++ == 0) {
		/* first entry */
		ldap_query_get_result(conn, auth_request,
				      &urequest->request, res);
	}
}