~ubuntu-branches/ubuntu/trusty/apache2/trusty

« back to all changes in this revision

Viewing changes to srclib/apr-util/dbd/apr_dbd_pgsql.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Fritsch, Stefan Fritsch, Peter Samuelson
  • Date: 2007-07-01 19:57:51 UTC
  • mfrom: (0.8.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070701195751-kcags6dpm5up3li5
Tags: 2.2.4-1
[ Stefan Fritsch ]
* Urgency medium for security fix
* Fix CVE-2007-1863: DoS in mod_cache
* New upstream version (Closes: #427050)
  - Fixes "proxy: error reading status line from remote server"
    (Closes: #410331)
* Fix CVE-2007-1862: mod_mem_cache DoS (introduced in 2.2.4)
* Change logrotate script to use reload instead of restart.
  (Closes: #298689)
* chmod o-rx /var/log/apache2 (Closes: #291841)
* chmod o-x suexec (Closes: #431048)
* Update patch for truncated mod_cgi 500 responses from upstream SVN
  (Closes: #412580)
* Don't use AddDefaultCharset for our docs (Closes: #414429)
* fix options syntax in sites-available/default (Closes: #419539)
* Move conf.d include to the end of apache2.conf (Closes: #305933)
* Remove log, cache, and lock files on purge (Closes: #428887)
* Ship /usr/lib/cgi-bin (Closes: #415698)
* Add note to README.Debian how to read docs (Closes: #350822)
* Document pid file name (Closes: #350286)
* Update Standards-Version (no changes needed)
* Fix some lintian warnings, add some overrides
* Start apache when doing a "restart" even if it was not running
  (Closes: #384682)
* reload config in apache2-doc postinst (Closes: #289289)
* don't fail in prerm if apache is not running (Closes: #418536)
* Suggest apache2-doc and www-browser (Closes: #399056)
* Make init script always display a warning if NO_START=1 since
  VERBOSE=yes is not the default anymore (Closes: #430116)
* Replace apache2(8) man page with a more current version
* Add httxt2dbm(8) man page
* Show -X option in help message (Closes: #391817)
* remove sick-hack-to-update-modules
* don't depend on procps on hurd (Closes: #431125)

[ Peter Samuelson ]
* Add shlibs:Depends to apache2.2-common.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
#if APU_HAVE_PGSQL
20
20
 
 
21
#include "apu_config.h"
 
22
 
21
23
#include <ctype.h>
22
24
#include <stdlib.h>
23
25
 
 
26
#ifdef HAVE_LIBPQ_FE_H
24
27
#include <libpq-fe.h>
 
28
#elif defined(HAVE_POSTGRESQL_LIBPQ_FE_H)
 
29
#include <postgresql/libpq-fe.h>
 
30
#endif
25
31
 
26
32
#include "apr_strings.h"
27
33
#include "apr_time.h"
57
63
struct apr_dbd_prepared_t {
58
64
    const char *name;
59
65
    int prepared;
 
66
    int nargs;
60
67
};
61
68
 
62
69
#define dbd_pgsql_is_success(x) (((x) == PGRES_EMPTY_QUERY) \
63
70
                                 || ((x) == PGRES_COMMAND_OK) \
64
71
                                 || ((x) == PGRES_TUPLES_OK))
65
72
 
 
73
static apr_status_t clear_result(void *data)
 
74
{
 
75
    PQclear(data);
 
76
    return APR_SUCCESS;
 
77
}
 
78
 
66
79
static int dbd_pgsql_select(apr_pool_t *pool, apr_dbd_t *sql,
67
80
                            apr_dbd_results_t **results,
68
81
                            const char *query, int seek)
97
110
        (*results)->ntuples = PQntuples(res);
98
111
        (*results)->sz = PQnfields(res);
99
112
        (*results)->random = seek;
100
 
        apr_pool_cleanup_register(pool, res, (void*)PQclear,
 
113
        apr_pool_cleanup_register(pool, res, clear_result,
101
114
                                  apr_pool_cleanup_null);
102
115
    }
103
116
    else {
140
153
    if (res->random) {
141
154
        if (row->n >= res->ntuples) {
142
155
            *rowp = NULL;
143
 
            apr_pool_cleanup_kill(pool, res->res, (void*)PQclear);
144
 
            PQclear(res->res);
 
156
            apr_pool_cleanup_run(pool, res->res, clear_result);
145
157
            res->res = NULL;
146
158
            return -1;
147
159
        }
221
233
                                    apr_dbd_t *sql)
222
234
{
223
235
    size_t len = strlen(arg);
224
 
    char *ret = apr_palloc(pool, len + 1);
 
236
    char *ret = apr_palloc(pool, 2*(len + 1));
225
237
    PQescapeString(ret, arg, len);
226
238
    return ret;
227
239
}
236
248
    size_t i = 0;
237
249
    const char *args[QUERY_MAX_ARGS];
238
250
    size_t alen;
239
 
    int nargs = 0;
240
251
    int ret;
241
252
    PGresult *res;
242
253
    char *pgquery;
245
256
    if (!*statement) {
246
257
        *statement = apr_palloc(pool, sizeof(apr_dbd_prepared_t));
247
258
    }
 
259
    (*statement)->nargs = 0;
248
260
    /* Translate from apr_dbd to native query format */
249
261
    for (sqlptr = (char*)query; *sqlptr; ++sqlptr) {
250
262
        if (sqlptr[0] == '%') {
251
263
            if (isalpha(sqlptr[1])) {
252
 
                ++nargs;
 
264
                ++(*statement)->nargs;
253
265
            }
254
266
            else if (sqlptr[1] == '%') {
255
267
                ++sqlptr;
257
269
        }
258
270
    }
259
271
    length = strlen(query) + 1;
260
 
    if (nargs > 8) {
261
 
        length += nargs - 8;
 
272
    if ((*statement)->nargs > 8) {
 
273
        length += (*statement)->nargs - 8;
262
274
    }
263
275
    pgptr = pgquery = apr_palloc(pool, length) ;
264
276
 
313
325
    length = strlen(label);
314
326
    memcpy(sqlptr, label, length);
315
327
    sqlptr += length;
316
 
    if (nargs > 0) {
 
328
    if ((*statement)->nargs > 0) {
317
329
        memcpy(sqlptr, " (",2);
318
330
        sqlptr += 2;
319
 
        for (i=0; i<nargs; ++i) {
 
331
        for (i=0; i < (*statement)->nargs; ++i) {
320
332
            alen = strlen(args[i]);
321
333
            memcpy(sqlptr, args[i], alen);
322
334
            sqlptr += alen;
353
365
{
354
366
    int ret;
355
367
    PGresult *res;
 
368
 
 
369
    if (sql->trans && sql->trans->errnum) {
 
370
        return sql->trans->errnum;
 
371
    }
 
372
 
356
373
    if (statement->prepared) {
357
374
        res = PQexecPrepared(sql->conn, statement->name, nargs, values, 0, 0,
358
375
                             0);
366
383
        if (dbd_pgsql_is_success(ret)) {
367
384
            ret = 0;
368
385
        }
 
386
        *nrows = atoi(PQcmdTuples(res));
369
387
        PQclear(res);
370
388
    }
371
389
    else {
382
400
                             int *nrows, apr_dbd_prepared_t *statement,
383
401
                             va_list args)
384
402
{
385
 
    const char *arg;
386
 
    int nargs = 0;
387
 
    const char *values[QUERY_MAX_ARGS];
 
403
    const char **values;
 
404
    int i;
388
405
 
389
406
    if (sql->trans && sql->trans->errnum) {
390
407
        return sql->trans->errnum;
391
408
    }
392
 
    while ( arg = va_arg(args, const char*), arg ) {
393
 
        if ( nargs >= QUERY_MAX_ARGS) {
394
 
            va_end(args);
395
 
            return -1;
396
 
        }
397
 
        values[nargs++] = apr_pstrdup(pool, arg);
 
409
 
 
410
    values = apr_palloc(pool, sizeof(*values) * statement->nargs);
 
411
 
 
412
    for (i = 0; i < statement->nargs; i++) {
 
413
        values[i] = apr_pstrdup(pool, va_arg(args, const char*));
398
414
    }
399
 
    values[nargs] = NULL;
400
 
    return dbd_pgsql_pquery(pool, sql, nrows, statement, nargs, values);
 
415
 
 
416
    return dbd_pgsql_pquery(pool, sql, nrows, statement,
 
417
                            statement->nargs, values);
401
418
}
402
419
 
403
420
static int dbd_pgsql_pselect(apr_pool_t *pool, apr_dbd_t *sql,
408
425
    PGresult *res;
409
426
    int rv;
410
427
    int ret = 0;
 
428
 
 
429
    if (sql->trans && sql->trans->errnum) {
 
430
        return sql->trans->errnum;
 
431
    }
 
432
 
411
433
    if (seek) { /* synchronous query */
412
434
        if (statement->prepared) {
413
435
            res = PQexecPrepared(sql->conn, statement->name, nargs, values, 0,
442
464
        (*results)->ntuples = PQntuples(res);
443
465
        (*results)->sz = PQnfields(res);
444
466
        (*results)->random = seek;
445
 
        apr_pool_cleanup_register(pool, res, (void*)PQclear,
 
467
        apr_pool_cleanup_register(pool, res, clear_result,
446
468
                                  apr_pool_cleanup_null);
447
469
    }
448
470
    else {
478
500
                              apr_dbd_prepared_t *statement,
479
501
                              int seek, va_list args)
480
502
{
481
 
    const char *arg;
482
 
    int nargs = 0;
483
 
    const char *values[QUERY_MAX_ARGS];
 
503
    const char **values;
 
504
    int i;
484
505
 
485
506
    if (sql->trans && sql->trans->errnum) {
486
507
        return sql->trans->errnum;
487
508
    }
488
509
 
489
 
    while (arg = va_arg(args, const char*), arg) {
490
 
        if ( nargs >= QUERY_MAX_ARGS) {
491
 
            va_end(args);
492
 
            return -1;
493
 
        }
494
 
        values[nargs++] = apr_pstrdup(pool, arg);
 
510
    values = apr_palloc(pool, sizeof(*values) * statement->nargs);
 
511
 
 
512
    for (i = 0; i < statement->nargs; i++) {
 
513
        values[i] = apr_pstrdup(pool, va_arg(args, const char*));
495
514
    }
 
515
 
496
516
    return dbd_pgsql_pselect(pool, sql, results, statement,
497
 
                             seek, nargs, values) ;
 
517
                             seek, statement->nargs, values) ;
498
518
}
499
519
 
500
520
static int dbd_pgsql_start_transaction(apr_pool_t *pool, apr_dbd_t *handle,