IBM / nodejs-idb-connector

A JavaScript (Node.js) library for communicating with Db2 for IBM i, with support for queries, procedures, and much more. Uses traditional callback-style syntax
MIT License
38 stars 23 forks source link

dbconn.conn authentication #93

Closed krisbaehr closed 4 years ago

krisbaehr commented 4 years ago

I've observed that specifying a bogus password to conn() actually works most of the time. Let's assume I normally connect like this: connection.conn('PROD', 'user', 'password'). The following are also valid:

The following throw authentication errors (SQLSTATE=08001 SQLCODE=-30082):

I understand that it's probably using my job's user to establish the connection but it's misleading if that is what's happening. Are the optionally provided username a password only used when connecting to *LOCAL? Some clarification would be good. Maybe conn() could throw an error if providing user id and password in cases where it would be ignored?

I also noticed that an invalid user always produces the error. If the user is being ignored, why would this even matter? And if the user matters, wouldn't the password as well?

Just a few questions. Thanks, guys!

abmusse commented 4 years ago

Interesting, when I tried specifying a bogus password and specified the user with an empty password .conn returned an error

Using this script:

    // Usage: `DBUSER=USER DBPASS=PASS node test.js

    const { dbconn } = require('idb-connector');

    // Allows empty string DBUSER or DBPASS
    if (process.env.DBUSER == undefined || process.env.DBPASS == undefined) {
       console.error('\n\nDBUSER & DBPASS ENV VARS MUST BE SPECIFIED\n\n');
       process.exit();   
    }

    new dbconn().conn('*LOCAL', process.env.DBUSER, process.env.DBPASS);

    console.log('Done!');
$  DBUSER=MYUSER DBPASS=bogus node test.js 
USER: MYUSER
PASS: bogus
/home/issues/idb-issue-93/test.js:11
    new dbconn().conn('*LOCAL', process.env.DBUSER, process.env.DBPASS);
                 ^

Error: SQLSTATE=08001 SQLCODE=-30082 Authorization failure on distributed database connection attempt.
$   DBUSER=MYUSER DBPASS="" node test.js
USER: MYUSER
PASS: 
/home/issues/idb-issue-93/test.js:11
    new dbconn().conn('*LOCAL', process.env.DBUSER, process.env.DBPASS);
                 ^

Error: SQLSTATE=08001 SQLCODE=-30082 Authorization failure on distributed database connection attempt.

The above is what I would expect to happen.

*LOCAL Is a special case where the current user profile is used therefore no need to specify the username and password.

ThePrez commented 4 years ago

*LOCAL Is a special case where the current user profile is used therefore no need to specify the username and password.

@abmusse , I think you are confusing *LOCAL (database) with *CURRENT (username). Even connecting to *LOCAL, a bogus password should fail.

(correction: apparently there are some optimizations for *LOCAL too!)

We should do some isolation to verify whether or not the proper (incorrect) values are indeed being passed to SQLConnect().

ThePrez commented 4 years ago

I think this may be related. The username and password are not revalidated if the connection object is already connected. @krisbaehr, are you using the same connection object and invoking conn() multiple times? Or fresh connection objects?

https://github.com/IBM/nodejs-idb-connector/blob/5e753bb69c9fbbd192b5f248def9e498bdb5a2d4/src/db2ia/dbconn.cc#L192

ThePrez commented 4 years ago

I also found these snippets chasing the SQLConnect() doc at https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_73/cli/rzadpfnconn.htm

@krisbaehr , I assume you are running in server mode (the default and recommended). Strangely, it doesn't say much about when the user specified is the current user.

When running in server mode, both szUID and szAuthStr must be passed in order for the connection to run on behalf of a user ID other than the current user. If either parameter is NULL or both are NULL, the connection is started using the user ID that is in effect for the current job running the CLI program.

Non-server mode connections to the *LOCAL relational database must specify for the connecting szUID either NULL or the current user. In this case, the password is not validated. When a non-server mode connection is used, the application should not obtain the connecting szUID as input from the user, since SQLConnect will not validate the password associated with the connection.

kadler commented 4 years ago

FYI, non-server mode connections always connect as the current user and need no password. Previously this was silently ignored, but I thought there was PTFs to change this behavior so at least you must pass an empty string or NULL, but I would have to do more investigation to be sure - John Eberhard would know more.

github-actions[bot] commented 4 years ago

:wave: Hi! This issue has been marked stale due to inactivity. If no further activity occurs, it will automatically be closed.