clear oADs=CREATEOBJECT("ADSystemInfo") lcGroups = '' lcLogin = ALLTRIM(SUBSTR(sys(0),AT('#',sys(0))+1)) ?"**********************************************************************************" ?"Current Login: "+lcLogin lcComputer = alltrim(left(sys(0), at("#", sys(0)) - 1)) ?" Workstation: "+lcComputer ?" User Name: "+oADs.UserName lcvalue = '' lcdomain = '' for i = 1 TO LEN(oADS.UserName) lcvalue = lcvalue + SUBSTR(oADS.UserName,i,1) IF RIGHT(lcvalue,3) = "DC=" lcdomain = '' FOR i2 = i+1 TO LEN(oADS.UserName) IF SUBSTR(oADS.UserName,i2,1) = "," EXIT ELSE lcDomain = lcDomain + SUBSTR(oADS.UserName,i2,1) ENDIF ENDFOR EXIT ENDIF ENDFOR ?" Domain: "+lcDomain oUser=GETOBJECT("LDAP://"+oADs.UserName) ?" Email: "+oUser.get("mail") && email address ?"**********************************************************************************" cDomain = lcDomain cUserName = lcLogin cDomain = inputbox("Domain you want to use:",'Active Directory Properties',lcDomain) cUserName = INPUTBOX("User Login:",'Active Directory Properties',lcLogin) cDomain = ALLTRIM(cDomain) cUserName = ALLTRIM(cUserName) IF EMPTY(cDomain) OR EMPTY(cUserName) RELEASE ALL CLEAR ALL RETURN ENDIF *cUserName = alltrim(substr(sys(0), at("#", sys(0)) + 1)) cComputer = alltrim(left(sys(0), at("#", sys(0)) - 1)) * Note these moniker types are case-sensitive: Winnt:// *will not work* oUser = getobject("WinNT://" + cDomain + "/" + cUserName + ",user") if oUser.AccountDisabled ? "Account is disabled" ? endif ? "User properties for " + cUserName * Populate the properties (the data may be there but the propertycount * isn't until this has been called) oUser.GetInfo() ShowProperties(oUser) ? ? "Group properties for " for each oGroup in oUser.Groups IF TYPE('oGroup.Name') = "C" lcGroups = lcGroups + oGroup.name+REPLICATE(' ',45)+CHR(13) ENDIF ?? ['] + oGroup.name + ['] ShowProperties(oGroup) * One will suffice. *exit next ? oComputer = getobject("WinNT://" + cDomain + "/" + cComputer + ",computer") oComputer.GetInfo() ? "Workstation properties for " + cComputer ShowProperties(oComputer) IF !EMPTY(lcGroups) =MESSAGEBOX(lcGroups+CHR(13),0+64+4096,'Security Groups for '+cUserName) ENDIF *DO c:\programnotes\activedirectory\cleardlls.prg return procedure ShowProperties lparameters oObject for nCount = 0 to oObject.PropertyCount - 1 * Access the properties collection. oProperty = oObject.item[nCount] ? oProperty.name if not isnull(oProperty.values) for each oValue in oProperty.values vValue = GetPropertyValue(oValue) ?? " : " + transform(vValue) if oProperty.name = "UserFlags" GetUserRights(vValue) endif next endif next endproc procedure GetPropertyValue lparameters oValue local vValue, nType nType = oValue.ADSType * Each type has it's own method to return the value (note to designer - ??) do case case nType = 1 vValue = oValue.DNString() case nType = 2 vValue = oValue.CaseExactString() case nType = 3 vValue = oValue.CaseIgnoreString() case nType = 4 vValue = oValue.PrintableString() case nType = 5 vValue = oValue.NumericString() case nType = 6 vValue = oValue.Boolean() case nType = 7 * Reserved word vValue = oValue.integer() case nType = 8 vValue = oValue.OctetString() case nType = 9 vValue = oValue.UTCTime() case nType = 10 vValue = oValue.LargeInteger() case nType = 25 vValue = oValue.SecurityDescriptor() otherwise * Other types can't be obtained through this interface. vValue = .null. endcase return vValue endproc procedure GetUserRights lparameters nFlags if bittest(nFlags, 0) && ADS_UF_SCRIPT, 1 ? "The logon script is executed." endif if bittest(nFlags, 1) && ADS_UF_ACCOUNTDISABLE, 2 ? "The user account is disabled." endif if bittest(nFlags, 2) && ?? ? "The third bit is set." endif if bittest(nFlags, 3) && ADS_UF_HOMEDIR_REQUIRED, 8 ? "The home directory is required." endif if bittest(nFlags, 4) && ADS_UF_LOCKOUT, 16 ? "The account is currently locked out." endif if bittest(nFlags, 5) && ADS_UF_PASSWD_NOTREQD, 32 ? "No password is required." endif if bittest(nFlags, 6) && ADS_UF_PASSWD_CANT_CHANGE, 64 ? "The user cannot change the password." endif if bittest(nFlags, 7) && ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED, 128 ? "The user can send an encrypted password." endif if bittest(nFlags, 8) && ADS_UF_TEMP_DUPLICATE_ACCOUNT, 256 ? "This is an account for users whose primary account is in another domain." endif if bittest(nFlags, 9) && ADS_UF_NORMAL_ACCOUNT, 512 ? "This is a default account type that represents a normal user." endif if bittest(nFlags, 10) && ?? ? "The tenth bit is set." endif if bittest(nFlags, 11) && ADS_UF_INTERDOMAIN_TRUST_ACCOUNT, 2048 ? "This is a permit to trust account for a system domain that trusts other domains." endif if bittest(nFlags, 12) && ADS_UF_WORKSTATION_TRUST_ACCOUNT, 4096 ? "This is an account for a computer which is a member of this domain." endif if bittest(nFlags, 13) && ADS_UF_SERVER_TRUST_ACCOUNT, 8192 ? "This is a computer account for a system backup domain controller that is a member of this domain." endif if bittest(nFlags, 16) && ADS_UF_DONT_EXPIRE_PASSWD, 65536 ? "The password will not expire on this account." endif if bittest(nFlags, 23) && ADS_UF_PASSWORD_EXPIRED, 8388608 ? "The user's password has expired." endif ? * Etc. See http://msdn.microsoft.com/library/en-us/adsi/adsi/ads_user_flag_enum.asp * for the rest and for the full descriptions. * They are mostly security related: Kerberos, smartcards, DES etc. endproc * User rights constants * Not all bits are defined here. Some may be for internal use? #define ADS_UF_SCRIPT 1 #define ADS_UF_ACCOUNTDISABLE 2 #define ADS_UF_HOMEDIR_REQUIRED 8 #define ADS_UF_LOCKOUT 16 #define ADS_UF_PASSWD_NOTREQD 32 #define ADS_UF_PASSWD_CANT_CHANGE 64 #define ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 128 #define ADS_UF_TEMP_DUPLICATE_ACCOUNT 256 #define ADS_UF_NORMAL_ACCOUNT 512 #define ADS_UF_INTERDOMAIN_TRUST_ACCOUNT 2048 #define ADS_UF_WORKSTATION_TRUST_ACCOUNT 4096 #define ADS_UF_SERVER_TRUST_ACCOUNT 8192 #define ADS_UF_DONT_EXPIRE_PASSWD 65536 #define ADS_UF_MNS_LOGON_ACCOUNT 131072 #define ADS_UF_SMARTCARD_REQUIRED 262144 #define ADS_UF_TRUSTED_FOR_DELEGATION 524288 #define ADS_UF_NOT_DELEGATED 1048576 #define ADS_UF_USE_DES_KEY_ONLY 2097152 #define ADS_UF_DONT_REQUIRE_PREAUTH 4194304 #define ADS_UF_PASSWORD_EXPIRED 8388608 #define ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 16777216 * Property type constants #define ADSTYPE_INVALID 0 && The data type is invalid. #define ADSTYPE_DN_STRING 1 && the string is a Distinguished Name (path) of a directory service object. #define ADSTYPE_CASE_EXACT_STRING 2 && the string is the case-sensitive type. #define ADSTYPE_CASE_IGNORE_STRING 3 && the string is the case-insensitive type. #define ADSTYPE_PRINTABLE_STRING 4 && The string is displayable on screen or in print. #define ADSTYPE_NUMERIC_STRING 5 && the string is a numeral to be interpreted as text. #define ADSTYPE_BOOLEAN 6 && the data is a Boolean value. #define ADSTYPE_INTEGER 7 && the data is an integer value. #define ADSTYPE_OCTET_STRING 8 && the string is a byte array. #define ADSTYPE_UTC_TIME 9 && the data is the universal time as expressed in Universal Time Coordinate (UTC). #define ADSTYPE_LARGE_INTEGER 10 && the data is a long integer value. #define ADSTYPE_PROV_SPECIFIC 11 && the string is a provider-specific string. #define ADSTYPE_OBJECT_CLASS 12 && Not used. #define ADSTYPE_CASEIGNORE_LIST 13 && the data is a list of case insensitive strings. #define ADSTYPE_OCTET_LIST 14 && the data is a list of octet strings. #define ADSTYPE_PATH 15 && the string is a directory path. #define ADSTYPE_POSTALADDRESS 16 && the string is the postal address type. #define ADSTYPE_TIMESTAMP 17 && the data is a time stamp in seconds. #define ADSTYPE_BACKLINK 18 && the string is a back link. #define ADSTYPE_TYPEDNAME 19 && the string is a typed name. #define ADSTYPE_HOLD 20 && the data is the Hold data structure. #define ADSTYPE_NETADDRESS 21 && the string is a net address. #define ADSTYPE_REPLICAPOINTER 22 && the data is a replica pointer. #define ADSTYPE_FAXNUMBER 23 && the string is a fax number. #define ADSTYPE_EMAIL 24 && the data is an e-mail message. #define ADSTYPE_NT_SECURITY_DESCRIPTOR 25 && the data is Windows NT/Windows 2000 security descriptor as represented by a byte array. #define ADSTYPE_UNKNOWN 26 && the data is an undefined type. #define ADSTYPE_DN_WITH_BINARY 27 && The data is used for mapping a distinguished name to a non varying GUID. #define ADSTYPE_DN_WITH_STRING 28 && The data is used for mapping a distinguished name to a non-varying string value.>> However, if I want to check a username and password, but not actually
>
>* Credentials
>cUserName = "stuartd"
>cPassword = "secret"
>
>* any OUs required to access user object
>cOUString = "OU=Users,OU=Staff"
>
>* required DC string
>cDCString = "DC=mydomain,DC=com"
>
>* The path returned must be able to create a user using GetObject() in order to work
>* with OpenDSPath()
>cPath = "LDAP://" + cDomain + "/CN=" + cUser + "," + cOUString + "," + cDCString
>
>oLDAP = getobject("LDAP:")
>
>* Error will occur if username/password is wrong.
>oUser = oLDAP.OpenDSObject(cPath, addbs(cDomain) + cUserName, cPassword, 0)
>
>* Valid.
>oUser.GetInfo()
>? oUser.Name
>
>