Registered: 2007-01-17
Posts: 29
Loc: Portland, OR
So I was assigned the task to figure out a way to send an email notification when a user account has been locked out in an economical fashion (please read as free).
I thought that I could go with an Event Viewer reader and some how parse out all of the Event IDs from each domain controller and then figure out a way to send an email notification out from there. Not really feasible.
So now I want to figure out a way to "automate" this. I know that since this is a free solution there is no way to "instantly automate" it. However, here are my thoughts:
Create the script and assign it as a schedule task to run every minute. If a locked account(s) are found have it copy that portion to the body of an email and send it using blat or some other email utility. If "No Objects Found" is returned then end the script and close it (no email sent).
I have the idea of how it would work, I am just having issues executing it. Seeing that I haven't had to touch a KiX script in over a year my skills and knowledge are seriously lacking. Thus I turn to the experts, you guys!
#192885 - 2009-03-1412:23 AMRe: User Account Locked Notification
[Re: JeffS]
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4401
Loc: New Jersey
It just so happens that I have a script that runs every Monday morning that checks for expired, locked, and about-to-expire accounts. It generates a report and emails the report to specific users. Since this does 173% of what you need, I've posted it here and you can remove the unwanted parts and customize it to your specific needs..
The core pieces are there - look for accounts that are locked, send email.
Glenn
_________________________ Actually I am a Rocket Scientist!
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4401
Loc: New Jersey
Couple of quick notes. You need blat.exe to send mail with this script. The S_BIN and S_CONFIG are environment variables that define (to my scripts) where other binary tools and script are (S_BIN) and config files can be found (S_CONFIG). You can easily replace that with @SCRIPTDIR, but I personally find that messy..
I create C:\Local to hold all my config files for all scripts. I create C:\Local\Bin for any executables and scripts. This way, everything is in one logical place, and one script can use another easily.
Glenn
_________________________ Actually I am a Rocket Scientist!
#192888 - 2009-03-1412:29 AMRe: User Account Locked Notification
[Re: JeffS]
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4401
Loc: New Jersey
No problem.. I don't usually do silver platter code, but this took no effort, and you'll need to do some tweaking to this to meet your needs... post your results back to share when you get it working.
Glenn
_________________________ Actually I am a Rocket Scientist!
#192900 - 2009-03-1503:07 AMRe: User Account Locked Notification
[Re: Gargoyle]
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4401
Loc: New Jersey
Don't you work for some Govt agency? Doesn't "no timeout" result in a permanant lock on the account until manually unlocked?
When I was at the Fed, we had a similar policy - lockout was permanent until someone validated your identity (you know, the "what was your brother's wife's cousin's pet's name when she was in second grade" question.) Once a human being could confirm your answer, they would unlock your account. Often, there were two or three such questions that were asked.
I imagine that most companies with a staffed operations center and dealing with financial or other sensitive data would have similar rules.
Glenn
_________________________ Actually I am a Rocket Scientist!
#192912 - 2009-03-1607:55 AMRe: User Account Locked Notification
[Re: Gargoyle]
NTDOCNTDOC Administrator
Registered: 2000-07-28
Posts: 11628
Loc: CA
Even at the Mouse who was rather paranoid about security, they only locked it out for 15 minutes. The whole point of a lock out is to help prevent HACKING the account, not prevent the user with a slow memory on Monday from doing their job. Yeah I suppose a permanent lockout would help on the hacking part but then goes against the other part which is more often than not the reason for the lock in the first place.
Registered: 2007-01-17
Posts: 29
Loc: Portland, OR
Originally Posted By: NTDOC
My gosh... how long are you guys locking accounts that you have to send mail?
I work at a financial institution and for us, once you are locked out you better hope you know the Helpdesk's extension because you aren't getting back in until you call them.
#192921 - 2009-03-1606:19 PMRe: User Account Locked Notification
[Re: JeffS]
NTDOCNTDOC Administrator
Registered: 2000-07-28
Posts: 11628
Loc: CA
Oh I see that based on at least a couple responses here and the desire to create code around it.
I'm just saying that I think Management or someone else is/was in charge of setting that lockout duration. Maybe you're Company is somehow under attack from hacking tools or users inside (often the case that an insider is the one doing the attack than outsider) and that is the reason for having a lockout so that you can't automate a tool against an account in that manner (there or other methods). But in a very large network of 140K desktops and 4K+ Servers we never had an account cracked on NT that we were aware of. Yes we have caught people inside using tools to attack accounts (again a reasonable lockout duration puts a big damper on that). We also found Admins copying the security databases and trying to crack them (no duration lockout will thwart that). We did have all types of attacks "attempted" from outside but none of them hacked a NT account. We did have a couple of FTP accounts on Linux hacked though one of which also lead to root take over. On a different subject - Web attacks on Windows boxes have been more successful than most other methods.
So I still have to ask WHY!!! I just see it as adding a layer of un-needed support on one end to open it back up, and also creating a non productive user for anywhere from an hour to a day or more???
My view is that we as IT Professionals are here to ENABLE users not CONTROL users.
Registered: 2007-01-17
Posts: 29
Loc: Portland, OR
Code:
; read flags
$Flags = $objUser.UserFlags
; if not disabled, and not Never Expires, report on expired or about to expire accounts
If Not $objUser.AccountDisabled And Not ($Flags & 65536)
$ExpDate = FixDate($objUser.PasswordExpirationDate)
$Days = Int(TimeDiff('Now', $ExpDate, 'D'))
$LStat = $objUser.IsAccountLocked
$EStat = $objUser.PasswordExpired
If $EStat Or $LStat Or $Days < 10
$R = $R + 1
ReDim Preserve $RptData[$R]
$RptData[$R] = Left($Member + ' ', 15)
$RptData[$R] = $RptData[$R] + Left($objUser.FullName + ' ', 40)
; display LOCKED and EXPIRED status
If $LStat
$RptData[$R] = $RptData[$R] + 'LOCKED '
Else
$RptData[$R] = $RptData[$R] + ' '
EndIf
If $EStat
$RptData[$R] = $RptData[$R] + 'EXPIRED ' + @CRLF + ' ' + $ExpDate
Else
; get remaining days
If $Days < $MaxDays
$RptData[$R] = $RptData[$R] + $Days + ' REMAIN ' + @CRLF + ' ' + $ExpDate
Else
$RptData[$R] = $RptData[$R] + ' '
EndIf
EndIf
If Exist('.\debug.txt')
$RptData[$R] ?
$I = $I + 1
If $I > 100 Quit 0 EndIf
EndIf
EndIf
EndIf
I ran the full report as pasted into the forum. However, I was looking at the expired accounts and some of them have a date set out in the future, some as far as June this year. What is that date? Or is there an issue with he way the script converts the time of a previous year?
Registered: 2007-01-17
Posts: 29
Loc: Portland, OR
Originally Posted By: NTDOC
Oh I see that based on at least a couple responses here and the desire to create code around it.
I'm just saying that I think Management or someone else is/was in charge of setting that lockout duration. Maybe you're Company is somehow under attack from hacking tools or users inside (often the case that an insider is the one doing the attack than outsider) and that is the reason for having a lockout so that you can't automate a tool against an account in that manner (there or other methods). But in a very large network of 140K desktops and 4K+ Servers we never had an account cracked on NT that we were aware of. Yes we have caught people inside using tools to attack accounts (again a reasonable lockout duration puts a big damper on that). We also found Admins copying the security databases and trying to crack them (no duration lockout will thwart that). We did have all types of attacks "attempted" from outside but none of them hacked a NT account. We did have a couple of FTP accounts on Linux hacked though one of which also lead to root take over. On a different subject - Web attacks on Windows boxes have been more successful than most other methods.
So I still have to ask WHY!!! I just see it as adding a layer of un-needed support on one end to open it back up, and also creating a non productive user for anywhere from an hour to a day or more???
My view is that we as IT Professionals are here to ENABLE users not CONTROL users.
I am currently working at my second financial institutions as an Admin and in both settings, there has no been a setting to unlock the account after a certain time period. The user HAS to call in to get their account unlocked.
Both places I have screamed until I am blue in the face about this, it is probably costing you more in salary and productivity not to set this setting. Think about it, the productivity lost of the user who is locked out and also the productivity the helpdesk user taking the call and from other issues.
I believe Management sees this as another potential way to safe guard and potentially save a buck. By having users call in to get unlocked they can potentially skip other costs somewhere else. Maybe cheaper security equipment, etc.
To me, you should either set the setting to allow it to unlock after a certain amount of time or to purchase a product where the user can unlock themselves.
#192955 - 2009-03-1708:40 PMRe: User Account Locked Notification
[Re: NTDOC]
Glenn BarnasGlenn Barnas KiX Supporter
Registered: 2003-01-28
Posts: 4401
Loc: New Jersey
To answer the original question, the expiration date you're seeing is when the password "would" expire if you had an expiration policy in place. If it's 4 months out, it would seem that a policy somewhere was set at one time to 120 days or so. That is also why you may see accounts that have expire dates in the past, but aren't affected because they have an "account never expires" setting.
Glenn
_________________________ Actually I am a Rocket Scientist!
Registered: 2007-01-17
Posts: 29
Loc: Portland, OR
Modified the script, however I am having an issue. Even when the account is locked it reports it is NOTLOCKED. I am obviously missing something somewhere but I am stumped. Any help?
Code:
;; KixGenerated: 2008/10/22 10:00:32
Break On
Dim $Members, $Member ; array of domain user members, enumerator var
Dim $I ; index var
Dim $objUser ; AD user query object pointer
Dim $Flags ; user flags
Dim $LStat ; locked status flags
Dim $RptData[0], $R ; report array, record pointer
Dim $Header ; report page header
Dim $MailTo, $MailSender, $MailServer ; mail parameters
Dim $BlatCmd ; Blat command string
; get array of user accounts
'Collecting'
$Members = GroupMembers(@DOMAIN, 'Domain Users', 2)
Chr(13) 'Reporting ' ?
$R = -1
; header
;00000000011111111112222222222333333333344444444445555555555666666666677777777778
;12345678901234567890123456789012345678901234567890123456789012345678901234567890
$Header = 'UserID UserName Locked? Expired?' + @CRLF
$Header = $Header + ' Expiration date' + @CRLF
$Header = $Header + '===============================================================================' + @CRLF
For Each $Member In $Members
; get specific user data
$objUser = GetObject('WinNT://' + @DOMAIN + '/' +$Member + ',user')
$LStat = $objUser.IsAccountLocked
If $LStat = TRUE
$R = $R + 1
ReDim Preserve $RptData[$R]
$RptData[$R] = Left($Member + ' ', 15)
$RptData[$R] = $RptData[$R] + Left($objUser.FullName + ' ', 40)
If $LStat
$RptData[$R] = $RptData[$R] + 'LOCKED'
Else
$RptData[$R] = $RptData[$R] + 'NOTLOCKED'
EndIf
If Exist('.\debug.txt')
$RptData[$R] ?
$I = $I + 1
If
$I > 100 Quit 0
EndIf
EndIf
EndIf
Next
Del '%S_CONFIG%\Logs\Locked.txt' ; remove prior report
$R = RedirectOutput('%S_CONFIG%\Logs\Locked.txt') ; create new report file
$Header ; output the header
For $R = 0 to UBound($RptData)
If $R Mod 52 = 0 And $R > 0
Chr(12) $Header ; output a formfeed and header every 52 records
EndIf
$RptData[$R] ?
Next
$R = RedirectOutput('') ; close the report file
$MailTo = ReadProfileString('%S_CONFIG%\lockout.ini', 'MAIL', 'MailTo')
$MailSender = ReadProfileString('%S_CONFIG%\lockout.ini', 'MAIL', 'MailSender')
$MailServer = ReadProfileString('%S_CONFIG%\lockout.ini', 'MAIL', 'MailServer')
; send the report via email (BLAT)
If $MailTo <> ''
$BlatCmd = '%COMSPEC% /c %S_BIN%\Blat\blat.exe %S_CONFIG%\Logs\Locked.txt'
$BlatCmd = $BlatCmd + ' -to ' + $MailTo
$BlatCmd = $BlatCmd + ' -subject "Expiring Passwords"'
$BlatCmd = $BlatCmd + ' -f ' + $MailSender
$BlatCmd = $BlatCmd + ' -server ' + $MailServer
$BlatCmd = $BlatCmd + ' >NUL:'
Shell $BlatCmd
EndIf
Exit 0
;
;FUNCTION GroupMembers
;
;ACTION Returns an array of all group members of the specified group
;
;SYNTAX GroupMembers(Target, Group, [FLAG])
;
;PARAMETERS Target
; The Domain name or Workstation to work with. For faster workstation
; execution, include the Domain Name that the workstation is a meber of.
;
; "Kixtart/beanbag" would be working with the workstation Beanbag in the
; Kixtart domain
;
; Group
; The Group you want to query
;
; [FLAGS]
; To use the flags options add the numbers of the desired flags toghthers and
; Use that number in the flag field.
;
; Filter :(only one filter flag at a time please)
; 1 = all
; 2 = Users only
; 4 = Groups only
;
; ADSI Information(return ADSI information "pick only one")
; 8 = ADSPath field
; 16 = ADSI Object Handle
;
;RETURNS an array containing , if the ADSPath option is used the ADSPath
; will also be returned |.
;
;REMARKS ADSI com object must be installed.
;
;EXAMPLES ;this return all members of the Domain Admins group in the kixtart domain.
; $members = groupmembers("kixtart","Domain admins")
;
; ;this will will return all groups in the local administrators group on
; ;the Workstation beanbad in the kixtart domain. Also the
; $groups = groupmembers("kixtart/beanbag","Administratoos","group")
Function Groupmembers($target, $group, optional $flag)
DIM $temparray[8], $member, $i, $chunk, $flag, $ADSIFlag, $filterFlag
$chunk = ubound($temparray)
$flag = val($flag)
$i = 0
$group = getobject("WinNT://" + $target + "/" + $group)
if vartype($group) <> 9 exit(@error) endif
select
case $flag & 1
$filterflag = 1
case $flag & 2
$filterflag = 2
case $flag & 4
$filterflag = 4
case 1
$filterflag = 1
endselect
select
case $flag & 8
$ADSIFlag = 8
case $flag & 16
$ADSIFlag = 16
endselect
for each $member in $group.members
select
case $filterflag = 2 AND $member.class = "user"
if substr($member.name,len($member.name),1) <> Chr(36)
$temparray[$i] = $member.name
select
case $adsiflag = 8
$temparray[$i] = $member.adspath
case $adsiflag = 16
$temparray[$i] = $member
endselect
$i = $i + 1
endif
case $filterflag = 4 AND $member.class = "Group"
if substr($member.name,len($member.name),1) <> Chr(36)
$temparray[$i] = $member.name
select
case $adsiflag = 8
$temparray[$i] = $member.adspath
case $adsiflag = 16
$temparray[$i] = $member
endselect
$i = $i + 1
endif
case $filterflag = 1
if substr($member.name,len($member.name),1) <> Chr(36)
$temparray[$i] = $member.name
select
case $adsiflag = 8
$temparray[$i] = $member.adspath
case $adsiflag = 16
$temparray[$i] = $member
endselect
$i = $i + 1
endif
case $filterflag
;bit bucket
endselect
if $i = ubound($temparray)
redim preserve $temparray[Ubound($temparray)+$chunk]
endif
next
if $i <> 0
redim preserve $temparray[$i-1]
$groupmembers=$temparray
endif
endfunction