~ubuntu-branches/ubuntu/vivid/libapache2-mod-auth-openidc/vivid-proposed

« back to all changes in this revision

Viewing changes to src/cache/shm.c

  • Committer: Package Import Robot
  • Author(s): Hans Zandbelt
  • Date: 2014-10-13 12:23:35 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20141013122335-31wgnq50ascmubib
Tags: 1.6.0-1
new upstream release; add libssl-dev dependency

Show diffs side-by-side

added added

removed removed

Lines of Context:
79
79
/* represents one (fixed size) cache entry, cq. name/value string pair */
80
80
typedef struct oidc_cache_shm_entry_t {
81
81
        /* name of the cache entry */
82
 
        char key[OIDC_CACHE_SHM_KEY_MAX];
 
82
        char section_key[OIDC_CACHE_SHM_KEY_MAX];
83
83
        /* value of the cache entry */
84
84
        char value[OIDC_CACHE_SHM_VALUE_MAX];
85
85
        /* last (read) access timestamp */
90
90
 
91
91
/* create the cache context */
92
92
static void *oidc_cache_shm_cfg_create(apr_pool_t *pool) {
93
 
        oidc_cache_cfg_shm_t *context = apr_pcalloc(pool, sizeof(oidc_cache_cfg_shm_t));
 
93
        oidc_cache_cfg_shm_t *context = apr_pcalloc(pool,
 
94
                        sizeof(oidc_cache_cfg_shm_t));
94
95
        context->mutex_filename = NULL;
95
96
        context->shm = NULL;
96
97
        context->mutex = NULL;
104
105
        oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(s->module_config,
105
106
                        &auth_openidc_module);
106
107
 
107
 
        if (cfg->cache_cfg != NULL) return APR_SUCCESS;
 
108
        if (cfg->cache_cfg != NULL)
 
109
                return APR_SUCCESS;
108
110
        oidc_cache_cfg_shm_t *context = oidc_cache_shm_cfg_create(s->process->pool);
109
111
        cfg->cache_cfg = context;
110
112
 
113
115
                        sizeof(oidc_cache_shm_entry_t) * cfg->cache_shm_size_max,
114
116
                        NULL, s->process->pool);
115
117
        if (rv != APR_SUCCESS) {
116
 
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
117
 
                                "oidc_cache_shm_post_config: apr_shm_create failed to create shared memory segment");
 
118
                oidc_serror(s, "apr_shm_create failed to create shared memory segment");
118
119
                return HTTP_INTERNAL_SERVER_ERROR;
119
120
        }
120
121
 
122
123
        int i;
123
124
        oidc_cache_shm_entry_t *table = apr_shm_baseaddr_get(context->shm);
124
125
        for (i = 0; i < cfg->cache_shm_size_max; i++) {
125
 
                table[i].key[0] = '\0';
 
126
                table[i].section_key[0] = '\0';
126
127
                table[i].access = 0;
127
128
        }
128
129
 
137
138
                        (const char *) context->mutex_filename, APR_LOCK_DEFAULT,
138
139
                        s->process->pool);
139
140
        if (rv != APR_SUCCESS) {
140
 
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
141
 
                                "oidc_cache_shm_post_config: apr_global_mutex_create failed to create mutex on file %s",
 
141
                oidc_serror(s,
 
142
                                "apr_global_mutex_create failed to create mutex on file %s",
142
143
                                context->mutex_filename);
143
144
                return HTTP_INTERNAL_SERVER_ERROR;
144
145
        }
151
152
        rv = unixd_set_global_mutex_perms(context->mutex);
152
153
#endif
153
154
        if (rv != APR_SUCCESS) {
154
 
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
155
 
                                "oidc_cache_shm_post_config: unixd_set_global_mutex_perms failed; could not set permissions ");
 
155
                oidc_serror(s,
 
156
                                "unixd_set_global_mutex_perms failed; could not set permissions ");
156
157
                return HTTP_INTERNAL_SERVER_ERROR;
157
158
        }
158
159
#endif
164
165
 * initialize the shared memory segment in a child process
165
166
 */
166
167
int oidc_cache_shm_child_init(apr_pool_t *p, server_rec *s) {
167
 
        oidc_cfg *cfg = ap_get_module_config(s->module_config, &auth_openidc_module);
168
 
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *)cfg->cache_cfg;
 
168
        oidc_cfg *cfg = ap_get_module_config(s->module_config,
 
169
                        &auth_openidc_module);
 
170
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *) cfg->cache_cfg;
169
171
 
170
172
        /* initialize the lock for the child process */
171
173
        apr_status_t rv = apr_global_mutex_child_init(&context->mutex,
172
174
                        (const char *) context->mutex_filename, p);
173
175
 
