View | Details | Raw Unified | Return to bug 47295
Collapse All | Expand All

(-)modules/aaa/mod_authn_dbd.c (-4 / +136 lines)
Lines 30-42 Link Here
30
30
31
typedef struct {
31
typedef struct {
32
    const char *user;
32
    const char *user;
33
    const char *uparams;
33
    const char *realm;
34
    const char *realm;
35
    const char *rparams;
34
} authn_dbd_conf;
36
} authn_dbd_conf;
35
typedef struct {
37
typedef struct {
36
    const char *label;
38
    const char *label;
37
    const char *query;
39
    const char *query;
38
} authn_dbd_rec;
40
} authn_dbd_rec;
39
41
42
/* replacement in query format */
43
#define QUERY_FMT_USERNAME      'u'
44
#define QUERY_FMT_PASSWORD      'p'
45
#define QUERY_FMT_REALM         'r'
46
#define QUERY_FMT_REMOTE_ADDR   'a'
47
#define QUERY_FMT_USER_DEFAULT  "p"
48
#define QUERY_FMT_REALM_DEFAULT "ur"
49
40
/* optional function - look it up once in post_config */
50
/* optional function - look it up once in post_config */
41
static ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL;
51
static ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL;
42
static void (*authn_dbd_prepare_fn)(server_rec*, const char*, const char*) = NULL;
52
static void (*authn_dbd_prepare_fn)(server_rec*, const char*, const char*) = NULL;
Lines 52-58 Link Here
52
    authn_dbd_conf *base = BASE;
62
    authn_dbd_conf *base = BASE;
53
    authn_dbd_conf *ret = apr_palloc(pool, sizeof(authn_dbd_conf));
63
    authn_dbd_conf *ret = apr_palloc(pool, sizeof(authn_dbd_conf));
54
    ret->user = (add->user == NULL) ? base->user : add->user;
64
    ret->user = (add->user == NULL) ? base->user : add->user;
65
    ret->uparams = (add->user == NULL) ? base->uparams : add->uparams;
55
    ret->realm = (add->realm == NULL) ? base->realm : add->realm;
66
    ret->realm = (add->realm == NULL) ? base->realm : add->realm;
67
    ret->rparams = (add->realm == NULL) ? base->rparams : add->rparams;
56
    return ret;
68
    return ret;
57
}
69
}
58
static const char *authn_dbd_prepare(cmd_parms *cmd, void *cfg, const char *query)
70
static const char *authn_dbd_prepare(cmd_parms *cmd, void *cfg, const char *query)
Lines 74-79 Link Here
74
    /* save the label here for our own use */
86
    /* save the label here for our own use */
75
    return ap_set_string_slot(cmd, cfg, label);
87
    return ap_set_string_slot(cmd, cfg, label);
76
}
88
}
89
static const char *setup_query_fmt(apr_pool_t *p, const char *query,
90
                                   const char **result_params)
