Does anyone have a COBOL example of a user validation in Active Directory they´d like to share?
Regards
Steen
Hi
Yes I'm aware that I might have do do some ActiveX / DLL calls but I what I ment was if there's anyone who already did some COBOL code for this and would like to share?
Steen
Does anyone have a COBOL example of a user validation in Active Directory they´d like to share?
Regards
Steen
What do you mean by "user validation"?
If you have a username and password, and you're running on Windows, you're probably better off just calling the standard Windows LogonUser function. It's simpler and almost always faster.
Here's the thing: There are essentially two ways to validate user credentials against an LDAP server such as AD. (I'm omitting proprietary, non-LDAP interfaces to AD, because they're basically equivalent for this purpose.) You can try to bind to the server using the credentials and see if that succeeds; or you can do a search against the server for the object representing the user, and then do something with the returned information.
Binding to AD as the user is equivalent to doing a domain signon in most cases, except:
Some users may not have permission to bind to AD
You don't get the benefits of local credential caching, such as:
Better performance (saves a network round trip and processing in AD)
Offline support
Looking up the user in AD generally isn't a good way to go, because:
Unless AD is configured to allow anonymous binds and then let the anonymous client search successfully for user records (which would be bad), you'll have to bind to AD first using some credentials.
If you use the credentials you're trying to validate, then you've just validated them, so why do anything more?
Otherwise, you have to get credentials from somewhere:
You can use the thread token (if you're running on Windows), but are you sure that account has appropriate permissions?
You can store a username and password somewhere. Now you have a security vulnerability.
Say you get the user information out of LDAP. How do you plan to validate the credentials you have against it?
So, if all you want to do is confirm the user's credentials, talking directly to AD probably isn't the way to go - if you're running on Windows.
If you're not running on Windows, you have a few choices:
Use the bind-to-AD method described above.
Use a remote mechanism for signing into a Windows domain, such as Samba. Or write your own (though I don't recommend this).
Use Kerberos instead.
It'd help to know what problem you're actually trying to solve, in some detail.
Does anyone have a COBOL example of a user validation in Active Directory they´d like to share?
Regards
Steen
I see what you mean, and I simply just want to check if the user is a "known user" and the user account isn't disabled / expired. So the best solution properly is to call the Windows LogonUser function as you suggest. Do you have an example of thsi?
Does anyone have a COBOL example of a user validation in Active Directory they´d like to share?
Regards
Steen
I don't have an ACU version - I'm not running ACU COBOL / Extend (so many MF products, so little time). I do have an old sample for this, for some now-forgotten reason, that I wrote in MF COBOL. I think that should work in ACU with relatively little massaging.
$set mf sourceformat"variable"
identification division.
program-id. logon.
data division.
working-storage section.
77 userid pic x(40).
77 password pic x(40).
77 strpos pic x(4) comp-5.
$if USEPTR defined
77 token pointer.
$else
$if P64 set
77 token pic x(8) comp-5.
$else
77 token pic x(4) comp-5.
$end
$end
77 result pic x(4) comp-5.
77 loadlib procedure-pointer.
77 errcode pic x(4) comp-5.
77 errdisp pic z(4)9 display.
procedure division.
*> Load Windows DLLs
set loadlib to entry "advapi32"
set loadlib to entry "kernel32"
perform until exit
*> Get username and password
display "Userid: " with no advancing
accept userid
if userid = spaces
exit perform
end-if
display "Password: " with no advancing
accept password
*> Nul-terminate strings
move 0 to strpos
inspect userid tallying strpos for characters before initial space
add 1 to strpos
move low-values to userid(strpos:1)
move 0 to strpos
inspect password tallying strpos for characters before initial space
add 1 to strpos
move low-values to password(strpos:1)
*> Try the logon
$if USEPTR defined
set token to null
$else
move 0 to token
$end
call "LogonUserA" using
by reference userid
by reference z"."
by reference password
by value 3
by value 0
by reference token
returning result
end-call
call "GetLastError" returning errcode
$if USEPTR defined
if token = null
$else
if token = 0
$end
display "No token returned"
else
display "Token returned"
*>call "CloseHandle" using by value token
call "CloseHandle" using by reference token
end-if
if result = 0
display "LogonUser returned false"
move errcode to errdisp
display "Error code was " errdisp
else
display "LogonUser returned true"
end-if
end-perform
move 0 to return-code
stop run.
Does anyone have a COBOL example of a user validation in Active Directory they´d like to share?
Regards
Steen
The z"somevalue" notation is used by various flavors of Micro Focus COBOL to indicate a null-terminated string literal; unfortunately, ACUCOBOL doesn't support this notation. However, you can use hexadecimal notation: ... by reference x"2e00". (2e is the hex value of the "dot" character, and 00 is a null byte).
Either the username or the password is incorrect, or the username needs to be domain-qualified, or you're calling LogonUser wrong. Note that all strings passed to LogonUser must be C strings (terminated with ASCII NUL). And this code calls LogonUserA, so they must be ASCII; that also means it can't be used with usernames or passwords that contain non-ASCII characters. For that you'd need to call LogonUserW and pass NUL-terminated UTF-16 strings.
If you're not familiar with calling Windows APIs I'd suggest doing some background reading.