Пример #1
0
struct vqpasswd *vpopmail_lookup_vqp(struct auth_request *request,
				     char vpop_user[VPOPMAIL_LIMIT],
				     char vpop_domain[VPOPMAIL_LIMIT])
{
	struct vqpasswd *vpw;

	/* vpop_user must be zero-filled or parse_email() leaves an
	   extra character after the user name. we'll fill vpop_domain
	   as well just to be sure... */
	memset(vpop_user, '\0', VPOPMAIL_LIMIT);
	memset(vpop_domain, '\0', VPOPMAIL_LIMIT);

	if (parse_email(request->user, vpop_user, vpop_domain,
			VPOPMAIL_LIMIT-1) < 0) {
		auth_request_log_info(request, "vpopmail",
				      "parse_email() failed");
		return NULL;
	}

	auth_request_log_debug(request, "vpopmail",
			       "lookup user=%s domain=%s",
			       vpop_user, vpop_domain);

	vpw = vauth_getpw(vpop_user, vpop_domain);
	if (vpw == NULL) {
		auth_request_log_info(request, "vpopmail", "unknown user");
		return NULL;
	}

	return vpw;
}
Пример #2
0
static void
mech_external_auth_continue(struct auth_request *request,
			    const unsigned char *data, size_t data_size)
{
	const char *authzid, *error;

	authzid = t_strndup(data, data_size);
	if (request->user == NULL) {
		auth_request_log_info(request, AUTH_SUBSYS_MECH,
				      "username not known");
		auth_request_fail(request);
		return;
	}

	/* this call is done simply to put the username through translation
	   settings */
	if (!auth_request_set_username(request, "", &error)) {
		auth_request_log_info(request, AUTH_SUBSYS_MECH,
				      "Invalid username");
		auth_request_fail(request);
		return;
	}

	if (*authzid != '\0' &&
	    !auth_request_set_login_username(request, authzid, &error)) {
		/* invalid login username */
		auth_request_log_info(request, AUTH_SUBSYS_MECH,
				      "login user: %s", error);
		auth_request_fail(request);
	} else {
                auth_request_verify_plain(request, "",
                                          plain_verify_callback);
	}
}
Пример #3
0
static void
mech_plain_auth_continue(struct auth_request *request,
			 const unsigned char *data, size_t data_size)
{
	const char *authid, *authenid, *error;
	char *pass;
	size_t i, len;
	int count;

	/* authorization ID \0 authentication ID \0 pass. */
	authid = (const char *) data;
	authenid = NULL; pass = NULL;

	count = 0;
	for (i = 0; i < data_size; i++) {
		if (data[i] == '\0') {
			if (++count == 1)
				authenid = (const char *) data + i+1;
			else {
				i++;
				len = data_size - i;
				pass = p_strndup(unsafe_data_stack_pool,
						 data+i, len);
				break;
			}
		}
	}

	if (authenid != NULL && strcmp(authid, authenid) == 0) {
		/* the login username isn't different */
		authid = "";
	}

	if (count != 2) {
		/* invalid input */
		auth_request_log_info(request, AUTH_SUBSYS_MECH, "invalid input");
		auth_request_fail(request);
	} else if (!auth_request_set_username(request, authenid, &error)) {
                /* invalid username */
                auth_request_log_info(request, AUTH_SUBSYS_MECH, "%s", error);
                auth_request_fail(request);
        } else if (*authid != '\0' &&
                   !auth_request_set_login_username(request, authid, &error)) {
                /* invalid login username */
                auth_request_log_info(request, AUTH_SUBSYS_MECH,
                                      "login user: %s", error);
                auth_request_fail(request);
        } else {
                auth_request_verify_plain(request, pass,
                                          plain_verify_callback);
	}

        /* make sure it's cleared */
	if (pass != NULL)
		safe_memset(pass, 0, strlen(pass));
}
Пример #4
0
static void
mech_dovecot_token_auth_continue(struct auth_request *request,
			     const unsigned char *data, size_t data_size)
{
	const char *session_id, *username, *pid, *service, *error;
	char *auth_token;
	size_t i, len;
	int count;

	/* service \0 pid \0 username \0 session_id \0 auth_token */
	service = (const char *) data;
	session_id = username = pid = auth_token = NULL;
	count = 0;
	for (i = 0; i < data_size; i++) {
		if (data[i] == '\0') {
			count++; i++;
			if (count == 1)
				pid = (const char *)data + i;
			else if (count == 2)
				username = (const char *)data + i;
			else if (count == 3)
				session_id = (const char *)data + i;
			else {
				len = data_size - i;
				auth_token = p_strndup(unsafe_data_stack_pool,
						       data+i, len);
				break;
			}
		}
	}	

	if (count != 4) {
		/* invalid input */
		auth_request_log_info(request, AUTH_SUBSYS_MECH, "invalid input");
		auth_request_fail(request);
	} else if (!auth_request_set_username(request, username, &error)) {
		/* invalid username */
		auth_request_log_info(request, AUTH_SUBSYS_MECH, "%s", error);
		auth_request_fail(request);
	} else {
		const char *valid_token =
			auth_token_get(service, pid, request->user, session_id);

		if (auth_token != NULL &&
		    strcmp(auth_token, valid_token) == 0) {
			request->passdb_success = TRUE;
			auth_request_success(request, NULL, 0);
		} else {
			auth_request_fail(request);
		}
	}

	/* make sure it's cleared */
	if (auth_token != NULL)
		safe_memset(auth_token, 0, strlen(auth_token));
}
Пример #5
0
static void
userdb_nss_lookup(struct auth_request *auth_request,
		  userdb_callback_t *callback)
{
	struct userdb_module *_module = auth_request->userdb->userdb;
	struct nss_userdb_module *module = (struct nss_userdb_module *)_module;
	struct passwd pw;
	enum nss_status status;
	enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE;
	int err;

	auth_request_log_debug(auth_request, "nss", "lookup");

	status = module->getpwnam_r(auth_request->user, &pw,
				    module->buf, module->bufsize, &err);
	switch (status) {
	case NSS_STATUS_TRYAGAIN:
		auth_request_log_error(auth_request, "nss",
				       "returned tryagain (err=%d)", err);
		break;
	case NSS_STATUS_UNAVAIL:
		auth_request_log_error(auth_request, "nss",
				       "unavailable (err=%d)", err);
		break;
	case NSS_STATUS_NOTFOUND:
		auth_request_log_info(auth_request, "nss", "unknown user");
		result = USERDB_RESULT_USER_UNKNOWN;
		break;
	case NSS_STATUS_SUCCESS:
		result = USERDB_RESULT_OK;
		break;
	default:
		auth_request_log_info(auth_request, "nss",
				      "returned %d (err=%d)", status, err);
		break;
	}

	if (result != USERDB_RESULT_OK) {
		callback(result, auth_request);
		return;
	}

	auth_request_set_field(auth_request, "user", pw.pw_name, NULL);

	auth_request_init_userdb_reply(auth_request);
	auth_request_set_userdb_field(auth_request, "system_groups_user",
				      pw.pw_name);
	auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
	auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
	auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);

	callback(USERDB_RESULT_OK, auth_request);
}
Пример #6
0
static void
ldap_lookup_finish(struct auth_request *auth_request,
		   struct passdb_ldap_request *ldap_request,
		   LDAPMessage *res)
{
	enum passdb_result passdb_result;
	const char *password = NULL, *scheme;
	int ret;

	if (res == NULL) {
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	} else if (ldap_request->entries == 0) {
		passdb_result = PASSDB_RESULT_USER_UNKNOWN;
		auth_request_log_info(auth_request, "ldap",
				      "unknown user");
	} else if (ldap_request->entries > 1) {
		auth_request_log_error(auth_request, "ldap",
			"pass_filter matched multiple objects, aborting");
		passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
	} else if (auth_request->passdb_password == NULL &&
		   !auth_fields_exists(auth_request->extra_fields, "nopassword")) {
		auth_request_log_info(auth_request, "ldap",
			"No password returned (and no nopassword)");
		passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
	} else {
		/* passdb_password may change on the way,
		   so we'll need to strdup. */
		password = t_strdup(auth_request->passdb_password);
		passdb_result = PASSDB_RESULT_OK;
	}

	scheme = password_get_scheme(&password);
	/* auth_request_set_field() sets scheme */
	i_assert(password == NULL || scheme != NULL);

	if (auth_request->credentials_scheme != NULL) {
		passdb_handle_credentials(passdb_result, password, scheme,
			ldap_request->callback.lookup_credentials,
			auth_request);
	} else {
		if (password != NULL) {
			ret = auth_request_password_verify(auth_request,
					auth_request->mech_password,
					password, scheme, "ldap");
			passdb_result = ret > 0 ? PASSDB_RESULT_OK :
				PASSDB_RESULT_PASSWORD_MISMATCH;
		}

		ldap_request->callback.verify_plain(passdb_result,
						    auth_request);
	}
}
Пример #7
0
static enum passdb_result
passwd_lookup(struct auth_request *request, struct passwd *pw_r)
{
	auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup");

	switch (i_getpwnam(request->user, pw_r)) {
	case -1:
		auth_request_log_error(request, AUTH_SUBSYS_DB,
				       "getpwnam() failed: %m");
		return PASSDB_RESULT_INTERNAL_FAILURE;
	case 0:
		auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
		return PASSDB_RESULT_USER_UNKNOWN;
	}

	if (!IS_VALID_PASSWD(pw_r->pw_passwd)) {
		auth_request_log_info(request, AUTH_SUBSYS_DB,
			"invalid password field '%s'", pw_r->pw_passwd);
		return PASSDB_RESULT_USER_DISABLED;
	}

	/* save the password so cache can use it */
	auth_request_set_field(request, "password", pw_r->pw_passwd,
			       PASSWD_PASS_SCHEME);
	return PASSDB_RESULT_OK;
}
Пример #8
0
static enum passdb_result
passdb_dict_lookup_key(struct auth_request *auth_request,
                       struct dict_passdb_module *module)
{
    struct db_dict_value_iter *iter;
    int ret;

