Change Password and User ID and Password Authentication Program Questions

Change Password and User ID and Password Authentication Program Questions

Post by Brooks Vaugh » Thu, 06 Feb 2003 01:20:53



Is the Delphi Unit SSPIValidatePassword, SSPLogonUser method to Validate
the A User's ID and Password any good?

I am thinking of using it in a Change Password program I am writting.

After I prompt for the User's Old and New Passwords, I call the
SSPLogonUser function below, if successful, then I call the ADSI
functions to ChangePassword.

One behavor I am trying to resolve is that if the user calls the change
password program again (within an hour), the New Password hasn't had
time to sync to all the BDC's yet so it wants the old password not the
new password.

To change the password, I am using the IADsUser Object ChangePassword
Method.

hr := ADsGetObject( FADsConnectString, IADsUser, FoUsr);
if hr = S_Ok then begin
try
   FoUsr.GetInfo;
   FoUsr.ChangePassword( FOldPassword, FNewPassword );
   FoUsr.SetInfo;
except
   on E:EOleException do begin
      UpdateMessage( 'ChangePassword ' + Trim(E.Source + ' Error: (0x' +
IntToHex(E.ErrorCode,8) + ') ' + E.Message) );
      Exit;
   end;
end;
end;

Is this the correct approach to change the User's Password?

Anyone have any idea's how to Authenticate the Password against the PDC
so the new password is now current?

-Brooks Vaughn
bvau...@ftc.gov

(*======================================================================*
 | SSPIValidatePassword                                                 |
 |                                                                      |
 | Validate NT passwords using the SSPI                                 |
 |                                                                      |
 | See MSDN article HOWTO: Validate User Credentials on Microsoft WinNT |
 | and Win95, and without Act As Part Of Operating System privilege     |
 |                                                                      |
 | nb.  Using this method is is analogous to calling the LogonUser API  |
 | with the LOGON32_LOGON_NETWORK logon type. The biggest downside to   |
 | this type of logon is that you cannot access remote network          |
 | resources after impersonating a network type logon.                  |
 |                                                                      |
 | Hence the function doesn't return an HTOKEN, like LogonUser does.    |
 |                                                                      |
 | Copyright (c) Colin Wilson 2001                                      |
 |                                                                      |
 | Version  Date        By    Description                               |
 | -------  ----------  ----  ------------------------------------------|
 | 1.0      01/03/2001  CPWW  Original                                  |
 *======================================================================*)

unit SSPIValidatePassword;

interface

uses Windows, SysUtils;

function SSPLogonUser (const DomainName, UserName, Password : string) :
boolean;

implementation

const

//---------------------------------------------------------------------
// Define SSPI constants

  SEC_WINNT_AUTH_IDENTITY_ANSI = $01;
  SECPKG_CRED_INBOUND          = $00000001;
  SECPKG_CRED_OUTBOUND         = $00000002;
  SECPKG_CRED_BOTH             = $00000003;
  SECPKG_CRED_DEFAULT          = $00000004;
    SECPKG_CRED_RESERVED         = $F0000000;

  SECBUFFER_VERSION           = 0;

  SECBUFFER_EMPTY             = 0;   // Undefined, replaced by provider
  SECBUFFER_DATA              = 1;   // Packet data
  SECBUFFER_TOKEN             = 2;   // Security token
  SECBUFFER_PKG_PARAMS        = 3;   // Package specific parameters
  SECBUFFER_MISSING           = 4;   // Missing Data indicator
  SECBUFFER_EXTRA             = 5;   // Extra data
  SECBUFFER_STREAM_TRAILER    = 6;   // Security Trailer
  SECBUFFER_STREAM_HEADER     = 7;   // Security Header
  SECBUFFER_NEGOTIATION_INFO  = 8;   // Hints from the negotiation pkg
  SECBUFFER_PADDING           = 9;   // non-data padding
  SECBUFFER_STREAM            = 10;  // whole encrypted message

  SECBUFFER_ATTRMASK          = $F0000000;
  SECBUFFER_READONLY          = $80000000;  // Buffer is read-only
  SECBUFFER_RESERVED          = $40000000;

  SECURITY_NATIVE_DREP        = $00000010;
    SECURITY_NETWORK_DREP       = $00000000;

  SEC_I_CONTINUE_NEEDED        = $00090312;
  SEC_I_COMPLETE_NEEDED        = $00090313;
  SEC_I_COMPLETE_AND_CONTINUE  = $00090314;

//---------------------------------------------------------------------
// Define SSPI types

type

TSecWinntAuthIdentity = packed record
  User : PChar;
  UserLength : DWORD;
  Domain : PChar;
  DomainLength : DWORD;
  Password : PChar;
  PasswordLength : DWORD;
  Flags : DWORD
end;
PSecWinntAuthIdentity = ^TSecWinntAuthIdentity;