174
176
        if (rv != APR_SUCCESS) {
175
 
                ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
176
 
                                "oic_cache_shm_child_init: apr_global_mutex_child_init failed to reopen mutex on file %s",
 
177
                oidc_serror(s,
 
178
                                "apr_global_mutex_child_init failed to reopen mutex on file %s",
177
179
                                context->mutex_filename);
178
180
        }
179
181
 
181
183
}
182
184
 
183
185
/*
 
186
 * assemble single key name based on section/key input
 
187
 */
 
188
static char *oidc_cache_shm_get_key(apr_pool_t *pool, const char *section,
 
189
                const char *key) {
 
190
        return apr_psprintf(pool, "%s:%s", section, key);
 
191
}
 
192
 
 
193
/*
184
194
 * get a value from the shared memory cache
185
195
 */
186
 
static apr_byte_t oidc_cache_shm_get(request_rec *r, const char *key,
187
 
                const char **value) {
 
196
static apr_byte_t oidc_cache_shm_get(request_rec *r, const char *section,
 
197
                const char *key, const char **value) {
188
198
 
189
 
        ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
190
 
                        "oidc_cache_shm_get: entering \"%s\"", key);
 
199
        oidc_debug(r, "enter, section=\"%s\", key=\"%s\"", section, key);
191
200
 
192
201
        oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
193
202
                        &auth_openidc_module);
194
 
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *)cfg->cache_cfg;
 
203
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *) cfg->cache_cfg;
195
204
 
196
205
        apr_status_t rv;
197
206
        int i;
 
207
        const char *section_key = oidc_cache_shm_get_key(r->pool, section, key);
 
208
 
198
209
        *value = NULL;
199
210
 
200
211
        /* grab the global lock */
201
212
        if ((rv = apr_global_mutex_lock(context->mutex)) != APR_SUCCESS) {
202
 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
203
 
                                "oidc_cache_shm_get: apr_global_mutex_lock() failed [%d]", rv);
 
213
                oidc_error(r, "apr_global_mutex_lock() failed [%d]", rv);
204
214
                return FALSE;
205
215
        }
206
216
 
209
219
 
210
220
        /* loop over the block, looking for the key */