    ret = db_dict_value_iter_init(module->conn, auth_request,
    &module->conn->set.passdb_fields,
    &module->conn->set.parsed_passdb_objects,
    &iter);
    if (ret < 0)
        return PASSDB_RESULT_INTERNAL_FAILURE;
    else if (ret == 0) {
        auth_request_log_unknown_user(auth_request, AUTH_SUBSYS_DB);
        return PASSDB_RESULT_USER_UNKNOWN;
    } else {
        if (dict_query_save_results(auth_request, module->conn, iter) < 0)
            return PASSDB_RESULT_INTERNAL_FAILURE;

        if (auth_request->passdb_password == NULL &&
        !auth_fields_exists(auth_request->extra_fields, "nopassword")) {
            auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
            "No password returned (and no nopassword)");
            return PASSDB_RESULT_PASSWORD_MISMATCH;
        } else {
            return PASSDB_RESULT_OK;
        }
    }
}
Пример #9
0
static void
mech_digest_md5_auth_continue(struct auth_request *auth_request,
			      const unsigned char *data, size_t data_size)
{
	struct digest_auth_request *request =
		(struct digest_auth_request *)auth_request;
	const char *username, *error;

	if (parse_digest_response(request, data, data_size, &error)) {
		if (auth_request->realm != NULL &&
		    strchr(request->username, '@') == NULL) {
			username = t_strconcat(request->username, "@",
					       auth_request->realm, NULL);
			auth_request->domain_is_realm = TRUE;
		} else {
			username = request->username;
		}

		if (auth_request_set_username(auth_request, username, &error) &&
				(request->authzid == NULL ||
				 auth_request_set_login_username(auth_request,
								 request->authzid,
								 &error))) {
			auth_request_lookup_credentials(auth_request,
					"DIGEST-MD5", credentials_callback);
			return;
		}
	}

	if (error != NULL)
                auth_request_log_info(auth_request, AUTH_SUBSYS_MECH, "%s", error);

	auth_request_fail(auth_request);
}
Пример #10
0
static enum passdb_result
passdb_dict_lookup_key(struct auth_request *auth_request,
		       struct dict_passdb_module *module, const char *key)
{
	const char *value;
	int ret;

