Hi Experts,
I have a .sas file "test.sas" which has a macro with ID and pass.
%macro test;
options metauser="testuser" metapass="{SAS002}FHIHJKLNAHIFGHRTY";
%mend;
I want to read the metauser and metapass values into a variable in my program.
options mprint mlogic;
%include "/mypath/test.sas";
%test;
%let id=%sysfunc(getoption(metauser));
%let pass=%sysfunc(getoption(metapass));
%put &id;
%put &pass;
Log:
79 %let id=%sysfunc(getoption(metauser));
80 %let pass=%sysfunc(getoption(metapass));
81 %put &id;
testuser
82 %put &pass;
XXXXXXXX
I am able to read the username but password is always XXXXX. I read the documentation for getoption and it's behaving as expected for passwords.
Please advise good way to read the ID and pass in this scenario.
Thanks @Kurt_Bremser . I fetched the pass directly from file and it worked.
options mprint mlogic;
%include "/mypath/test.sas";
%test;
%let username=%sysfunc(getoption(metauser));
filename env '/mypath/test.sas';
data _null_;
infile env termstr=CRLF length=c scanover truncover;
input @'metapass=' pass $50.;
quote1=find(pass, '"');
quote2=find(pass, '";');
pass=substr(pass, quote1+1, quote2-2);
call symput('pwd', pass);
run;
%let host=mytestserver.com;
%let port=7980;
%let appserver=SASApp;
/* Get a TGT and store the response and headers*/
filename resp TEMP;
filename headers TEMP;
proc http method="POST" url="http://&host.:&port./SASLogon/v1/tickets"
in="username=&username.%nrstr(&password)=&pwd" headerout=headers out=resp
HEADEROUT_OVERWRITE;
run;
%global tgturl;
data _null_;
infile headers termstr=CRLF length=c scanover truncover;
input @'Location:' tgt $119.;
put tgt=;
run;
Log:
tgt=http:/mytestserver.com:7980/SASLogon/v1/tickets/TGT-12345-hfkhlhlalkhkglajljlsdhalhlibalsdhlsajfiijalldanhiilandlanlsi
NOTE: 1 record was read from the infile HEADERS.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time
This is not an issue of the GETOPTION function, but a feature of encoded passwords.
From the documentation of PROC PWENCODE :
"The encoded password is never written to the SAS log in plain text. Instead, each character of the password is replaced by an X in the SAS log."
There is no alternative approach. As soon as the log engine detects an encoded password, it replaces the characters with X's. You cannot PUT an encoded password to the log, for security reasons.
PS this means that the password is not displayed. To see if the encoded password is actually stored in the macro variable, try to use it as intended.
Yes, it doesn't work as intended.
options mprint mlogic;
%include "/mypath/test.sas";
%test;
%let username=%sysfunc(getoption(metauser));
%let pwd=%sysfunc(getoption(metapass));
%let host=mytestserver.com;
%let port=7980;
%let appserver=SASApp;
filename resp TEMP;
filename headers TEMP;
proc http method="POST" url="http://&host.:&port./SASLogon/v1/tickets"
in="username=&username.%nrstr(&password)=&pwd" headerout=headers out=resp
HEADEROUT_OVERWRITE;
run;
%global tgturl;
data _null_;
infile headers termstr=CRLF length=c scanover truncover;
input @'Location:' tgt $119.;
put tgt=;
call symput('tgturl', trim(tgt));
%put &tgturl.;
run;
Log:
104 %global tgturl;
105
106 data _null_;
107 infile headers termstr=CRLF length=c scanover truncover;
108 input @'Location:' tgt $119.;
109 put tgt=;
110 call symput('tgturl', trim(tgt));
111 %put &tgturl.;
112 run;
If I just hardcode the password, it works.
options mprint mlogic;
%include "/mypath/test.sas";
%test;
%let username=%sysfunc(getoption(metauser));
%let pwd={SAS002}FHIHJKLNAHIFGHRTY;
%let host=mytestserver.com;
%let port=7980;
%let appserver=SASApp;
/* Get a TGT and store the response and headers*/
filename resp TEMP;
filename headers TEMP;
proc http method="POST" url="http://&host.:&port./SASLogon/v1/tickets"
in="username=&username.%nrstr(&password)=&pwd" headerout=headers out=resp
HEADEROUT_OVERWRITE;
run;
%global tgturl;
data _null_;
infile headers termstr=CRLF length=c scanover truncover;
input @'Location:' tgt $119.;
put tgt=;
call symput('tgturl', trim(tgt));
%put &tgturl.;
run;
Log:
tgt=http:/mytestserver.com:7980/SASLogon/v1/tickets/TGT-12345-hfkhlhlalkhkglajljlsdhalhlibalsdhlsajfiijalldanhiilandlanlsi
NOTE: 1 record was read from the infile HEADERS.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time
I see; after reading the doc myself, it is clear that GETOPTION will not return the value from any option that contains a password.
Which means that you have to find another way to supply the password to your code.
If you need to retrieve the password of a system user (one that can run a workspace server), then you won't find that in metadata anyway, as it (not the password, but the hash from it) is stored in the authentication source (local operating system or LDAP).
It seems you want to retrieve a ticket from the Logon Manager; what do you intend to do with that?
Thanks @Kurt_Bremser . I fetched the pass directly from file and it worked.
options mprint mlogic;
%include "/mypath/test.sas";
%test;
%let username=%sysfunc(getoption(metauser));
filename env '/mypath/test.sas';
data _null_;
infile env termstr=CRLF length=c scanover truncover;
input @'metapass=' pass $50.;
quote1=find(pass, '"');
quote2=find(pass, '";');
pass=substr(pass, quote1+1, quote2-2);
call symput('pwd', pass);
run;
%let host=mytestserver.com;
%let port=7980;
%let appserver=SASApp;
/* Get a TGT and store the response and headers*/
filename resp TEMP;
filename headers TEMP;
proc http method="POST" url="http://&host.:&port./SASLogon/v1/tickets"
in="username=&username.%nrstr(&password)=&pwd" headerout=headers out=resp
HEADEROUT_OVERWRITE;
run;
%global tgturl;
data _null_;
infile headers termstr=CRLF length=c scanover truncover;
input @'Location:' tgt $119.;
put tgt=;
run;
Log:
tgt=http:/mytestserver.com:7980/SASLogon/v1/tickets/TGT-12345-hfkhlhlalkhkglajljlsdhalhlibalsdhlsajfiijalldanhiilandlanlsi
NOTE: 1 record was read from the infile HEADERS.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time
A quick note on your code. You probably do NOT want to store trailing spaces into your macro variable by using the older CALL SYMPUT() function instead of the newer more powerful CALL SYMPUTX() function.
call symputX('pwd', pass);
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.