91
{
92
    char   *copy, *pos, *params, *tmp;
93
    int     pnums = 0, plimit = 0;
94
95
    copy = apr_palloc(p, strlen(query) + 1);
96
    params = apr_palloc(p, plimit + 1);
97
98
    for (pos = copy; *query != '\0'; query++) {
99
        if (*query != '$') {
100
            *pos++ = *query;
101
            continue;
102
        }
103
        /* expand parameter buffer */
104
        if (pnums == plimit) {
105
            plimit += 10;
106
            tmp = apr_palloc(p, plimit + 1);
107
            strcpy(tmp, params);
108
            params = tmp;
109
        }
110
        /* replace format string to %s */
111
        if (strncmp(query, "$(username)", 11) == 0) {
112
            query += 10;
113
            pos += sprintf(pos, "%%s");
114
            params[pnums++] = QUERY_FMT_USERNAME;
115
        }
116
        else if (strncmp(query, "$(password)", 11) == 0) {
117
            query += 10;
118
            pos += sprintf(pos, "%%s");
119
            params[pnums++] = QUERY_FMT_PASSWORD;
120
        }
121
        else if (strncmp(query, "$(realm)", 8) == 0) {
122
            query += 7;
123
            pos += sprintf(pos, "%%s");
124
            params[pnums++] = QUERY_FMT_REALM;
125
        }
126
        else if (strncmp(query, "$(remote_addr)", 14) == 0) {
127
            query += 13;
128
            pos += sprintf(pos, "%%s");
129
            params[pnums++] = QUERY_FMT_REMOTE_ADDR;
130
        }
131
        else {
132
            /* keep the unknown $... */
133
            *pos++ = *query;
134
        }
135
    }
136
    *pos = '\0';
137
    params[pnums++] = '\0';
138
139
    *result_params = params;
140
    return copy;
141
}
142
static const char *set_user_query_fmt(cmd_parms *cmd, void *cfg, const char *query)
143
{
144
    authn_dbd_conf *conf = cfg;
145
    const char *new_query
146
        = setup_query_fmt(cmd->pool, query, &conf->uparams);
147
    /* do the normal setups */
148
    return authn_dbd_prepare(cmd, cfg, new_query);
149
}
150
static const char *set_realm_query_fmt(cmd_parms *cmd, void *cfg, const char *query)
151
{
152
    authn_dbd_conf *conf = cfg;
153
    const char *new_query
154
        = setup_query_fmt(cmd->pool, query, &conf->rparams);
155
    /* do the normal setups */
156
    return authn_dbd_prepare(cmd, cfg, new_query);
157
}
77
static const command_rec authn_dbd_cmds[] =
158
static const command_rec authn_dbd_cmds[] =
78
{
159
{
79
    AP_INIT_TAKE1("AuthDBDUserPWQuery", authn_dbd_prepare,
160
    AP_INIT_TAKE1("AuthDBDUserPWQuery", authn_dbd_prepare,
Lines 82-89 Link Here
82
    AP_INIT_TAKE1("AuthDBDUserRealmQuery", authn_dbd_prepare,
163
    AP_INIT_TAKE1("AuthDBDUserRealmQuery", authn_dbd_prepare,
83
                  (void *)APR_OFFSETOF(authn_dbd_conf, realm), ACCESS_CONF,
164
                  (void *)APR_OFFSETOF(authn_dbd_conf, realm), ACCESS_CONF,
84
                  "Query used to fetch password for user+realm"),
165
                  "Query used to fetch password for user+realm"),
166
    AP_INIT_TAKE1("AuthDBDUserPWQueryFmt", set_user_query_fmt,
167
                  (void *)APR_OFFSETOF(authn_dbd_conf, user), ACCESS_CONF,
168
                  "Query used to fetch password for user"),
169
    AP_INIT_TAKE1("AuthDBDUserRealmQueryFmt", set_realm_query_fmt,
170
                  (void *)APR_OFFSETOF(authn_dbd_conf, realm), ACCESS_CONF,
171
                  "Query used to fetch password for user+realm"),
85
    {NULL}
172
    {NULL}
86
};
173
};
174
static void authn_dbd_setup_params(request_rec *r, const char *params,
175
                                   const char ***args, int *nargs,
176
                                   const char *username,
177
                                   const char *password,
178
                                   const char *realm)
179
{
180
    const char **ptable = NULL;
181
    int c, index = 0;
182
183
    ptable = apr_palloc(r->pool, sizeof(const char *) * strlen(params));
184
185
    while ((c = *params++) != '\0') {
186
        switch (c) {
187
        case QUERY_FMT_USERNAME:
188
            ptable[index++] = username;
189
            break;
190
        case QUERY_FMT_PASSWORD:
191
            ptable[index++] = password;
192
            break;
193
        case QUERY_FMT_REALM:
194
            ptable[index++] = realm;
195
            break;
196
        case QUERY_FMT_REMOTE_ADDR:
197
            ptable[index++] = r->connection->remote_ip;
198
            break;
199
        default:
200
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
201
                          "Bug? unexpected format: %c", c);
202
            break;
203
        }
204
    }
205
206
    *args = ptable;
207
    *nargs = index;
208
}
87
static authn_status authn_dbd_password(request_rec *r, const char *user,
209
static authn_status authn_dbd_password(request_rec *r, const char *user,
88
                                       const char *password)
210
                                       const char *password)
89
{
211
{
Lines 92-97 Link Here
92
    apr_dbd_prepared_t *statement;
214
    apr_dbd_prepared_t *statement;
93
    apr_dbd_results_t *res = NULL;
215
    apr_dbd_results_t *res = NULL;
94
    apr_dbd_row_t *row = NULL;
216
    apr_dbd_row_t *row = NULL;
217
    const char **args;
218
    int nargs;
95
219
96
    authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
220
    authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
97
                                                &authn_dbd_module);
221
                                                &authn_dbd_module);
Lines 116-123 Link Here
116
                      "AuthDBDUserPWQuery with the key '%s'", conf->user);
240
                      "AuthDBDUserPWQuery with the key '%s'", conf->user);
117
        return AUTH_GENERAL_ERROR;
241
        return AUTH_GENERAL_ERROR;
118
    }
242
    }
119
    if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement,
243
120
                              0, user, NULL) != 0) {
244
    authn_dbd_setup_params(r, conf->uparams ? conf->uparams : QUERY_FMT_USER_DEFAULT,
245
                           &args, &nargs, user, password, NULL);
246
    if (apr_dbd_pselect(dbd->driver, r->pool, dbd->handle, &res,
247
                        statement, 0, nargs, args) != 0) {
121
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
248
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
122
                      "Query execution error looking up '%s' "
249
                      "Query execution error looking up '%s' "
123
                      "in database", user);
250
                      "in database", user);
Lines 184-189 Link Here
184
    apr_dbd_prepared_t *statement;
311
    apr_dbd_prepared_t *statement;
185
    apr_dbd_results_t *res = NULL;
312
    apr_dbd_results_t *res = NULL;
186
    apr_dbd_row_t *row = NULL;
313
    apr_dbd_row_t *row = NULL;
314
    const char **args;
315
    int nargs;
187
316
188
    authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
317
    authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
189
                                                &authn_dbd_module);
318
                                                &authn_dbd_module);
Lines 206-213 Link Here
206
                      "AuthDBDUserRealmQuery with the key '%s'", conf->realm);
335
                      "AuthDBDUserRealmQuery with the key '%s'", conf->realm);
207
        return AUTH_GENERAL_ERROR;
336
        return AUTH_GENERAL_ERROR;
208
    }
337
    }
209
    if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement,
338
210
                              0, user, realm, NULL) != 0) {
339
    authn_dbd_setup_params(r, conf->rparams ? conf->rparams : QUERY_FMT_REALM_DEFAULT,
340
                           &args, &nargs, user, NULL, realm);
341
    if (apr_dbd_pselect(dbd->driver, r->pool, dbd->handle, &res,
342
                        statement, 0, nargs, args) != 0) {
211
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
343
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
212
                      "Query execution error looking up '%s:%s' "
344
                      "Query execution error looking up '%s:%s' "
213
                      "in database", user, realm);
345
                      "in database", user, realm);

Return to bug 47295