#!/usr/local/bin/perl5.004 # $Id: dm_check_password_smb.pl,v 1.1 1999/02/01 18:40:34 briansp Exp briansp $ use Authen::Smb; use Socket; use Sys::Hostname; # Define some constants. $pdc = ''; # Hostname of Primary Domain Controller. $bdc = ''; # Hostname of Backup Domain Controller. $domain = ''; # Name of NT Domain. # Debugging help. #$debug = 1; if ($debug) { $debug_file = "/tmp/dm_check_password.out"; open DEBUG, ">>$debug_file"; } ########################################################################## # Documentum API Result Codes ########################################################################## $DM_EXT_APP_SUCCESS = 0; $DM_CHKPASS_BAD_LOGIN = 245; $DM_CHKPASS_PASSWORD_STALE = 246; $DM_CHKPASS_PASSWORD_EXPIRED = 247; $DM_CHKPASS_ACCOUNT_EXPIRED = 248; $DM_CHKPASS_ACCOUNT_DROPPED = 249; $DM_CHGPASS_PASSWORD_CRITERIA = 251; $DM_ASSUME_USER_SYSTEM_ERROR = 252; $DM_EXT_APP_OS_ERROR = 253; $DM_EXT_APP_NOT_IMPLEMENTED = 254; $DM_EXT_APP_UNEXPECTED_ERROR = 255; ########################################################################## # SMB Auth Result Codes ########################################################################## $NTV_NO_ERROR = 0; $NTV_SERVER_ERROR = 1; $NTV_PROTOCOL_ERROR = 2; $NTV_LOGON_ERROR = 3; ########################################################################## # Simple getspnam routine. sub getspnam ($) { my($username) = @_; my(%data); open(SHADOW,"/etc/shadow") || return; while() { chomp; my($name,$junk) = split(':',$_); my(@list) = split(':',$_); $data{$name} = [ @list]; } close(SHADOW); @{ $data{$username} }; } # Local Auth (/etc/{passwd,shadow}). sub dm_Local_Auth ($$) { my($username,$user_passwd) = @_; $sys_passwd_enc = (&getspnam($username))[1]; # Its important to check that we got something back from getspnam(), # since crypt() returns NULL with NULL salt. if (! $sys_passwd_enc) { # The user doesn't exist locally. Return and we'll try another method. return(0); } else { $user_passwd_enc = crypt $password, $sys_passwd_enc; if ($user_passwd_enc eq $sys_passwd_enc) { return(1); } else { $RESULT = $DM_CHKPASS_BAD_LOGIN; return(0); } } } sub dm_SMB_Passwd_Auth ($$$$$) { my($username,$password,$pdc,$bdc,$domain) = @_; my($rc) = Authen::Smb::authen($username,$password,$pdc,$bdc,$domain); if ($rc == $NTV_NO_ERROR) { return(1); } elsif (($rc == $NTV_SERVER_ERROR) or ($rc == $NTV_PROTOCOL_ERROR)) { print DEBUG "Smb::authen returned $rc.\n" if ($debug); $RESULT = $DM_EXT_APP_OS_ERROR; return(0); } elsif ($rc == $NTV_LOGON_ERROR) { print DEBUG "Smb::authen returned $rc.\n" if ($debug); $RESULT = $DM_CHKPASS_BAD_LOGIN; return(0); } return(0); } ############################################################################## # Grab our data from stdin. Isn't perl great? $username = ; chomp $username; $password = ; chomp $password; $auth_data_1 = ; chomp $auth_data_1; $auth_data_2 = ; chop $auth_data_2; # First try to validate the user locally. if ((! $auth_data_1) or (! $auth_data_2)) { if (&dm_Local_Auth($username,$password)) { exit $DM_EXT_APP_SUCCESS; } else { # If we set RESULT in dm_Local_Auth then exit with that value. if ($RESULT) { print DEBUG "Got $RESULT from dm_Local_Auth. Exiting.\n" if ($debug); exit($RESULT); } else { print DEBUG "dm_Local_Auth failed. Trying NT Domain Auth.\n" if ($debug); if (&dm_SMB_Passwd_Auth($username,$password,$pdc,$bdc,$domain)) { exit $DM_EXT_APP_SUCCESS; } else { if ($RESULT) { print DEBUG "Got $RESULT from dm_SMB_Passwd_Auth. Exiting.\n" if ($debug); exit($RESULT); } else { print DEBUG "dm_SMB_Passwd_Auth failed, but no RESULT set. Exiting with DM_EXT_APP_OS_ERROR.\n"; exit($DM_EXT_APP_OS_ERROR); } } } } } # If we got this far, exit with a failure. print DEBUG "Passed through loop. Exiting with DM_CHKPASS_BAD_LOGIN.\n" if ($debug); exit($DM_CHKPASS_BAD_LOGIN);