TSecHandle = packed record
  dwLower : DWORD;
  dwUpper : DWORD
end;
PSecHandle = ^TSecHandle;

TSecBuffer = packed record
  cbBuffer : DWORD;
  BufferType : DWORD;           // Type of the buffer (below)
  pvBuffer : pointer;
end;
PSecBuffer = ^TSecBuffer;

TSecBufferDesc = packed record
  ulVersion,
  cBuffers : DWORD;             // Number of buffers
  pBuffers : PSecBuffer
end;
PSecBufferDesc = ^TSecBufferDesc;

TCredHandle = TSecHandle;
PCredHandle = PSecHandle;

TCtxtHandle = TSecHandle;
PCtxtHandle = PSecHandle;

TAuthSeq = packed record
   _fNewConversation : BOOL;
   _hcred : TCredHandle;
   _fHaveCredHandle : BOOL;
   _fHaveCtxtHandle : BOOL;
   _hctxt : TSecHandle;
end;
PAuthSeq = ^TAuthSeq;

PNode = ^TNode;
TNode = record
   dwKey : DWORD;
   pData : pointer;
   pNext : PNode
end;

TSecPkgInfo = record
  fCapabilities : DWORD;        // Capability bitmask
  wVersion : WORD;            // Version of driver
  wRPCID : WORD;              // ID for RPC Runtime
  cbMaxToken : DWORD;           // Size of authentication token (max)
  Name : PChar;
  Comment : PChar;         // Comment
end;
PSecPkgInfo = ^TSecPkgInfo;

TSecurityStatus = LongInt;

ENUMERATE_SECURITY_PACKAGES_FN_A  = function (var cPackages : DWORD; var
PackageInfo : PSecPkgInfo) : TSecurityStatus; stdcall;
QUERY_SECURITY_PACKAGE_INFO_FN_A  = function (packageName : PChar; var
info : PSecPkgInfo) : TSecurityStatus; stdcall;
QUERY_CREDENTIALS_ATTRIBUTES_FN_A = function (phCredential :
pCredHandle; ulAttribute : DWORD; buffer : pointer) : TSecurityStatus;
stdcall;
EXPORT_SECURITY_CONTEXT_FN        = function (hContext : pCtxtHandle;
flags : DWORD; pPackedContext : PSecBuffer; var token : pointer) :
TSecurityStatus;
SEC_GET_KEY_FN                    = procedure (Arg, Principal : pointer;
KeyVer : DWORD; var Key : pointer; var status : TSecurityStatus);

ACQUIRE_CREDENTIALS_HANDLE_FN_A      = function (
  pszPrincipal : PChar;
    pszPackage : PChar;
  fCredentialUse : DWORD;
  pvLogonID : pointer;
  pAuthData : pointer;
  pGetKeyFn : SEC_GET_KEY_FN;
  pvGetKeyArgument : pointer;
  var phCredential : TCredHandle;
  var ptsExpiry : TTimeStamp) : TSecurityStatus; stdcall;

FREE_CREDENTIALS_HANDLE_FN = function (credHandle : PCredHandle) :
TSecurityStatus; stdcall;

INITIALIZE_SECURITY_CONTEXT_FN_A  = function (
    phCredential : PCredHandle;
    phContent : PCtxtHandle;
    pszTargetName : PChar;
    fContextReq,
    Reserved1,
    TargetDataRep : DWORD;
    pInput : PSecBufferDesc;
    Reserved2 : DWORD;
    phNewContext : PCtxtHandle;
      pOutput : PSecBufferDesc;
    var pfContextAttr : DWORD;
    var ptsExpiry : TTimeStamp) : TSecurityStatus; stdcall;

ACCEPT_SECURITY_CONTEXT_FN = function (
    phCredential : PCredHandle;
    phContext : PCtxtHandle;
    pInput : PSecBufferDesc;
    fContextReq,
    TargetDataRep : DWORD;
    phNewContext : PCtxtHandle;
    pOutput : PSecBufferDesc;
    var pfContextAttr : DWORD;
    var ptsExpiry : TTimeStamp) : TSecurityStatus; stdcall;

