~ubuntu-branches/ubuntu/lucid/psqlodbc/lucid

« back to all changes in this revision

Viewing changes to drvconn.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-05-13 10:47:36 UTC
  • Revision ID: james.westby@ubuntu.com-20040513104736-a530gmn0p3knep89
Tags: upstream-07.03.0200
ImportĀ upstreamĀ versionĀ 07.03.0200

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------
 
2
  Module:                       drvconn.c
 
3
 *
 
4
 * Description:         This module contains only routines related to
 
5
 *                                      implementing SQLDriverConnect.
 
6
 *
 
7
 * Classes:                     n/a
 
8
 *
 
9
 * API functions:       SQLDriverConnect
 
10
 *
 
11
 * Comments:            See "notice.txt" for copyright and license information.
 
12
 *-------
 
13
 */
 
14
 
 
15
#include "psqlodbc.h"
 
16
 
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
 
 
20
#include "connection.h"
 
21
 
 
22
#ifndef WIN32
 
23
#include <sys/types.h>
 
24
#include <sys/socket.h>
 
25
#define NEAR
 
26
#else
 
27
#include <winsock.h>
 
28
#endif
 
29
 
 
30
#include <string.h>
 
31
 
 
32
#ifdef WIN32
 
33
#include <windowsx.h>
 
34
#include "resource.h"
 
35
#endif
 
36
#include "pgapifunc.h"
 
37
 
 
38
#ifndef TRUE
 
39
#define TRUE    (BOOL)1
 
40
#endif
 
41
#ifndef FALSE
 
42
#define FALSE   (BOOL)0
 
43
#endif
 
44
 
 
45
#include "dlg_specific.h"
 
46
 
 
47
#define NULL_IF_NULL(a) (a ? a : "(NULL)")
 
48
 
 
49
static char * hide_password(const char *str)
 
50
{
 
51
        char *outstr, *pwdp;
 
52
 
 
53
        if (!str)       return NULL;
 
54
        outstr = strdup(str);
 
55
        if (pwdp = strstr(outstr, "PWD="), !pwdp)
 
56
                pwdp = strstr(outstr, "pwd=");
 
57
        if (pwdp)
 
58
        {
 
59
                char    *p;
 
60
 
 
61
                for (p=pwdp + 4; *p && *p != ';'; p++)
 
62
                        *p = 'x';
 
63
        }
 
64
        return outstr;
 
65
}
 
66
 
 
67
/* prototypes */
 
68
void            dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci);
 
69
static void dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci);
 
70
 
 
71
#ifdef WIN32
 
72
BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
 
73
RETCODE         dconn_DoDialog(HWND hwnd, ConnInfo *ci);
 
74
 
 
75
extern HINSTANCE NEAR s_hModule;        /* Saved module handle. */
 
76
#endif
 
77
 
 
78
 
 
79
RETCODE         SQL_API
 
80
PGAPI_DriverConnect(
 
81
                                        HDBC hdbc,
 
82
                                        HWND hwnd,
 
83
                                        UCHAR FAR * szConnStrIn,
 
84
                                        SWORD cbConnStrIn,
 
85
                                        UCHAR FAR * szConnStrOut,
 
86
                                        SWORD cbConnStrOutMax,
 
87
                                        SWORD FAR * pcbConnStrOut,
 
88
                                        UWORD fDriverCompletion)
 
