We want to remove the hard-coded passwords from the ODBC connection strings in our SAS code, and also to prevent the appearance of any of the passwords in the SAS log files.
There seem to be a lot of recommendations discussing how to do this, but I either find problems with them or can't make them work.
A user request each time for PW is not a viable alternative. Also, storing a password in a macro variable is an acceptable approach if you have a way to suppress it from printing to log with MACROGEN and SYMBOLGEN enabled.
ATTEMPT 1 - ENCODING ( link to white paper here )
proc pwencode in='mypassword' method=sasenc; run;
gives:
{sasenc}ACFD24061BF77D7D5362EE7C2D00D08B
If I replace my plaintext password with an encoded value in my code, then the POSHRORE ODBC instruction will work fine.
proc sql noprint; connect to odbc as remote (datasrc=cmg_report user=myuser password='{sasenc}68B279564BD2695538CDCDB301E8A357563480B0'); create table sqlo as select * from connection to remote ( select top 1 * from application ) ; disconnect from remote; quit;
And the log correctly masks the values with XXXXXXX.
961 proc sql noprint; 962 connect to odbc as remote (datasrc=cmg_report user=&user_cmg password=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX); 963 create table sqlo as 964 select * 965 from connection to remote 966 ( 967 select top 1 * from application 968 ) 969 ; 971 quit; NOTE: Table WORK.SQLO created, with 1 rows and 29 columns. NOTE: PROCEDURE SQL used (Total process time): real time 0.34 seconds cpu time 0.01 seconds
The problem with the above approach is that if someone has access to the code, he can log in using an encrypted password without knowing the plain text password. Therefore, while it hides the actual password, it does not provide security. Does this seem silly to me, or am I missing something? EDIT:. This provides some security if your ODBC password is used elsewhere, but more on that.
CONFIRMATION 2 - USE SYMGET ( link to white paper here )
The problem is that I just cannot get the described technique in SAS. I am running SAS 9.2 on XP, trying to connect to a SQL Server database.
%let my_password = password; proc sql noprint; connect to odbc (dsn=cmg_report uid=myuser pwd=symget('my_password')); create table sqlo as select * from connection to remote ( select top 1 * from application ) ; quit;
I get the following message that the login failed:
1034 proc sql noprint; 1035 connect to odbc (dsn=cmg_report uid=myuser pwd=XXXXXX('my_password')); ERROR: CLI error trying to establish connection: [Microsoft][SQL Server Native Client 10.0][SQL Server]Login failed for user 'myuser'.
It looks like he is trying to use "symget" as the actual password (since it was masked in the log). There are several answers to this text that says to wrap a character in a% sysfunc call, but the symget () function is one of the few functions that SAS does not allow in a% sysfunc call, so I don’t see how this is possible.
Any other tips / suggestions / ideas would be highly appreciated.
thanks
EDIT: It would be especially nice if there was a method that worked with options symbolgen macrogen enabled.