Re: Change UNIX password from Windows (with Sample Powerbuilder Code)
Posted in 1996
Derrek Poulson wrote: > > Mike Segel <mikey@segel.com> writes: > > >Derrek Poulson wrote: > > >> the UNIX password is changed, it'd sure be nice to be able to update the > >> encrypted password Setnet puts in informix.ini. Any suggestions on this one? > > Theoretically, you are of course correct. Passwords shouldn't be stored > anywhere where they're readable by anyone other than system administrators, > even if encrypted. > > Realistically, I see only 3 ways to manage UNIX/Informix passwords in a > client/server environment, none of which is entirely satisfactory: > > 1. Make up a UNIX password when a new account is created, then code the > PowerBuilder (or whatever) app to automatically supply the correct password > each time the app is run. Disadvantages: 1) how to securely supply the > password automatically, 2) keeping a password perpetually unchanged is asking > for trouble. > > 2. Have the user supply the password each time the app is run. From a > security standpoint, this is ideal, but from the user's standpoint, having to > authenticate every time you open a new app is unacceptable. This is > understandable to a degree since one authentication per session (i.e. the > Netware login) should be sufficient. When users have modest hardware and apps > are written in PowerBuilder (which is a resource hog), a fair amount of > opening and closing apps is unavoidable. > > 3. Use setnet and informix.ini. If access to informix.ini is governed by > a network login, this provides reasonable security. The drawback is that when > the UNIX password needs to be changed, you have to change it in Setnet also. > Hence my original question. > > I'm a UNIX administrator, so I have the same concerns you do. There's always > a tradeoff between security and convenience for legit users; in this case, I > think #3 is a reasonable compromise. > > And no, Informix's encryption isn't crypt. To the best of my knowledge, > Informix hasn't made their encryption algorithm public, so to crack a password, > you'd probably have to resort to a homegrown app that would feed keystrokes to > setnet and parse informix.ini. > Derrek, All your 3 approaches are based upon the assumption that setnet cannot be bypassed, which is not true. As I said previously, you cannot completely bypass setnet under Powerbuilder 3, but it is possible under Powerbuilder 4. I believe you are not using Powerbuilder 3 anyway. In our production environment, we delete informix.ini and setnet icon/program for security reasons. Users must go through our applications in order to access the database. Bypassing setnet for Powerbuilder 4 is not difficult. You need to populate transaction object with required information which includes user name, database name, server name, password, ... etc. You can design a login screen to collect the information and then populate the transaction object. In addition to the above information, you need two more pieces of information: service and dbms The service part is not implemented in Powerbuilder 3. That is the reason you cannot drop setnet for Powerbuilder 3. The attached code is long. It has many more functions than just login. However, the concept is simple. Chao ======================================================== This is the ini file read by the u_ini_file object. The TIME=... part is not necessary. ======================================================== [DATABASE] DBMS=IN5 - I-Net v5.x DBPARM="DISABLEBIND=1,INET_SERVICE='online7',TIME=' ""HH:MM"" '" [INPUT] database=input server=input1 ======================================================== This is the application script, which calls a user object to get information defined in a window ini file. The content of the ini file is listed above. ======================================================== integer li_logincount , li_errorcode BOOLEAN lb_result string ls_returned gs_app_name = THIS.appname iu_ini_file = CREATE u_ini_file IF (iu_ini_file.ufb_ini_init(your_ini_file_name, SQLCA )) THEN OPEN(w_login) IF Message.StringParm = "FAILED" THEN HALT CLOSE ELSE EXECUTE IMMEDIATE "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"; gs_server_name = Trim(gs_server_name) gs_current_user_id = sqlca.userid OPEN(w_main) w_main.title="XXXX System (Server " + gs_server_name + ")" END IF ELSE HALT Close END IF ======================================================== This is part of the u_ini_file object that populate the transaction object. As you can see, ======================================================== at_dbtransaction.DBMS = ProfileString(ss_app_ini,"DATABASE","dbms","") at_dbtransaction.database = ProfileString(ss_app_ini,gs_app_name,"database","") //at_dbtransaction.userid = ProfileString(ss_app_ini,"DATABASE","userid","") //at_dbtransaction.dbpass = ProfileString(ss_app_ini,"DATABASE","dbpass","") //at_dbtransaction.logid = ProfileString(ss_app_ini,"DATABASE","logid","") //at_dbtransaction.logpass = ProfileString(ss_app_ini,"DATABASE","logpass","") at_dbtransaction.servername = ProfileString(ss_app_ini,gs_app_name,"server","") at_dbtransaction.dbparm = ProfileString(ss_app_ini,"DATABASE","dbparm","") RETURN(TRUE) ======================================================== This is the script for the OK button of w_login screen. ======================================================== string ls_password u_security lu_security boolean lb_expired boolean lb_multiple_connections SetPointer(HourGlass!) ls_password = TRIM(sle_user_id.text) ii_login_attempts = ii_login_attempts + 1 SQLCA.userid = TRIM(sle_user_id.text) SQLCA.dbpass = TRIM(sle_password.text) CONNECT USING SQLCA; IF SQLCA.SQLCODE = 0 THEN COMMIT USING SQLCA; // Handle the application security here SetPointer (Arrow!) IF lb_expired = TRUE THEN CloseWithReturn (parent, "FAILED") ELSE CloseWithReturn (parent, "SUCCESS") END IF ELSE // Display login error message ROLLBACK USING SQLCA; sle_password.SelectText(1,Len(sle_password.text)) sle_password.SetFocus() IF ii_login_attempts = 3 THEN MessageBox ("Sorry!", "Login failed", STOPSIGN!) CloseWithReturn (Parent, "FAILED") END IF END IF