	auth_request_log_debug(auth_request, "dict", "lookup %s", key);
	ret = dict_lookup(module->conn->dict, pool_datastack_create(),
			  key, &value);
	if (ret < 0) {
		auth_request_log_error(auth_request, "dict", "Lookup failed");
		return PASSDB_RESULT_INTERNAL_FAILURE;
	} else if (ret == 0) {
		auth_request_log_unknown_user(auth_request, "dict");
		return PASSDB_RESULT_USER_UNKNOWN;
	} else {
		auth_request_log_debug(auth_request, "dict",
				       "result: %s", value);
		if (dict_query_save_results(auth_request, module->conn, value) < 0)
			return PASSDB_RESULT_INTERNAL_FAILURE;

		if (auth_request->passdb_password == NULL &&
		    !auth_fields_exists(auth_request->extra_fields, "nopassword")) {
			auth_request_log_info(auth_request, "dict",
				"No password returned (and no nopassword)");
			return PASSDB_RESULT_PASSWORD_MISMATCH;
		} else {
			return PASSDB_RESULT_OK;
		}
	}
}
Пример #11
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);
}
Пример #12
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);
}
Пример #13
0
static enum passdb_result
static_save_fields(struct auth_request *request, const char **password_r)
{
	struct static_passdb_module *module =
		(struct static_passdb_module *)request->passdb->passdb;
        const struct var_expand_table *table;
	string_t *str = t_str_new(128);

	auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup");
	passdb_template_export(module->tmpl, request);

	if (module->static_password_tmpl != NULL) {
		table = auth_request_get_var_expand_table(request, NULL);
		var_expand(str, module->static_password_tmpl, table);
		*password_r = str_c(str);
	} else if (auth_fields_exists(request->extra_fields, "nopassword")) {
		*password_r = "";
	} else {
		auth_request_log_info(request, AUTH_SUBSYS_DB,
			"No password returned (and no nopassword)");
		*password_r = NULL;
		return PASSDB_RESULT_PASSWORD_MISMATCH;
	}
	return PASSDB_RESULT_OK;
}
Пример #14
0
static bool verify_credentials(struct cram_auth_request *request,
                               const unsigned char *credentials, size_t size)
{

    unsigned char digest[MD5_RESULTLEN];
    struct hmac_context ctx;
    const char *response_hex;

    if (size != CRAM_MD5_CONTEXTLEN) {
        auth_request_log_error(&request->auth_request, AUTH_SUBSYS_MECH,
                               "invalid credentials length");
        return FALSE;
    }

    hmac_init(&ctx, NULL, 0, &hash_method_md5);
    hmac_md5_set_cram_context(&ctx, credentials);
    hmac_update(&ctx, request->challenge, strlen(request->challenge));
    hmac_final(&ctx, digest);

    response_hex = binary_to_hex(digest, sizeof(digest));

    if (memcmp(response_hex, request->response, sizeof(digest)*2) != 0) {
        auth_request_log_info(&request->auth_request, AUTH_SUBSYS_MECH,
                              "password mismatch");
        return FALSE;
    }

    return TRUE;
}
Пример #15
0
static void
checkpassword_request_half_finish(struct chkpw_auth_request *request)
{
	if (!request->exited || request->fd_in != -1)
		return;

	switch (request->exit_status) {
	case 3:
		/* User does not exist. */
		auth_request_log_info(request->request, "userdb-checkpassword",
				      "User unknown");
		checkpassword_request_finish(request,
					     USERDB_RESULT_USER_UNKNOWN);
		break;
	case 2:
		/* This is intentionally not 0. checkpassword-reply exits with
		   2 on success when AUTHORIZED is set. */
		if (request->input_buf != NULL) {
			checkpassword_request_finish(request, USERDB_RESULT_OK);
			break;
		}
		/* missing input - fall through */
	default:
		/* whatever error... */
		auth_request_log_error(request->request, "userdb-checkpassword",
			"Child %s exited with status %d",
			dec2str(request->pid), request->exit_status);
		checkpassword_request_finish(request,
					     USERDB_RESULT_INTERNAL_FAILURE);
		break;
	}
}
Пример #16
0
bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
			       const char *password,
			       enum passdb_result *result_r, bool use_expired)
{
	const char *value, *cached_pw, *scheme, *const *list;
	struct auth_cache_node *node;
	int ret;
	bool neg_expired;

