Using system;
Using System.directoryServices;
Namespace systemframeworks.helper
{
///
/// Active directory auxiliary class. Package a series of active directory operations related methods.
///
Public Sealed Class Adhelper
{
///
/// domain name
///
Private static string domainname = "mydomain";
///
/// LDAP address
///
Private static string ldapdomain = "DC = mydomain, dc = local";
///
/// LDAP binding path
///
Private static string adpath = "ldap://brooocks.mydomain.local";
///
/// log in account
///
Private static string aduser = "administrator";
///
/// login password
///
Private static string adpassword = "password";
///
/// Play an example
///
Private static identityimpersonation impersonate = new IdentityimPersonation (aduser, adpassword, domainname);
///
/// User login verification result
///
Public Enum LoginResult
{
///
// Normal login
///
Login_user_ok = 0,
///
/// User does not exist
///
Login_user_doesnt_exist,
///
/// User account is disabled
///
Login_user_account_inactive,
///
/// user password is incorrect
///
Login_user_password_incorRect
}
///
// User Attribute Definition Sign
///
Public enum ads_user_flag_enum
{
///
/// Log in to the script flag. This flag is invalid if you read or write through the ADSI LDAP. If you pass through the ADSI WINNT, the logo is read-only.
///
ADS_UF_Script = 0x0001,
///
/// User account disable flag
///
ADS_UF_ACCOUNTDISABLE = 0x0002,
///
// main folder flag
///
ADS_UF_HOMEDIR_REQUIRED = 0x0008,
///
/// expired sign
///
ADS_UF_LOCKOUT = 0x0010,
///
/// User password is not necessary
///
ADS_UF_PASSWD_NOTREQD = 0x0020,
///
/// password cannot be changed
///
ADS_UF_PASSWD_CANT_CHANGE = 0x0040,
///
/// Use reversible encryption to save password
///
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x0080,
///
// / Local account sign
///
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0x0100,
///
/// Normal user's default account type
///
ADS_UF_NORMAL_ACCOUNT = 0x0200,
///
/// Cross-domain trust account logo
///
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x0800, ///
/// Workstation trust account logo
///
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x1000,
///
// server trust account logo
///
ADS_UF_SERVER_TRUST_ACCOUNT = 0x2000,
///
/// password never expired
///
ADS_UF_DONT_EXPIRE_PASSWD = 0x10000,
///
/// MNS account logo
///
ADS_UF_MNS_LOGON_ACCOUNT = 0x20000,
///
/// Interactive login must use smart card
///
ADS_UF_SMARTCARD_REQUIRED = 0x40000,
///
/// When setting the flag, the service account (user or computer account) will be trusted by Kerberos.
///
ADS_UF_TRUSTED_FOR_DELEGATION = 0x80000,
///
/// When setting the flag, even if the service account is trusted by Kerberos, the sensitive account cannot be delegated.
///
ADS_UF_NOT_DELEGATED = 0x100000,
///
/// This account requires the DES encryption type
///
ADS_UF_USE_DES_KEY_ONLY = 0x200000,
///
// / Do not perform Kerberos pre-authentication
///
ADS_UF_DONT_REQUIRE_PREAUTH = 0x4000000,
///
/// User password expired sign
///
ADS_UF_PASSWORD_EXPIRED = 0x800000,
///
/// User account can be entrusted
///
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000
}
Public adhelper ()
{
//
}
#Region getDirectoryObject
///
/// Get the DirectoryEntry object instance, log in to the Administrator
///
///
Private static directoryentry getDirectoryObject ()
{
DirectoryEntry Entry = New DirectoryEntry (Adpath, ADUser, Adpassword, AuthenticationTypes.Secure);
Return Entry;
}
///
// / get the corresponding DirectoryEntry entity according to the specified username and password
///
///
///
///
Private Static DirectoryEntry GetDirectoryObject (String UserName, String Password)
{
DirectoryEntry Entry = New DirectoryEntry (Adpath, UserName, Password, AuthenticationTypes.none);
Return Entry;
}
///
/// i.e. / cn = users, dc = Creditsights, DC = cybelves, DC = COM
///
///
///
Private statoryEntry GetDirectoryObject (String DomainReference)
{
DirectoryEntry Entry = New DirectoryEntry (Adpath DomainReference, ADuser, Adpassword, AuthenticationTypes.Secure); Return Entry
}
///
/// Get DirectoryEntry created with username, password
///
///
///
///
///
Private Static DirectoryEntry GetDirectoryObject (String UserName, String Password)
{
DirectoryEntry Entry = New DirectoryEntry (Adpath DomainReference, UserName, Password, AuthenticationTypes.Secure);
Return Entry;
}
#ndregion
#Region getDirectoryEntry
///
/ / According to the user's public name, get the user's object
///
/// user public name
/// If you find the user, return to the user's object; otherwise return NULL
Public Static DirectoryEntry GetDirectoryEntry (String Commonname)
{
DirectoryEntry de = getDirectoryObject ();
DirectorySEARCHER DeSearch = New DirectorySearcher (DE);
Desearch.filter = "(& (ObjectCategory = Person) (CN =" CommonName ")"
Desearch.searchscope = searchscope.subtree;
Try
{
SearchResult results = desearch.findone ();
DE = New DirectoryEntry (Result.Path);
Return de;
}
Catch
{
Return NULL;
}
}
///
// / Note the user's object according to the user public name and password.
///
/// user public name
/// user password
/// If you find the user, return to the user's object; otherwise return NULL
Public Static DirectoryEntry GetDirectoryEntry (String Commonname, String Password)
{
DirectoryEntry de = getDirectoryObject (Commonname, Password);
DirectorySEARCHER DeSearch = New DirectorySearcher (DE);
Desearch.filter = "(& (ObjectCategory = Person) (CN =" CommonName ")"
Desearch.searchscope = searchscope.subtree;
Try
{
SearchResult results = desearch.findone ();
DE = New DirectoryEntry (Result.Path);
Return de;
}
Catch
{
Return NULL;
}
///
/ / / According to the user account number, obtain the user's object
///
/// User account name
/// If you find the user, return to the user's object; otherwise return NULL
Public Static DirectoryEntry GetDirectoryEntryByAccount (String Samaccountname)
{
DirectoryEntry de = getDirectoryObject ();
DirectorySEARCHER DeSearch = New DirectorySearcher (DE);
Desearch.filter = "(& (" ObjectClass = USER) (SamaccountName = " SamaccountName ") "
Desearch.searchscope = searchscope.subtree;
Try
{
SearchResult results = desearch.findone ();
DE = New DirectoryEntry (Result.Path);
Return de;
}
Catch
{
Return NULL;
}
}
///
/ / Obtain the user's object according to the user account and password
///
/// User account name
/// user password
/// If you find the user, return to the user's object; otherwise return NULL
Public Static DirectoryEntry GetDirectoryEntryByAccount (String Samaccountname, String Password)
{
DirectoryEntry de = getDirectoryEntryByAccount (SamaccountName);
IF (de! = null)
{
String commonname = de.properties ["cn"] [0] .tostring ();
IF (COMMONNAME, PASSWORD)! = NULL)
Return getDirectoryEntry (Commonname, Password);
Else
Return NULL;
}
Else
{
Return NULL;
}
}
///
/ / Object of the user group according to the group name
///
/// group name
///
Public Static DirectoryEntry GetDirectoryEntryOfGroup (String Groupname)
{
DirectoryEntry de = getDirectoryObject ();
DirectorySEARCHER DeSearch = New DirectorySearcher (DE);
Desearch.filter = "(& (ObjectClass = group) (CN =" Groupname ")"
Desearch.searchscope = searchscope.subtree;
Try
{
SearchResult results = desearch.findone ();
DE = New DirectoryEntry (Result.Path);
Return de;
}
Catch
{
Return NULL;
}
}
#ndregion
#Region getProperty
///
/// Get the value corresponding to the specified specified attribute name
///////
/// attribute name
/// attribute value
Public Static String GetProperty (DirectoryEntry de, String property)
{
IF (de.properties.contains (propertyname))
{
Return de.properties [propertyname] [0] .tostring ();
}
Else
{
Return string.empty;
}
}
///
/// Get the value corresponding to the specified property name in the specified search result
///
///
/// attribute name
/// attribute value
Public Static String GetProperty (SearchResult SearchResult, String PropertyName)
{
IF (SearchResult.properties.Contains (propertyname))
{
Return SearchResult.properties [PropertyName] [0] .tostring ();
}
Else
{
Return string.empty;
}
}
#ndregion
///
/// Set the specified attribute value
///
///
/// attribute name
/// attribute value
Public Static Void SetProperty (DirectoryEntry DE, String PropertyName, String PropertyValue)
{
IF (PropertyValue! = String.empty || PropertyValue! = "" || PropertyValue! = null)
{
IF (de.properties.contains (propertyname))
{
de.properties [PropertyName] [0] = PropertyValue;
}
Else
{
de.properties [PropertyName] .add (PropertyValue);
}
}
}
///
/// Create a new user
///
/// DN position. For example: OU = shared platform or cn = user
// / public name
/// account number
/// password
///
Public Static DirectoryEntry CreateNewUser (String Ldapdn, String Samaccountname, String Password)
{
DirectoryEntry entry = getdirectoryObject ();
DirectoryEntry SubenTry = entry.children.find (ldaPDN);
DirectoryEntry deuser = Subentry.children.Add ("cn =" commonname, "user";
DEUSER.PROPERTIES ["SamaccountName"]. Value = SamaccountName
DEUSER.commitchanges ();
Adhelper.enableuser (Commonname);
Adhelper.SetPassword (CommonName, Password);
DEUSER.CLOSE ();
Return deuse;
}
///
/// Create a new user. Create by default under the Users unit.
///
// / public name
/// account number
/// password
///
Public Static DirectoryEntry CreateNewUser (String Samaccountname, String Password) {
Return CreateNewuser ("CN = Uses", CommonName, SamaccountName, Password;
}
///
/// Determine if the user of the specified public name exists
///
/// user public name
/// If there is, return true; otherwise return false
Public Static Bool IsuseRexists (String Common "
{
DirectoryEntry de = getDirectoryObject ();
DirectorySEARCHER DeSearch = New DirectorySearcher (DE);
Desearch.filter = "(& (ObjectCategory = Person) (CN =" CommonName ")"; // LDAP query string
SearchResultCollection results = duence.findall ();
IF (results.count == 0)
Return False;
Else
Return True;
}
///
/// Determine if the user account is activated
///
/// User Account Properties Controller
/// If the user account is activated, return true; otherwise return false
Public Static Bool IsaccountActive (int useractControl)
{
INT uSERACCOUNTCONTROL_DISABLED = Convert.Toint32 (ADS_USER_FLAG_ENUM.ADS_UF_ACCOUNTDISABLE);
Int flagXists = useeraccountControl & UseraccountControl_disabled;
IF (Flagexists> 0)
Return False;
Else
Return True;
}
///
/// Determine if the user and the password are sufficient to meet the authentication and then log in
///
/// user public name
/// password
// / Return true if you can log in normally; otherwise return false
Public Static loginResult login (String Commonname, String Password)
{
DirectoryEntry de = getDirectoryEntry (Commonname);
IF (de! = null)
{
/ / The account activation attribute must be judged before determining the user password; otherwise an exception will appear.
INT useraccountControl = Convert.Toint32 (de.properties ["UseraccountControl"] [0]);
de.close ();
IF (! isaccountactive (useeraccountControl))
Return LoginResult.login_user_account_inactive;
IF (COMMONNAME, PASSWORD)! = NULL)
Return LoginResult.login_user_ok;
Else
Return loginResult.login_user_password_incorRect;
Else
{
Return LoginResult.login_user_doesnt_exist;
}
}
///
/// Determine if the user account and the password are sufficient to meet the authentication and log in
///
/// user account
/// password
// / Return true if you can log in normally; otherwise return false
Public Static LoginResult LoginByAccount (String Samaccountname, String Password)
{
DirectoryEntry de = getDirectoryEntryByAccount (SamaccountName);
IF (de! = null)
{
/ / The account activation attribute must be judged before determining the user password; otherwise an exception will appear.
INT useraccountControl = Convert.Toint32 (de.properties ["UseraccountControl"] [0]);
de.close ();
IF (! isaccountactive (useeraccountControl))
Return LoginResult.login_user_account_inactive;
GetDirectoryEntrybyAccount (SamaccountName, Password)! = null)
Return LoginResult.login_user_ok;
Else
Return loginResult.login_user_password_incorRect;
}
Else
{
Return LoginResult.login_user_doesnt_exist;
}
}
///
/// Set the user password, the administrator can modify the password of the specified user.
///
/// user public name
/// user new password
Public Static Void SetPassword (String Commonname, String NewPassword)
{
DirectoryEntry de = getDirectoryEntry (Commonname);
// Simulate super administrators to achieve permission to modify user password
Impersonate.beginimpersonate ();
de.invoke ("setPassword", new object [] {newpassword};
Impersonate.stopimpersonate ();
de.close ();
}
///
/// Set the account password, the administrator can modify the password of the specified account.
///
/// user account
/// user new password
Public Static Void SetPasswordByAccount (String Samaccountname, String NewPassword)
{
DirectoryEntry de = getDirectoryEntryByAccount (SamaccountName);
// Simulate super administrators to achieve permission to modify user password
Identityimpersonation Impersonate = New IdentityimPersonation (ADUser, Adpassword, DomainName);
Impersonate.beginimpersonate ();
de.invoke ("setPassword", new object [] {newpassword};
Impersonate.stopimpersonate ();
de.close ();
}
///
// / Modify user password
///
/// user public name
/// old password
/// new password
Public Static Void ChangeUserpassword (String Commonname, String Newpassword)
{
// to-do: Need to solve password policy issues
DirectoryEntry Ouser = getDirectoryEntry (Commonname);
OUSER.INVOKE ("ChangePassword", New Object [] {oldpassword, newpassword});
OUSER.CLOSE ();
}
///
// Enable users specified public name
///
/// user public name
Public static void enableuser (String Commonname)
{
Enableuser (COMMONNAME);
}
///
// / Enable the specified user
///
///
Public Static Void Enableuser (DirectoryEntry DE)
{
Impersonate.beginimpersonate ();
De.properties ["UseraccountControl"] [0] = adhelper.ads_user_flag_enum.ads_uf_normal_account | adhelper.ads_user_flag_enum.ads_uf_dont_expire_passwd;
de.commitchanges ();
Impersonate.stopimpersonate ();
de.close ();
}
///
// / Users who disable the designated public name
///
/// user public name
Public static void disableuser (String Commonname)
{
Disableuser (COMMONNAME)) and DISABLETRY
}
///
/ / Disable the specified user
///
///
Public Static Void Disableuser (DirectoryEntry DE)
{
Impersonate.beginimpersonate ();
de.Properties [ "userAccountControl"] [0] = ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_NORMAL_ACCOUNT | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_ACCOUNTDISABLE;
de.commitchanges ();
Impersonate.stopimpersonate ();
de.close ();
}
///
/// Add the specified user to the specified group. The group and user under Users.
///
/// user public name
/// group name
Public Static Void Addusertogroup (String UserCommonname, String Groupname)
{
DirectoryEntry OGroup = getDirectoryEnTryOfGroup (groupname);
DirectoryEntry Ouser = getDirectoryEntry (usercommonname);
Impersonate.beginimpersonate ();
Ogroup.properties ["Member"]. add (OUSER.PROPERTIES ["DISTINGUISHEDNAME"]. Value); OGroup.commitchanges ();
Impersonate.stopimpersonate ();
Ogroup.close ();
OUSER.CLOSE ();
}
///
/// Remove the user from the specified group. The group and user under Users.
///
/// user public name
/// group name
Public Static Void RemoveUserFromGroup (String UserCommonname, String Groupname)
{
DirectoryEntry OGroup = getDirectoryEnTryOfGroup (groupname);
DirectoryEntry Ouser = getDirectoryEntry (usercommonname);
Impersonate.beginimpersonate ();
Ogroup.properties ["MEMBER"]. Remove (OUSER.PROPERTIES ["DISTINGUISHEDNAME"]. Value);
Ogroup.commitchanges ();
Impersonate.stopimpersonate ();
Ogroup.close ();
OUSER.CLOSE ();
}
}
///
/// User simulates the role class. Implement the user role simulation within the block.
///
Public Class IdentityImPersonation
{
[DLLIMPORT ("Advapi32.dll", SetLastError = true)]
Public Static Extern Bool Logonuser (String Lpszusername, String Lpszdomain, String Lpszpassword, int dwlogontype, int dwlonprovider, ref INTPTPTR phoken);
[DLLIMPORT ("Advapi32.dll", Charset = charset.auto, setLastError = true)]
Public Extern Static Bool DuplicateToken (INT Security_impersonation_level, ref INTPTR DUPLICATETOLENDE);
[DLLIMPORT ("kernel32.dll", charset = charSet.Auto)]
Public Extern Static Bool CloseHandle (INTPTR HANDLE);
// User name, password, domain (machine name) to be simulated
Private string _simperusername;
Private string _simperpassword;
Private string _simperdomain
// Record the simulation context
Private windowsimpersonationContext_impercontext;
Private INTPTR _ADMINTOKEN;
Private INTPTR _DUPETOKEN
/ / Whether it has stopped simulation
Private boolean _bclosed;
///
/// Constructor
///
/// user name of the user to simulate
/// The password of the user to simulate
/// The domain where the user wants to simulate
Public IdentityimPersonation (String ImpersonationUsername, String ImpersonationDomain) {
_simperusername = impersonation ionUsername;
_simperpassword = impersonationpassword;
_simperdomain = impersonationdomain;
_admintoken = INTPTR.ZERO;
_dupetoken = intptr.zero;
_bclosed = true;
}
///
/// destructor
///
~ IdentityimPersonation ()
{
IF (! _ bclosed)
{
Stopimpersonate ();
}
}
///
/// Start identity role simulation.
///
///
Public Boolean Beginimpersonate ()
{
Boolean blogined = logonuser (_SIMPERUSERNAME, _SIMPERDOMAIN, _SIMPERPASSWORD, 2, 0, REF _ADMINTOKEN);
IF (! blogined)
{
Return False;
}
Boolean bduped = duplicatetoken (_ADMintoken, 2, ref _dupetoken);
IF (! bduped)
{
Return False;
}
Windowsidentity Fakeid = New WindowsIdentity (_DuPetoken);
_impercontext = fakeid.impersonate ();
_BClosed = false;
Return True;
}
///
/// Stop the identity role simulation.
///
Public void stopimpersonate ()
{
_impercontext.undo ();
CloseHandle (_DuPetoken);
CloseHandle (_ADMINTOKEN);
_bclosed = true;
}
}
}