here is the pick basic code. Don't laugh :)
CNTR = 0
EXECUTE "BREAK-KEY-OFF"
EXECUTE "CLS"
10 IF CNTR = 3 THEN EXECUTE "OFF"
CRT "Case sensitive Password"
CRT "SSD Password Please:":
ECHO OFF
INPUT PASSWORD.ORG
IF PASSWORD.ORG = '' THEN CNTR += 1; GOTO 10
ECHO ON
WHO = ICONV(0, 'U50BB')
INITIALS.ORG = FIELD(WHO, ' ', 3)
DOME = "!php ldap.php ":INITIALS.ORG:" '":PASSWORD.ORG:"'"
EXECUTE DOME CAPTURING OUT
IF OUT<1> = "success" THEN
* GOOD LDAP LOGIN
CRT "GOOD LOGIN"
END ELSE
CNTR += 1
CRT "BAD LOGIN, ATTEMPT ":CNTR
GOTO 10
END
EXECUTE "BREAK-KEY-ON" CAPTURING OUT
CRT "HIT YOUR CAPS LOCK"
and you will need the php file ldap.php - this does the actual authentication. Use this for both our web server authentication and for the D3 users. Have sanitized with xx
<?php
// this is in production. This provides authentication services for web.login and also d3 users login
ini_set('display_errors', 0);
error_reporting(0);
$cnname = $argv[1];
$password = $argv[2];
$attributes_ad = array("displayName","description","cn");
$tree = "DC=xx,DC=xx,DC=xx";
$username = $cnname."@xx.xx.xx";
$samaccountname = $cnname;
//ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
$con = ldap_connect('ldaps://xx.xx.xx.xx:636' );
ldap_set_option($con, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($con, LDAP_OPT_REFERRALS, 0);
ldap_set_option($con, LDAP_OPT_NETWORK_TIMEOUT, 1);
ldap_set_option($con, LDAP_OPT_DIAGNOSTIC_MESSAGE, 0);
if ($bind = ldap_bind($con, $username, $password)) {
print "success\r\n";
$result = ldap_search($con,$tree,"(sAMAccountName=$samaccountname)");
$data = ldap_get_entries($con, $result);
print_r( $data[0]['employeeid'][0]);
print "\n\r"
} else {
print "failure\n\r";
}
?>
------------------------------
Craig Curtis
System Programmer
Sevier Valley School District
Richfield UT United States
------------------------------
Original Message:
Sent: 10-14-2021 11:29
From: Brian Cram
Subject: D3 Password Management
Hey, Craig, I don't know about anyone else, but I'd LOVE to see that at your convenience! Thanks in advance.
------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
Original Message:
Sent: 10-14-2021 08:31
From: Craig Curtis
Subject: D3 Password Management
Morning Brian,
Nice post! sorry for the late reply but you know work gets in the way!
I just wanted to mention that we decided to go somewhere in the middle as far as login and who controls the password. We still create the user but use a subroutine to verify the password via LDAP and our AD server. This way we still can limit access but use AD as the single password for all systems. If anyone is interested I could scrub the program and share.
Thanks Again for keeping us thinking.
Craig
------------------------------
Craig Curtis
System Programmer
Sevier Valley School District
Richfield UT United States
Original Message:
Sent: 10-12-2021 11:54
From: Brian Cram
Subject: D3 Password Management
A while back, D3 introduced the concept of Host Authentication to give users the ability to manage passwords and password standards using O/S authentication ( Active Directory, LDAP, whatever ). This is detailed in the D3 System Administration Guides:
https://www3.rocketsoftware.com/rocketd3/support/documentation/d3nt/103/admin/index.htm
https://www3.rocketsoftware.com/rocketd3/support/documentation/d3linux/103/admin/index.htm
https://www3.rocketsoftware.com/rocketd3/support/documentation/AIX/103/admin/index.htm
While that is a really good thing to implement and highly recommended by Rocket D3 staff, including myself, sometimes it can be a bit challenging to implement. For those of you who simply want a way to enforce D3 password standards ( expiry, history, length, character content ) from within D3 itself, you might want to take a look at this program I wrote for an end user. To implement it, you would call this program from the USERS file item logon macro ( somewhere after TERM-TYPE on A12 and before you LOGTO any account ) and create a file in DM ( or somewhere else with a Q-pointer thereto from DM ). Details in the program comments. Have a look, enjoy, and please post any comments, improvements or other points of view herein.
* userpwd.pgm - bsc 09/29/21
*
* Manage password criteria:
* Expiry
* Length
* Character content
* History
*
* NOTE: D3 supports multiple user passwords in
* A7 of the users item, support for that
* not yet implemented in this program
*
prompt ''
open 'users' to f.users else stop
*
* userpwd file must exist either in DM
* or Q-pointed from DM, else program disabled
*
open 'userpwd' to f.pwd else stop
read uitem from f.users,@user else stop
*
* If no current password, program disabled
*
pwcur = uitem<7,1>
if len(pwcur) = 8 else stop
*
* Set up expiry days, password history count
* and valid character constants
*
pwexp = 90
pwcnt = 6
nchar = "0123456789"
uchar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lchar = "abcdefghijklmnopqrstuvwxyz"
schar = "!#$%_-"
*
* Read the userpwd item or initialize and make
* sure the current password exists in history
*
read pitem from f.pwd,@user else
pitem = uitem<7,1>
pitem<2> = date()
end
locate pwcur in pitem<1> setting ix else
pitem<pwcnt> = ""
ins pwcur before pitem<1,1>
del pitem<1,pwcnt+1>
end
write pitem on f.pwd,@user
*
* Set up expiry date and check to see if the
* current password is expired or will soon,
* prompt for new password in either case
*
dtexp = pitem<2> + pwexp
begin case
case dtexp <= date()
crt "Password is expired"
gosub EnterPwd
if pwnew = "" then execute "off"
case dtexp <= (date() + 15)
crt "Password expires in ":(dtexp - date()):" day(s)"
crt "Change Password (y)?":
input yesno
if yesno[1,1] = "y" then
gosub EnterPwd
if pwnew = "" then execute "off"
end
end case
*
stop
*
EnterPwd:
*
* If any failure to meet standards,
* pwnew set to null telling main
* program to fail and log user off
*
casing on
crt "Enter new password: ":
echo off
input pwnew
echo on
*
pwlen = len(pwnew)
if pwlen < 8 then
crt "Failed: shorter than 8 characters"
pwnew = ""
end else
isnum = 0
islow = 0
isupr = 0
isspc = 0
for px = 1 to pwlen
wch = pwnew[px,1]
if index(nchar,wch,1) then isnum = 1
if index(uchar,wch,1) then isupr = 1
if index(lchar,wch,1) then islow = 1
if index(schar,wch,1) then isspc = 1
next px
end
*
begin case
case not(isnum)
crt "Failed: no numeric characers (":nchar:")"
pwnew = ""
case not(isupr)
crt "Failed: no upper-case characers (":uchar:")"
pwnew = ""
case not(islow)
crt "Failed: no lower-case characers (":lchar:")"
pwnew = ""
case not(isspc)
crt "Failed: no special characers (":schar:")"
pwnew = ""
end case
*
* Reenter password to make sure they match
*
if pwnew = "" else
crt "Reenter new password: ":
echo off
input w
echo on
if w = pwnew else
crt "Passwords do not match."
pwnew = ""
end
end
*
* Make sure new password is not in recent usage list
*
if pwnew = "" else
pwnew = iconv(pwnew,"u0c")
locate pwnew in pitem<1> setting ix then
crt "Failed: password recently used"
pwnew = ""
end else
*
* If everything good, update password history
* file and write new password on users file
*
writev pwnew on f.users,@user,7
ins pwnew before pitem<1,1>
del pitem<1,pwcnt+1>
pitem<2> = date()
write pitem on f.pwd,@user
end
end
casing off
return
*
* End of source
------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------