	if (passdb_cache == NULL || key == NULL)
		return FALSE;

	if (!passdb_cache_lookup(request, key, use_expired,
				 &node, &value, &neg_expired))
		return FALSE;

	if (*value == '\0') {
		/* negative cache entry */
		auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
		*result_r = PASSDB_RESULT_USER_UNKNOWN;
		return TRUE;
	}

	list = t_strsplit_tab(value);

	cached_pw = list[0];
	if (*cached_pw == '\0') {
		/* NULL password */
		auth_request_log_info(request, AUTH_SUBSYS_DB,
				      "Cached NULL password access");
		ret = 1;
	} else {
		scheme = password_get_scheme(&cached_pw);
		i_assert(scheme != NULL);

		ret = auth_request_password_verify(request, password, cached_pw,
						   scheme, AUTH_SUBSYS_DB);

		if (ret == 0 && (node->last_success || neg_expired)) {
			/* a) the last authentication was successful. assume
			   that the password was changed and cache is expired.
			   b) negative TTL reached, use it for password
			   mismatches too. */
			node->last_success = FALSE;
			return FALSE;
		}
	}
	node->last_success = ret > 0;

	/* save the extra_fields only after we know we're using the
	   cached data */
	auth_request_set_fields(request, list + 1, NULL);

	*result_r = ret > 0 ? PASSDB_RESULT_OK :
		PASSDB_RESULT_PASSWORD_MISMATCH;
	return TRUE;
}
Пример #17
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, "ldap", "%s", str);
			passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
		} else if (ret == LDAP_NO_SUCH_OBJECT) {
			passdb_result = PASSDB_RESULT_USER_UNKNOWN;
			auth_request_log_info(auth_request, "ldap",
					      "unknown user");
		} else {
			auth_request_log_error(auth_request, "ldap",
					       "ldap_bind() failed: %s",
					       ldap_err2string(ret));
		}
	}

	passdb_ldap_request->callback.
		verify_plain(passdb_result, auth_request);
        auth_request_unref(&auth_request);
}
static void auth_request_handler_auth_fail(struct auth_request_handler *handler,
					   struct auth_request *request,
					   const char *reason)
{
	string_t *str = t_str_new(128);

	auth_request_log_info(request, request->mech->mech_name, "%s", reason);

	str_printfa(str, "FAIL\t%u\treason=", request->id);
	str_append_tabescaped(str, reason);

	handler->callback(str_c(str), handler->context);
	auth_request_handler_remove(handler, request);
}
Пример #19
0
static void
passwd_verify_plain(struct auth_request *request, const char *password,
		    verify_plain_callback_t *callback)
{
	struct passwd pw;
	int ret;

	auth_request_log_debug(request, "passwd", "lookup");

	switch (i_getpwnam(request->user, &pw)) {
	case -1:
		auth_request_log_error(request, "passwd",
				       "getpwnam() failed: %m");
		callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
		return;
	case 0:
		auth_request_log_unknown_user(request, "passwd");
		callback(PASSDB_RESULT_USER_UNKNOWN, request);
		return;
	}

	if (!IS_VALID_PASSWD(pw.pw_passwd)) {
		auth_request_log_info(request, "passwd",
			"invalid password field '%s'", pw.pw_passwd);
		callback(PASSDB_RESULT_USER_DISABLED, request);
		return;
	}

	/* save the password so cache can use it */
	auth_request_set_field(request, "password", pw.pw_passwd,
			       PASSWD_PASS_SCHEME);

	/* check if the password is valid */
	ret = auth_request_password_verify(request, password, pw.pw_passwd,
					   PASSWD_PASS_SCHEME, "passwd");

	/* clear the passwords from memory */
	safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd));

	if (ret <= 0) {
		callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
		return;
	}

	/* make sure we're using the username exactly as it's in the database */
        auth_request_set_field(request, "user", pw.pw_name, NULL);

	callback(PASSDB_RESULT_OK, request);
}
static bool
postfix_input_user(struct auth_postfix_connection *conn, const char *username)
{
	struct auth_request *auth_request;
	const char *error;

	io_remove(&conn->io);
	if (!postfix_input_auth_request(conn, username,
					&auth_request, &error)) {
		auth_request_log_info(auth_request, "postfix", "%s", error);
		user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
	} else {
		auth_request_set_state(auth_request, AUTH_REQUEST_STATE_USERDB);
		auth_request_lookup_user(auth_request, user_callback);
	}
	return TRUE;
}
static void auth_request_timeout(struct auth_request *request)
{
	unsigned int secs = (unsigned int)(time(NULL) - request->last_access);

	if (request->state != AUTH_REQUEST_STATE_MECH_CONTINUE) {
		/* client's fault */
		auth_request_log_error(request, request->mech->mech_name,
			"Request %u.%u timed out after %u secs, state=%d",
			request->handler->client_pid, request->id,
			secs, request->state);
	} else if (request->set->verbose) {
		auth_request_log_info(request, request->mech->mech_name,
			"Request timed out waiting for client to continue authentication "
			"(%u secs)", secs);
	}
	auth_request_handler_remove(request->handler, request);
}
Пример #22
0
static enum passdb_result
static_save_fields(struct auth_request *request, const char **password_r,
		   const char **scheme_r)
{
	struct static_passdb_module *module =
		(struct static_passdb_module *)request->passdb->passdb;
	const char *error;

	*password_r = NULL;
	*scheme_r = NULL;

	auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup");
	if (passdb_template_export(module->tmpl, request, &error) < 0) {
		auth_request_log_error(request, AUTH_SUBSYS_DB,
			"Failed to expand template: %s", error);
		return PASSDB_RESULT_INTERNAL_FAILURE;
	}

	if (module->static_password_tmpl != NULL) {
		if (t_auth_request_var_expand(module->static_password_tmpl,
				request, NULL, password_r, &error) <= 0) {
			auth_request_log_error(request, AUTH_SUBSYS_DB,
				"Failed to expand password=%s: %s",
				module->static_password_tmpl, error);
			return PASSDB_RESULT_INTERNAL_FAILURE;
		}
	} else if (auth_fields_exists(request->extra_fields, "nopassword")) {
		*password_r = "";
	} else {
		auth_request_log_info(request, AUTH_SUBSYS_DB,
			"No password returned (and no nopassword)");
		return PASSDB_RESULT_PASSWORD_MISMATCH;
	}

	*scheme_r = password_get_scheme(password_r);

	if (*scheme_r == NULL)
		*scheme_r = STATIC_PASS_SCHEME;

	auth_request_set_field(request, "password",
			       *password_r, *scheme_r);

	return PASSDB_RESULT_OK;
}
Пример #23
0
static void passwd_lookup(struct auth_request *auth_request,
			  userdb_callback_t *callback)
{
	struct userdb_module *_module = auth_request->userdb->userdb;
	struct passwd_userdb_module *module =
		(struct passwd_userdb_module *)_module;
	struct passwd pw;
	struct timeval start_tv;
	int ret;

	auth_request_log_debug(auth_request, "passwd", "lookup");

	if (gettimeofday(&start_tv, NULL) < 0)
		start_tv.tv_sec = 0;
	ret = i_getpwnam(auth_request->user, &pw);
	if (start_tv.tv_sec != 0)
		passwd_check_warnings(auth_request, module, &start_tv);

	switch (ret) {
	case -1:
		auth_request_log_error(auth_request, "passwd",
				       "getpwnam() failed: %m");
		callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request);
		return;
	case 0:
		auth_request_log_info(auth_request, "passwd", "unknown user");
		callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
		return;
	}

	auth_request_set_field(auth_request, "user", pw.pw_name, NULL);

	auth_request_init_userdb_reply(auth_request);
	auth_request_set_userdb_field(auth_request, "system_groups_user",
				      pw.pw_name);
	auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid));
	auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid));
	auth_request_set_userdb_field(auth_request, "home", pw.pw_dir);

	userdb_template_export(module->tmpl, auth_request);

	callback(USERDB_RESULT_OK, auth_request);
}
static bool
master_input_user(struct auth_master_connection *conn, const char *args)
{
	struct auth_request *auth_request;
	const char *error;
	int ret;

	ret = master_input_auth_request(conn, args, "USER",
					&auth_request, &error);
	if (ret <= 0) {
		if (ret < 0)
			return FALSE;
		auth_request_log_info(auth_request, "userdb", "%s", error);
		user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request);
	} else {
		auth_request_set_state(auth_request, AUTH_REQUEST_STATE_USERDB);
		auth_request_lookup_user(auth_request, user_callback);
	}
	return TRUE;
}
Пример #25
0
static void
mech_anonymous_auth_continue(struct auth_request *request,
			     const unsigned char *data, size_t data_size)
{
	i_assert(*request->set->anonymous_username != '\0');

	if (request->set->verbose) {
		/* temporarily set the user to the one that was given,
		   so that the log message goes right */
		request->user =
			p_strndup(pool_datastack_create(), data, data_size);
		auth_request_log_info(request, AUTH_SUBSYS_MECH, "login");
	}

	request->user = p_strdup(request->pool,
				 request->set->anonymous_username);

	request->passdb_success = TRUE;
	auth_request_success(request, "", 0);
}
Пример #26
0
static char *
vpopmail_password_lookup(struct auth_request *auth_request, bool *cleartext,
			 enum passdb_result *result_r)
{
	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
	struct vqpasswd *vpw;
	char *password;