89
{
 
90
        CSTR func = "PGAPI_DriverConnect";
 
91
        ConnectionClass *conn = (ConnectionClass *) hdbc;
 
92
        ConnInfo   *ci;
 
93
 
 
94
#ifdef WIN32
 
95
        RETCODE         dialog_result;
 
96
#endif
 
97
        RETCODE         result;
 
98
        char            connStrIn[MAX_CONNECT_STRING];
 
99
        char            connStrOut[MAX_CONNECT_STRING];
 
100
        int                     retval;
 
101
        char            salt[5];
 
102
        char            password_required = AUTH_REQ_OK;
 
103
        int                     len = 0;
 
104
        SWORD           lenStrout;
 
105
 
 
106
 
 
107
        mylog("%s: entering...\n", func);
 
108
 
 
109
        if (!conn)
 
110
        {
 
111
                CC_log_error(func, "", NULL);
 
112
                return SQL_INVALID_HANDLE;
 
113
        }
 
114
 
 
115
        make_string(szConnStrIn, cbConnStrIn, connStrIn);
 
116
 
 
117
#ifdef  FORCE_PASSWORD_DISPLAY
 
118
        mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
 
119
        qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
 
120
#else
 
121
        if (get_qlog() || get_mylog())
 
122
        {
 
123
                char    *hide_str = hide_password(connStrIn);
 
124
 
 
125
                mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, NULL_IF_NULL(hide_str));
 
126
                qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, NULL_IF_NULL(hide_str), fDriverCompletion);
 
127
                if (hide_str)
 
128
                        free(hide_str);
 
129
        }
 
130
#endif  /* FORCE_PASSWORD_DISPLAY */
 
131
 
 
132
        ci = &(conn->connInfo);
 
133
 
 
134
        /* Parse the connect string and fill in conninfo for this hdbc. */
 
135
        dconn_get_connect_attributes(connStrIn, ci);
 
136
 
 
137
        /*
 
138
         * If the ConnInfo in the hdbc is missing anything, this function will
 
139
         * fill them in from the registry (assuming of course there is a DSN
 
140
         * given -- if not, it does nothing!)
 
141
         */
 
142
        getDSNinfo(ci, CONN_DONT_OVERWRITE);
 
143
        dconn_get_common_attributes(connStrIn, ci);
 
144
        logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
 
145
 
 
146
        /* Fill in any default parameters if they are not there. */
 
147
        getDSNdefaults(ci);
 
148
        /* initialize pg_version */
 
149
        CC_initialize_pg_version(conn);
 
150
        salt[0] = '\0';
 
151
 
 
152
#ifdef WIN32
 
153
dialog:
 
154
#endif
 
155
        ci->focus_password = password_required;
 
156
 
 
157
        switch (fDriverCompletion)
 
158
        {
 
159
#ifdef WIN32
 
160
                case SQL_DRIVER_PROMPT:
 
161
                        dialog_result = dconn_DoDialog(hwnd, ci);
 
162
                        if (dialog_result != SQL_SUCCESS)
 
163
                                return dialog_result;
 
164
                        break;
 
165
 
 
166
                case SQL_DRIVER_COMPLETE_REQUIRED:
 
167
 
 
168
                        /* Fall through */
 
169
 
 
170
                case SQL_DRIVER_COMPLETE:
 
171
 
 
172
                        /* Password is not a required parameter. */
 
173
                        if (ci->username[0] == '\0' ||
 
174
                                ci->server[0] == '\0' ||
 
175
                                ci->database[0] == '\0' ||
 
176
                                ci->port[0] == '\0' ||
 
177
                                password_required)
 
178
                        {
 
179
                                dialog_result = dconn_DoDialog(hwnd, ci);
 
180
                                if (dialog_result != SQL_SUCCESS)
 
181
                                        return dialog_result;
 
182
                        }
 
183
                        break;
 
184
#else
 
185
                case SQL_DRIVER_PROMPT:
 
186
                case SQL_DRIVER_COMPLETE:
 
187
                case SQL_DRIVER_COMPLETE_REQUIRED:
 
188
#endif
 
189
                case SQL_DRIVER_NOPROMPT:
 
190
                        break;
 
191
        }
 
192
 
 
193
        /*
 
194
         * Password is not a required parameter unless authentication asks for
 
195
         * it. For now, I think it's better to just let the application ask
 
196
         * over and over until a password is entered (the user can always hit
 
197
         * Cancel to get out)
 
198
         */
 
199
        if (ci->username[0] == '\0' ||
 
200
                ci->server[0] == '\0' ||
 
201
                ci->database[0] == '\0' ||
 
202
                ci->port[0] == '\0')
 
203
        {
 
204
                /* (password_required && ci->password[0] == '\0')) */
 
205
 
 
206
                return SQL_NO_DATA_FOUND;
 
207
        }
 