COMPLETE_AUTH_TOKEN_FN           = function (phContext : PCtxtHandle;
pToken : PSecBufferDesc) : TSecurityStatus; stdcall;
DELETE_SECURITY_CONTEXT_FN       = function (phContext : PCtxtHandle) :
TSecurityStatus; stdcall;
APPLY_CONTROL_TOKEN_FN           = function (phContext : PCtxtHandle;
pInput : PSecBufferDesc) : TSecurityStatus; stdcall;
QUERY_CONTEXT_ATTRIBUTES_FN_A    = function (phContext : PCtxtHandle;
alAttribute : DWORD; pBuffer : pointer) : TSecurityStatus; stdcall;
IMPERSONATE_SECURITY_CONTEXT_FN  = function (phContext : PCtxtHandle) :
TSecurityStatus; stdcall;
REVERT_SECURITY_CONTEXT_FN       = function (phContext : PCtxtHandle) :
TSecurityStatus; stdcall;
MAKE_SIGNATURE_FN                = function (phContext : PCtxtHandle;
fQOP : DWORD; pMessage : PSecBufferDesc;  MessageSeqNo : DWORD) :
TSecurityStatus; stdcall;
VERIFY_SIGNATURE_FN              = function (phContext : PCtxtHandle;
pMessage : PSecBufferDesc; MessageSeqNo : DWORD; var fQOP : DWORD) :
TSecurityStatus; stdcall;
FREE_CONTEXT_BUFFER_FN           = function (contextBuffer : pointer) :
TSecurityStatus; stdcall;
IMPORT_SECURITY_CONTEXT_FN_A     = function (pszPackage : PChar;
pPackedContext : PSecBuffer; Token : pointer; phContext : PCtxtHandle) :
TSecurityStatus; stdcall;

ADD_CREDENTIALS_FN_A             = function (
    hCredentials : PCredHandle;
    pszPrincipal,
    pszPackage : PChar;
    fCredentialUse : DWORD;
    pAuthData : pointer;
    pGetKeyFn : SEC_GET_KEY_FN;
    pvGetKeyArgument : pointer;
    var ptsExpiry : TTimeStamp) : TSecurityStatus; stdcall;

QUERY_SECURITY_CONTEXT_TOKEN_FN = function (phContext : PCtxtHandle; var
token : pointer) : TSecurityStatus; stdcall;
ENCRYPT_MESSAGE_FN              = function (phContext : PCtxtHandle;
fQOP : DWORD; pMessage : PSecBufferDesc; MessageSeqNo : DWORD) :
TSecurityStatus; stdcall;
DECRYPT_MESSAGE_FN              = function (phContext : PCtxtHandle;
pMessage : PSecBufferDesc; MessageSeqNo : DWORD; fQOP : DWORD) :
TSecurityStatus; stdcall;

TSecurityFunctionTable = record
  dwVersion : LongInt;
    EnumerateSecurityPackagesA  : ENUMERATE_SECURITY_PACKAGES_FN_A;
  QueryCredentialsAttributesA : QUERY_CREDENTIALS_ATTRIBUTES_FN_A;
  AcquireCredentialsHandleA   :
...

read more »

 
 
 

Change Password and User ID and Password Authentication Program Questions

Post by Jason Tyle » Sun, 16 Feb 2003 03:57:52


Hello Brooks,

Sorry, I don't know a whole lot about Delphi.

I did however find this website, that explains how to bind, and set
passwords using Delphi, as well as several other common routines.

http://www.agnisoft.com/adsi/Conf2000/3132.htm

Please check out this information.

Thanks.

Jason Tyler
Microsoft Developer Support

 
 
 

1. Changing a user password who has 'Change Password at next Logon' flagged

Hi,

I'm trying to change the password of a user using VB and ADSI with the
LDAP provider. The VB is built as a COM component and running as a
server application and has an identity set to a user account with
administrative rights.
The method call is from an ASP page where a user types in the relevant
information to change their password.

My code in brief is as below :

    strUserPath = "LDAP://" & strDomain & "/CN=" & UserName & "," &
strContainer
    Set objUser = GetObject(strUserPath)

    objUser.ChangePassword OldPassword, NewPassword

which results in the following error :

    Error Number : -2147023545 (0x80070547)

    Description : Automation error

    Configuration information could not be read from the domain
controller,     either because the machine is unavailable, or access
has been denied.

The security error that occurs on the DC is as follows :

Event Type:     Failure Audit
Event Source:   Security
Event Category: Account Logon
Event ID:       681
Date:           04/02/2003
Time:           10:12:47
User:           NT AUTHORITY\SYSTEM
Computer:       CRISDVLPDC
Description:
The logon to account: 100099
 by: MICROSOFT_AUTHENTICATION_PACKAGE_V1_0
 from workstation: GBCRISS193
 failed. The error code was: 3221226020

The error code translates to User Logon with 'Change Password at Next
Logon' Flagged.

This works no problem with the WinNT provider but I have to use the
LDAP provider.

Any thoughts or suggestions are most welcome

Paul Jackson

2. launch 'cdev' from app

3. Cant SET 'user cant change password' AND 'password never expires'

4. Metafont: All fonts available in .mf format

5. Change local user password on remote computer w/o domain authentication

6. Ontogenesis of Mechanoia

7. User has authentication problems after changing password

8. HD Chinon external floppy?

9. Changing User Password when set to Change at next logon

10. how to change smb-password and windows password form client

11. net password \\samba from Windows 95 fails to change password

12. Password change / Password file problem.