	vpw = vpopmail_lookup_vqp(auth_request, vpop_user, vpop_domain);
	if (vpw == NULL) {
		*result_r = PASSDB_RESULT_USER_UNKNOWN;
		return NULL;
	}

	if (vpopmail_is_disabled(auth_request, vpw)) {
		auth_request_log_info(auth_request, AUTH_SUBSYS_DB,
				      "%s disabled in vpopmail for this user",
				      auth_request->service);
		password = NULL;
		*result_r = PASSDB_RESULT_USER_DISABLED;
	} else {
		if (vpw->pw_clear_passwd != NULL &&
		    *vpw->pw_clear_passwd != '\0') {
			password = t_strdup_noconst(vpw->pw_clear_passwd);
			*cleartext = TRUE;
		} else if (!*cleartext)
			password = t_strdup_noconst(vpw->pw_passwd);
		else
			password = NULL;
		*result_r = password != NULL ? PASSDB_RESULT_OK :
			PASSDB_RESULT_SCHEME_NOT_AVAILABLE;
	}

	safe_memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd));
	if (vpw->pw_clear_passwd != NULL) {
		safe_memset(vpw->pw_clear_passwd, 0,
			    strlen(vpw->pw_clear_passwd));
	}

	return password;
}
Пример #27
0
static void ldap_auth_bind(struct ldap_connection *conn,
			   struct ldap_request_bind *brequest)
{
	struct passdb_ldap_request *passdb_ldap_request =
		(struct passdb_ldap_request *)brequest;
	struct auth_request *auth_request = brequest->request.auth_request;