208
 
 
209
        /* do the actual connect */
 
210
        retval = CC_connect(conn, password_required, salt);
 
211
        if (retval < 0)
 
212
        {                                                       /* need a password */
 
213
                if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
 
214
                {
 
215
                        CC_log_error(func, "Need password but Driver_NoPrompt", conn);
 
216
                        return SQL_ERROR;       /* need a password but not allowed to
 
217
                                                                 * prompt so error */
 
218
                }
 
219
                else
 
220
                {
 
221
#ifdef WIN32
 
222
                        password_required = -retval;
 
223
                        goto dialog;
 
224
#else
 
225
                        return SQL_ERROR;       /* until a better solution is found. */
 
226
#endif
 
227
                }
 
228
        }
 
229
        else if (retval == 0)
 
230
        {
 
231
                /* error msg filled in above */
 
232
                CC_log_error(func, "Error from CC_Connect", conn);
 
233
                return SQL_ERROR;
 
234
        }
 
235
 
 
236
        /*
 
237
         * Create the Output Connection String
 
238
         */
 
239
        result = SQL_SUCCESS;
 
240
 
 
241
        lenStrout = cbConnStrOutMax;
 
242
        if (conn->ms_jet && lenStrout > 255)
 
243
                lenStrout = 255;
 
244
        makeConnectString(connStrOut, ci, lenStrout);
 
245
        len = strlen(connStrOut);
 
246
 
 
247
        if (szConnStrOut)
 
248
        {
 
249
                /*
 
250
                 * Return the completed string to the caller. The correct method
 
251
                 * is to only construct the connect string if a dialog was put up,
 
252
                 * otherwise, it should just copy the connection input string to
 
253
                 * the output. However, it seems ok to just always construct an
 
254
                 * output string.  There are possible bad side effects on working
 
255
                 * applications (Access) by implementing the correct behavior,
 
256
                 * anyway.
 
257
                 */
 
258
                strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
 
259
 
 
260
                if (len >= cbConnStrOutMax)
 
261
                {
 
262
                        int                     clen;
 
263
 
 
264
                        for (clen = strlen(szConnStrOut) - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--)
 
265
                                szConnStrOut[clen] = '\0';
 
266
                        result = SQL_SUCCESS_WITH_INFO;
 
267
                        CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the ConnStrOut.");
 
268
                }
 
269
        }
 
270
 
 
271
        if (pcbConnStrOut)
 
272
                *pcbConnStrOut = len;
 
273
 
 
274
#ifdef  FORCE_PASSWORD_DISPLAY
 
275
        mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(szConnStrOut), len, cbConnStrOutMax);
 
276
        qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(szConnStrOut));
 
277
#else
 
278
        if (get_qlog() || get_mylog())
 
279
        {
 
280
                char    *hide_str = hide_password(szConnStrOut);
 
281
 
 
282
                mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(hide_str), len, cbConnStrOutMax);
 
283
                qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(hide_str));
 
284
                if (hide_str)
 
285
                        free(hide_str);
 
286
        }
 
287
#endif /* FORCE_PASSWORD_DISPLAY */
 
288
 
 
289
 
 
290
        mylog("PGAPI_DriverConnect: returning %d\n", result);
 
291
        return result;
 
292
}
 
293
 
 
294
 
 
295
#ifdef WIN32
 
296
RETCODE
 
297
dconn_DoDialog(HWND hwnd, ConnInfo *ci)
 
298
{
 
299
        int                     dialog_result;
 
300
 
 
301
        mylog("dconn_DoDialog: ci = %u\n", ci);
 
302
 
 
303
        if (hwnd)
 
304
        {
 
305
                dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
 
306
                                                        hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
 
307
                if (!dialog_result || (dialog_result == -1))
 
308
                        return SQL_NO_DATA_FOUND;
 
309
                else
 
310
                        return SQL_SUCCESS;
 
311
        }
 
312
 
 
313
        return SQL_ERROR;
 
314
}
 
315
 
 
316
 
 
317
BOOL FAR        PASCAL
 