211
221
        for (i = 0; i < cfg->cache_shm_size_max; i++) {
212
 
                const char *tablekey = table[i].key;
 
222
                const char *tablekey = table[i].section_key;
213
223
 
214
224
                if (tablekey == NULL)
215
225
                        continue;
216
226
 
217
 
                if (strcmp(tablekey, key) == 0) {
 
227
                if (apr_strnatcmp(tablekey, section_key) == 0) {
218
228
 
219
229
                        /* found a match, check if it has expired */
220
230
                        if (table[i].expires > apr_time_now()) {
235
245
/*
236
246
 * store a value in the shared memory cache
237
247
 */
238
 
static apr_byte_t oidc_cache_shm_set(request_rec *r, const char *key,
239
 
                const char *value, apr_time_t expiry) {
 
248
static apr_byte_t oidc_cache_shm_set(request_rec *r, const char *section,
 
249
                const char *key, const char *value, apr_time_t expiry) {
 
250
 
 
251
        oidc_debug(r, "enter, section=\"%s\", key=\"%s\", value size=%llu", section,
 
252
                        key, value ? (unsigned long long )strlen(value) : 0);
240
253
 
241
254
        oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
242
255
                        &auth_openidc_module);
243
 
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *)cfg->cache_cfg;
244
 
 
245
 
        ap_log_rerror(APLOG_MARK, OIDC_DEBUG, 0, r,
246
 
                        "oidc_cache_shm_set: entering \"%s\" (value size=(%zu)", key,
247
 
                        value ? strlen(value) : 0);
 
256
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *) cfg->cache_cfg;
248
257
 
249
258
        oidc_cache_shm_entry_t *match, *free, *lru;
250
259
        oidc_cache_shm_entry_t *table;
252
261
        int i;
253
262
        apr_time_t age;
254
263
 
 
264
        const char *section_key = oidc_cache_shm_get_key(r->pool, section, key);
 
265
 
255
266
        /* check that the passed in key is valid */
256
 
        if (key == NULL || strlen(key) > OIDC_CACHE_SHM_KEY_MAX) {
257
 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
258
 
                                "oidc_cache_shm_set: could not set value since key is NULL or too long (%s)",
259
 
                                key);
 
267
        if (strlen(section_key) > OIDC_CACHE_SHM_KEY_MAX) {
 
268
                oidc_error(r, "could not set value since key is too long (%s)",
 
269
                                section_key);
260
270
                return FALSE;
261
271
        }
262
272
 
263
273
        /* check that the passed in value is valid */
264
 
        if ( (value != NULL) && strlen(value) > OIDC_CACHE_SHM_VALUE_MAX) {
265
 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
266
 
                                "oidc_cache_shm_set: could not set value since value is too long (%zu > %d)",
 
274
        if ((value != NULL) && strlen(value) > OIDC_CACHE_SHM_VALUE_MAX) {
 
275
                oidc_error(r, "could not set value since value is too long (%zu > %d)",
267
276
                                strlen(value), OIDC_CACHE_SHM_VALUE_MAX);
268
277
                return FALSE;
269
278
        }
270
279
 
271
280
        /* grab the global lock */
272
281
        if (apr_global_mutex_lock(context->mutex) != APR_SUCCESS) {
273
 
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
274
 
                                "oidc_cache_shm_set: apr_global_mutex_lock() failed");
 
282
                oidc_error(r, "apr_global_mutex_lock() failed");
275
283
                return FALSE;
276
284
        }
277
285
 
288
296
        for (i = 0; i < cfg->cache_shm_size_max; i++) {
289
297
 
290
298
                /* see if this slot is free */
291
 
                if (table[i].key[0] == '\0') {
292
 
                        if (free == NULL) free = &table[i];
 
299
                if (table[i].section_key[0] == '\0') {
 
300
                        if (free == NULL)
 
301
                                free = &table[i];
293
302
                        continue;
294
303
                }
295
304
 
296
305
                /* see if a value already exists for this key */
297
 
                if (strcmp(table[i].key, key) == 0) {
 
306
                if (apr_strnatcmp(table[i].section_key, section_key) == 0) {
298
307
                        match = &table[i];
299
308
                        break;
300
309
                }
301
310
 
302
311
                /* see if this slot has expired */
303
312
                if (table[i].expires <= current_time) {
304
 
                        if (free == NULL) free = &table[i];
 
313
                        if (free == NULL)
 
314
                                free = &table[i];
305
315
                        continue;
306
316
                }
307
317
 
316
326
        if (match == NULL && free == NULL) {
317
327
                age = (current_time - lru->access) / 1000000;
318
328
                if (age < 3600) {
319
 
                        ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
320
 
                                        "oidc_cache_shm_set: dropping LRU entry with age = %" APR_TIME_T_FMT "s, which is less than one hour; consider increasing the shared memory caching space (which is %d now) with the (global) OIDCCacheShmMax setting.",
 
329
                        oidc_warn(r,
 
330
                                        "dropping LRU entry with age = %" APR_TIME_T_FMT "s, which is less than one hour; consider increasing the shared memory caching space (which is %d now) with the (global) OIDCCacheShmMax setting.",
321
331
                                        age, cfg->cache_shm_size_max);
322
332
                }
323
333
        }
327
337
        if (value != NULL) {
328
338
 
329
339
                /* fill out the entry with the provided data */
330
 
                strcpy(t->key, key);
 
340
                strcpy(t->section_key, section_key);
331
341
                strcpy(t->value, value);
332
342
                t->expires = expiry;
333
343
                t->access = current_time;
334
344
 
335
345
        } else {
336
346
 
337
 
                t->key[0] = '\0';
 
347
                t->section_key[0] = '\0';
338
348
        }
339
349
 
340
350
        /* release the global lock */
344
354
}
345
355
 
346
356
static int oidc_cache_shm_destroy(server_rec *s) {
347
 
        oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(
348
 
                        s->module_config, &auth_openidc_module);
349
 
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *)cfg->cache_cfg;
 
357
        oidc_cfg *cfg = (oidc_cfg *) ap_get_module_config(s->module_config,
 
358
                        &auth_openidc_module);
 
359
        oidc_cache_cfg_shm_t *context = (oidc_cache_cfg_shm_t *) cfg->cache_cfg;
350
360
        apr_status_t rv = APR_SUCCESS;
351
361
 
352
 
    if (context->shm) {
353
 
        rv = apr_shm_destroy(context->shm);
354
 
        ap_log_error(APLOG_MARK, OIDC_DEBUG, rv, s,
355
 
                        "oidc_cache_shm_destroy: apr_shm_destroy returned: %d", rv);
356
 
        context->shm = NULL;
357
 
    }
 
362
        if (context->shm) {
 
363
                rv = apr_shm_destroy(context->shm);
 
364
                oidc_sdebug(s, "apr_shm_destroy returned: %d", rv);
 
365
                context->shm = NULL;
 
366
        }
358
367
 
359
 
    if (context->mutex) {
360
 
        rv = apr_global_mutex_destroy(context->mutex);
361
 
        ap_log_error(APLOG_MARK, OIDC_DEBUG, rv, s,
362
 
                        "oidc_cache_shm_destroy: apr_global_mutex_destroy returned: %d", rv);
363
 
        context->mutex = NULL;
364
 
    }
 
368
        if (context->mutex) {
 
369
                rv = apr_global_mutex_destroy(context->mutex);
 
370
                oidc_sdebug(s, "apr_global_mutex_destroy returned: %d", rv);
 
371
                context->mutex = NULL;
 
372
        }
365
373
 
366
374
        return rv;
367
375
}