	if (*auth_request->mech_password == '\0') {
		/* Assume that empty password fails. This is especially
		   important with Windows 2003 AD, which always returns success
		   with empty passwords. */
		auth_request_log_info(auth_request, "ldap",
				      "Login attempt with empty password");
		passdb_ldap_request->callback.
			verify_plain(PASSDB_RESULT_PASSWORD_MISMATCH,
				     auth_request);
		return;
	}

	brequest->request.callback = ldap_auth_bind_callback;
	db_ldap_request(conn, &brequest->request);
}
/* return AD realm if it exists */
const char *get_ad_realm ( struct auth_request *auth_request )
{
	const char *out_realm = NULL;

	SCDynamicStoreRef store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("dovecot.digest.auth"), NULL, NULL);
	if ( store ) {
		CFDictionaryRef dict = SCDynamicStoreCopyValue(store, CFSTR("com.apple.opendirectoryd.ActiveDirectory"));
		if (dict) {
			CFStringRef domain = CFDictionaryGetValue(dict, CFSTR("DomainNameFlat"));
			if (domain) {
				const char *ad_realm = CFStringGetCStringPtr(domain, kCFStringEncodingUTF8);
				if (ad_realm) {
					auth_request_log_info(auth_request, "digest-md5", "ad realm: %s", ad_realm);
					out_realm = t_strdup(ad_realm);
				}
			}
			CFRelease(dict);
		}
		CFRelease(store);
	}
	return( out_realm );
}
Пример #29
0
static void
mech_cram_md5_auth_continue(struct auth_request *auth_request,
                            const unsigned char *data, size_t data_size)
{
    struct cram_auth_request *request =
        (struct cram_auth_request *)auth_request;
    const char *error;

    if (parse_cram_response(request, data, data_size, &error)) {
        if (auth_request_set_username(auth_request, request->username,
                                      &error)) {
            auth_request_lookup_credentials(auth_request,
                                            "CRAM-MD5", credentials_callback);
            return;
        }
    }

    if (error == NULL)
        error = "authentication failed";

    auth_request_log_info(auth_request, AUTH_SUBSYS_MECH, "%s", error);
    auth_request_fail(auth_request);
}
Пример #30
0
static void
mech_apop_auth_initial(struct auth_request *auth_request,
		       const unsigned char *data, size_t data_size)
{
	struct apop_auth_request *request =
		(struct apop_auth_request *)auth_request;
	const unsigned char *tmp, *end, *username = NULL;
	unsigned long pid, connect_uid, timestamp;
	const char *error;

	/* pop3-login handles sending the challenge and getting the response.
	   Our input here is: <challenge> \0 <username> \0 <response> */

	if (data_size == 0) {
		/* Should never happen */
		auth_request_log_info(auth_request, "apop",
				      "no initial respone");
		auth_request_fail(auth_request);
		return;
	}

	tmp = data;
	end = data + data_size;

	/* get the challenge */
	while (tmp != end && *tmp != '\0')
		tmp++;
	request->challenge = p_strdup_until(request->pool, data, tmp);

	if (tmp != end) {
		/* get the username */
		username = ++tmp;
		while (tmp != end && *tmp != '\0')
			tmp++;
	}

	if (tmp + 1 + 16 != end) {
		/* Should never happen */
		auth_request_log_info(auth_request, "apop", "malformed data");
		auth_request_fail(auth_request);
		return;
	}
	memcpy(request->response_digest, tmp + 1,
	       sizeof(request->response_digest));

	/* the challenge must begin with trusted unique ID. we trust only
	   ourself, so make sure it matches our connection specific UID
	   which we told to client in handshake. Also require a timestamp
	   which is later than this process's start time. */

	if (sscanf(request->challenge, "<%lx.%lx.%lx.",
		   &pid, &connect_uid, &timestamp) != 3 ||
	    connect_uid != auth_request->connect_uid ||
            pid != (unsigned long)getpid() ||
	    (time_t)timestamp < process_start_time) {
		auth_request_log_info(auth_request, "apop",
				      "invalid challenge");
		auth_request_fail(auth_request);
		return;
	}

	if (!auth_request_set_username(auth_request, (const char *)username,
				       &error)) {
		auth_request_log_info(auth_request, "apop", "%s", error);
		auth_request_fail(auth_request);
		return;
	}

	auth_request_lookup_credentials(auth_request, "PLAIN",
					apop_credentials_callback);
}