318
dconn_FDriverConnectProc(
 
319
                                                 HWND hdlg,
 
320
                                                 UINT wMsg,
 
321
                                                 WPARAM wParam,
 
322
                                                 LPARAM lParam)
 
323
{
 
324
        ConnInfo   *ci;
 
325
        char    strbuf[64];
 
326
 
 
327
        switch (wMsg)
 
328
        {
 
329
                case WM_INITDIALOG:
 
330
                        ci = (ConnInfo *) lParam;
 
331
 
 
332
                        /* Change the caption for the setup dialog */
 
333
                        SetWindowText(hdlg, "PostgreSQL Connection");
 
334
 
 
335
                        LoadString(s_hModule, IDS_ADVANCE_CONNECTION, strbuf, sizeof(strbuf));
 
336
                        SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), strbuf);
 
337
 
 
338
                        /* Hide the DSN and description fields */
 
339
                        ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
 
340
                        ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
 
341
                        ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
 
342
                        ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
 
343
                        ShowWindow(GetDlgItem(hdlg, IDC_DRIVER), SW_HIDE);
 
344
 
 
345
                        SetWindowLong(hdlg, DWL_USER, lParam);          /* Save the ConnInfo for
 
346
                                                                                                                 * the "OK" */
 
347
                        SetDlgStuff(hdlg, ci);
 
348
 
 
349
                        if (ci->database[0] == '\0')
 
350
                                ;                               /* default focus */
 
351
                        else if (ci->server[0] == '\0')
 
352
                                SetFocus(GetDlgItem(hdlg, IDC_SERVER));
 
353
                        else if (ci->port[0] == '\0')
 
354
                                SetFocus(GetDlgItem(hdlg, IDC_PORT));
 
355
                        else if (ci->username[0] == '\0')
 
356
                                SetFocus(GetDlgItem(hdlg, IDC_USER));
 
357
                        else if (ci->focus_password)
 
358
                                SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
 
359
                        break;
 
360
 
 
361
                case WM_COMMAND:
 
362
                        switch (GET_WM_COMMAND_ID(wParam, lParam))
 
363
                        {
 
364
                                case IDOK:
 
365
                                        ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
 
366
 
 
367
                                        GetDlgStuff(hdlg, ci);
 
368
 
 
369
                                case IDCANCEL:
 
370
                                        EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
 
371
                                        return TRUE;
 
372
 
 
373
                                case IDC_DATASOURCE:
 
374
                                        ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
 
375
                                        DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
 
376
                                                                   hdlg, ds_options1Proc, (LPARAM) ci);
 
377
                                        break;
 
378
 
 
379
                                case IDC_DRIVER:
 
380
                                        ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
 
381
                                        DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
 
382
                                                                   hdlg, driver_optionsProc, (LPARAM) ci);
 
383
                                        break;
 
384
                        }
 
385
        }
 
386
 
 
387
        return FALSE;
 
388
}
 
389
#endif   /* WIN32 */
 
390
 
 
391
 
 
392
void
 
393
dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
 
