static apr_status_t setUserInDb(apr_dbm_t *userDbm,
                                const char *user,
                                const char *password,
                                yubiauth_dir_cfg *cfg,
                                request_rec *r)
{
    char *timeAuthenticated = NULL;
    char *dbToken = NULL; //This is used to store pw:date
    char *userKey = NULL;

    apr_datum_t key, value;
    apr_status_t rv;

    /* Built up some combination of token:time */
    timeAuthenticated = apr_psprintf(r->pool, "%" APR_TIME_T_FMT, (apr_time_t) (apr_time_sec(apr_time_now())));
    dbToken = apr_pstrcat(r->pool, password, ":", timeAuthenticated, NULL);

    /* store OTP:time combo with username as key in DB */
    userKey = getDbKey(user, cfg, r);
    key = string2datum(userKey, r);
    value = string2datum(dbToken, r);

    /* Pump user into db, store un, cookie value, creation date,
     * let this expire sometime
     */
    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r, LOG_PREFIX "Writing key: %s and value: %s to db",
                  key.dptr, value.dptr);
    rv = apr_dbm_store(userDbm, key, value);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, LOG_PREFIX "Error writing to db ... with key: %s and value: %s",
                      key.dptr, value.dptr);
    }
    /* Spit back, so we can decide wheather s.th. went wrong or not */
    return rv;
}
/* User Key because the username is the key to the db */
static void deleteKeyFromDb(apr_dbm_t *userDbm, const char *userKey, request_rec *r)
{
    apr_datum_t key;
    apr_status_t rv;
    key = string2datum(userKey, r);
    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                  LOG_PREFIX "Deleting key %s",
                  key.dptr);
    rv = apr_dbm_delete(userDbm, key);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      LOG_PREFIX "Could not delete key %s",
                      key.dptr);
    }
}
static authn_status authn_check_otp(request_rec *r, const char *user,
                                    const char *password)
{
    apr_status_t rv;
    apr_dbm_t *userDbm = NULL;
    yubiauth_dir_cfg *cfg = ap_get_module_config(r->per_dir_config, &authn_yubikey_module);

    apr_datum_t key,dbUserRecord;
    key.dptr = NULL;
    dbUserRecord.dptr = NULL;

    char *lookedUpToken = NULL;
    char *lookedUpPassword = NULL; //This is the OTP token
    char *dbUserKey = (char *) malloc(sizeof(user));
    apr_size_t passwordLength = 0;
    apr_time_t lookedUpDate = 0;



    /* No username and no password is set */
    if (!*user || !*password)
        return AUTH_DENIED;

    /* Since the password field contains possibly a password and the OTP token, we 
     * have to break that up here
     */
    passwordLength = (apr_size_t) strlen(password) - YUBIKEY_TOKEN_LENGTH;

    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                  LOG_PREFIX "Username is: %s and password is: %s", user, &password[passwordLength]);

    /* Now open the User DB and see if the user really is one of us.
     * for that we save the 12char token:username combo.
     * Ideally we can fill that with the htpasswd utility
     * NOTE: enter full password here
     */
    if (!isUserValid(user, password, cfg, r)) {
      return AUTH_DENIED;
    }

    openDb(&userDbm, cfg->tmpAuthDbFilename, r);

    dbUserKey = strcpy(dbUserKey, user);
    dbUserKey = getDbKey(dbUserKey, cfg, r);
    key = string2datum(dbUserKey, r);
    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r, LOG_PREFIX "Fetching token (pw:time) for user %s from db ...", user);
    rv = apr_dbm_fetch(userDbm, key, &dbUserRecord);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, LOG_PREFIX "unable to fetch the user (%s) from the"
                      "Database, better abort here.", user);
        closeDb(userDbm, r);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    if (dbUserRecord.dptr != NULL) {

        /* it's separated pw:time here */
        const char *sep = ":";
        char *time;

        lookedUpToken = apr_pstrmemdup(r->pool, dbUserRecord.dptr, dbUserRecord.dsize);
        /* Break down the token into it's pw:time components */
        lookedUpPassword = apr_strtok(lookedUpToken, sep, &time);
        lookedUpDate = (apr_time_t) apr_atoi64(time);


        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                      LOG_PREFIX "We could extrace these values from the token:");
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                      LOG_PREFIX "The looked up token for the user: %s",
                      user);
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                      LOG_PREFIX "The looked up password: %s",
                      lookedUpPassword);
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                      LOG_PREFIX "The looked up time: %" APR_TIME_T_FMT,
                      lookedUpDate);
        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
                      LOG_PREFIX "The looked up token: %s",
                      lookedUpToken);
    }
    ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r, LOG_PREFIX "Fetched token (%s) ...", lookedUpToken);

    /* password has to be set, if the pw content is NULL or empty, we have 
     * catched that earlier ...
     */
    if (lookedUpPassword != NULL && !strcmp(lookedUpPassword, &password[passwordLength])) {
        /* The date expired */
        if (passwordExpired(user, lookedUpDate, cfg->timeoutSeconds, r)) {
            /* Delete user record */
            ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_DEBUG, 0, r,
			LOG_PREFIX "Remove expired entry for user : %s",
			user);
            deleteKeyFromDb(userDbm, user, cfg, r);
            closeDb(userDbm, r);
            return AUTH_DENIED;
        }
        else {
            closeDb(userDbm, r);
            return AUTH_GRANTED;
        }
    }
    else {
        int authenticationSuccessful = 0;
        int ret = YUBIKEY_CLIENT_BAD_OTP;
        /* We could not lookup the password, verify the sent password */
        ret = yubikey_client_simple_request(&password[passwordLength], 1, 0, NULL, r);
            if (ret == YUBIKEY_CLIENT_OK) {
                authenticationSuccessful = 1;
            } else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              LOG_PREFIX "Authentication failed, reason: %s",
                              yubikey_client_strerror(ret));
                return AUTH_DENIED;
            }

        /* We could successfully authenticate the user */
        if (authenticationSuccessful) {
            /* Try to write the user into the db */
            if (setUserInDb(userDbm, user, &password[passwordLength], cfg, r)
		!= APR_SUCCESS) {
                /* Abort, we could not write the user into the db after
                 * authenticating him ...
                 */
                closeDb(userDbm, r);
                return HTTP_INTERNAL_SERVER_ERROR;
            }

            /* User could be written to the db*/
            closeDb(userDbm, r);
            return AUTH_GRANTED;
        }

        /* Could not authenticate successful */
        closeDb(userDbm, r);
        return AUTH_DENIED;
    }

    /* Something went wrong or we did not think about it, better deny */
    closeDb(userDbm, r);
    return AUTH_DENIED;
}