394
{
 
395
        char       *our_connect_string;
 
396
        char       *pair,
 
397
                           *attribute,
 
398
                           *value,
 
399
                           *equals;
 
400
        char       *strtok_arg;
 
401
#ifdef  HAVE_STRTOK_R
 
402
        char       *last;
 
403
#endif /* HAVE_STRTOK_R */
 
404
 
 
405
        CC_conninfo_init(ci);
 
406
 
 
407
        our_connect_string = strdup(connect_string);
 
408
        strtok_arg = our_connect_string;
 
409
 
 
410
#ifdef  FORCE_PASSWORD_DISPLAY
 
411
        mylog("our_connect_string = '%s'\n", our_connect_string);
 
412
#else
 
413
        if (get_mylog())
 
414
        {
 
415
                char    *hide_str = hide_password(our_connect_string);
 
416
 
 
417
                mylog("our_connect_string = '%s'\n", hide_str);
 
418
                free(hide_str);
 
419
        }
 
420
#endif /* FORCE_PASSWORD_DISPLAY */
 
421
 
 
422
        while (1)
 
423
        {
 
424
#ifdef  HAVE_STRTOK_R
 
425
                pair = strtok_r(strtok_arg, ";", &last);
 
426
#else
 
427
                pair = strtok(strtok_arg, ";");
 
428
#endif /* HAVE_STRTOK_R */
 
429
                if (strtok_arg)
 
430
                        strtok_arg = 0;
 
431
                if (!pair)
 
432
                        break;
 
433
 
 
434
                equals = strchr(pair, '=');
 
435
                if (!equals)
 
436
                        continue;
 
437
 
 
438
                *equals = '\0';
 
439
                attribute = pair;               /* ex. DSN */
 
440
                value = equals + 1;             /* ex. 'CEO co1' */
 
441
 
 
442
#ifndef FORCE_PASSWORD_DISPLAY
 
443
                if (stricmp(attribute, INI_PASSWORD) == 0 ||
 
444
                    stricmp(attribute, "pwd") == 0)
 
445
                        mylog("attribute = '%s', value = 'xxxxx'\n", attribute);
 
446
                else
 
447
#endif /* FORCE_PASSWORD_DISPLAY */
 
448
                        mylog("attribute = '%s', value = '%s'\n", attribute, value);
 
449
 
 
450
                if (!attribute || !value)
 
451
                        continue;
 
452
 
 
453
                /* Copy the appropriate value to the conninfo  */
 
454
                copyAttributes(ci, attribute, value);
 
455
 
 
456
        }
 
457
 
 
458
        free(our_connect_string);
 
459
}
 
460
 
 
461
static void
 
462
dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
 
463
{
 
464
        char       *our_connect_string;
 
465
        char       *pair,
 
466
                           *attribute,
 
467
                           *value,
 
468
                           *equals;
 
469
        char       *strtok_arg;
 
470
#ifdef  HAVE_STRTOK_R
 
471
        char       *last;
 
472
#endif /* HAVE_STRTOK_R */
 
473
 
 
474
        our_connect_string = strdup(connect_string);
 
475
        strtok_arg = our_connect_string;
 
476
 
 
477
#ifdef  FORCE_PASSWORD_DISPLAY
 
478
        mylog("our_connect_string = '%s'\n", our_connect_string);
 
479
#else
 
480
        if (get_mylog())
 
481
        {
 
482
                char    *hide_str = hide_password(our_connect_string);
 
483
 
 
484
                mylog("our_connect_string = '%s'\n", hide_str);
 
485
                free(hide_str);
 
486
        }
 
487
#endif /* FORCE_PASSWORD_DISPLAY */
 
488
 
 
489
        while (1)
 
490
        {
 
491
#ifdef  HAVE_STRTOK_R
 
492
                pair = strtok_r(strtok_arg, ";", &last);
 
493
#else
 
494
                pair = strtok(strtok_arg, ";");
 
495
#endif /* HAVE_STRTOK_R */
 
496
                if (strtok_arg)
 
497
                        strtok_arg = 0;
 
498
                if (!pair)
 
499
                        break;
 
500
 
 
501
                equals = strchr(pair, '=');
 
502
                if (!equals)
 
503
                        continue;
 
504
 
 
505
                *equals = '\0';
 
506
                attribute = pair;               /* ex. DSN */
 
507
                value = equals + 1;             /* ex. 'CEO co1' */
 
508
 
 
509
#ifndef FORCE_PASSWORD_DISPLAY
 
510
                if (stricmp(attribute, INI_PASSWORD) == 0 ||
 
511
                    stricmp(attribute, "pwd") == 0)
 
512
                        mylog("attribute = '%s', value = 'xxxxx'\n", attribute);
 
513
                else
 
514
#endif /* FORCE_PASSWORD_DISPLAY */
 
515
                        mylog("attribute = '%s', value = '%s'\n", attribute, value);
 
516
 
 
517
                if (!attribute || !value)
 
518
                        continue;
 
519
 
 
520
                /* Copy the appropriate value to the conninfo  */
 
521
                copyCommonAttributes(ci, attribute, value);
 
522
 
 
523
        }
 
524
 
 
525
        free(our_connect_string);
 
526
}