protected override void InternalProcessRecord() { TaskLogger.LogEnter(new object[] { this.DataObject }); try { base.InternalProcessRecord(); if (base.IsSetRandomPassword) { MailboxTaskHelper.SetMailboxPassword((IRecipientSession)base.DataSession, this.DataObject, null, new Task.ErrorLoggerDelegate(base.WriteError)); } SmtpAddress value = (SmtpAddress)this.DataObject[ADRecipientSchema.WindowsLiveID]; if (value != SmtpAddress.Empty) { UserAccountControlFlags userAccountControlFlags = (UserAccountControlFlags)this.DataObject[ADUserSchema.UserAccountControl]; if ((userAccountControlFlags & UserAccountControlFlags.AccountDisabled) == UserAccountControlFlags.AccountDisabled) { this.DataObject[ADUserSchema.UserAccountControl] = (userAccountControlFlags & ~UserAccountControlFlags.AccountDisabled); using (TaskPerformanceData.SaveResult.StartRequestTimer()) { base.DataSession.Save(this.DataObject); } } } } finally { ProvisioningPerformanceHelper.StopLatencyDetection(this.latencyContext); } TaskLogger.LogExit(); }
internal static extern NtStatus SamEnumerateUsersInDomain( SafeSamHandle DomainHandle, ref int EnumerationContext, UserAccountControlFlags UserAccountControl, out SafeSamMemoryBuffer Buffer, // PSAM_RID_ENUMERATION * int PreferedMaximumLength, out int CountReturned );
/// <summary> /// Enumerate users in a domain. /// </summary> /// <param name="user_account_control">User account control flags.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The list of users.</returns> public NtResult <IReadOnlyList <SamRidEnumeration> > EnumerateUsers(UserAccountControlFlags user_account_control, bool throw_on_error) { SecurityEnumDelegate <SafeSamHandle, SafeSamMemoryBuffer> enum_func = (SafeSamHandle handle, ref int context, out SafeSamMemoryBuffer buffer, int max_count, out int entries_read) => SecurityNativeMethods.SamEnumerateUsersInDomain(handle, ref context, user_account_control, out buffer, max_count, out entries_read); return(SamUtils.SamEnumerateObjects(Handle, enum_func, (SAM_RID_ENUMERATION s) => new SamRidEnumeration(s), throw_on_error)); }
/// <summary> /// The AddNew function will add new user acount to Active Directory /// </summary> /// <param name="strLogin"></param> /// <param name="strPwd"></param> /// <param name="strFullName"></param> /// <param name="AccountActive"></param> public void AddNewActiveDirectoryUser(string strLogin, string strPwd, string strFullName, bool AccountActive) { string ldapPath = accountWizardSettings.Get("LDAP.Path"); string ldapUserName = Encryptor.Decrypt(accountWizardSettings.Get("LDAP.UserName")); string ldapPassword = Encryptor.Decrypt(accountWizardSettings.Get("LDAP.Passwrod")); DirectoryEntry obDirEntry = new DirectoryEntry(ldapPath, ldapUserName, ldapPassword); bool userFound = false; try { if (obDirEntry.Children.Find("CN=" + strLogin, "user") != null) { userFound = true; } } catch (Exception) { userFound = false; //user not in the system // MessageBox.Show("New User error: " + ex.ToString()); } if (!userFound) //If User Not Found In System { DirectoryEntry obUser = obDirEntry.Children.Add("CN=" + strLogin, "user"); obUser.Properties["sAMAccountName"].Add(strLogin); obUser.Properties["userPrincipalName"].Value = strLogin + "@Edge.BI"; obUser.CommitChanges(); object[] oPassword = new object[] { strPwd }; object ret = obUser.Invoke("SetPassword", strPwd); obUser.CommitChanges(); //UF_DONT_EXPIRE_PASSWD 0x10000 UserAccountControlFlags exp = (UserAccountControlFlags)obUser.Properties["userAccountControl"].Value; obUser.Properties["userAccountControl"].Value = exp | UserAccountControlFlags.UF_DONT_EXPIRE_PASSWD; //what is this? obUser.CommitChanges(); if (AccountActive) { //UF_ACCOUNTDISABLE 0x0002 UserAccountControlFlags val = (UserAccountControlFlags)obUser.Properties["userAccountControl"].Value; obUser.Properties["userAccountControl"].Value = val & ~UserAccountControlFlags.UF_ACCOUNTDISABLE; //what is this? obUser.CommitChanges(); } obUser.Close(); obUser.Dispose(); } obDirEntry.Dispose(); }
private void SetDomainUsersAndComputers() { if (!String.IsNullOrEmpty(MyOptions.TargetDc)) { DomainControllers.Add(MyOptions.TargetDc); } else { GetDomainControllers(); } List <string> domainComputers = new List <string>(); List <string> domainUsers = new List <string>(); // we do this so if the first one fails we keep trying til we find a DC we can talk to. foreach (string domainController in DomainControllers) { try { // TODO add support for user defined creds here. using (DirectoryEntry entry = new DirectoryEntry("LDAP://" + domainController)) { using (DirectorySearcher mySearcher = new DirectorySearcher(entry)) { mySearcher.Filter = ("(objectClass=computer)"); // No size limit, reads all objects mySearcher.SizeLimit = 0; // Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit) mySearcher.PageSize = 250; // Let searcher know which properties are going to be used, and only load those mySearcher.PropertiesToLoad.Add("name"); mySearcher.PropertiesToLoad.Add("dNSHostName"); mySearcher.PropertiesToLoad.Add("lastLogonTimeStamp"); foreach (SearchResult resEnt in mySearcher.FindAll()) { // Note: Properties can contain multiple values. if (resEnt.Properties["dNSHostName"].Count > 0) { string computerName = (string)resEnt.Properties["dNSHostName"][0]; domainComputers.Add(computerName); } } } this._domainComputers = domainComputers; if (MyOptions.DomainUserRules) { // now users using (DirectorySearcher mySearcher = new DirectorySearcher(entry)) { mySearcher.Filter = ("(objectClass=user)"); // No size limit, reads all objects mySearcher.SizeLimit = 0; // Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit) mySearcher.PageSize = 250; // Let searcher know which properties are going to be used, and only load those mySearcher.PropertiesToLoad.Add("name"); mySearcher.PropertiesToLoad.Add("adminCount"); mySearcher.PropertiesToLoad.Add("sAMAccountName"); mySearcher.PropertiesToLoad.Add("userAccountControl"); foreach (SearchResult resEnt in mySearcher.FindAll()) { try { //busted account name if (resEnt.Properties["sAMAccountName"].Count == 0) { continue; } int uacFlags; bool succes = int.TryParse(resEnt.Properties["userAccountControl"][0].ToString(), out uacFlags); UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags; if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled)) { continue; } string userName = (string)resEnt.Properties["sAMAccountName"][0]; // skip computer accounts if (userName.EndsWith("$")) { continue; } if (userName.IndexOf("mailbox", StringComparison.OrdinalIgnoreCase) >= 0) { continue; } if (userName.IndexOf("mbx", StringComparison.OrdinalIgnoreCase) >= 0) { continue; } // if it's got adminCount, keep it if (resEnt.Properties["adminCount"].Count != 0) { if (resEnt.Properties["adminCount"][0].ToString() == "1") { Mq.Trace("Adding " + userName + " to target list because it had adminCount=1."); domainUsers.Add(userName); continue; } } // if the password doesn't expire it's probably a service account if (userAccFlags.HasFlag(UserAccountControlFlags.PasswordDoesNotExpire)) { Mq.Trace("Adding " + userName + " to target list because I think it's a service account."); domainUsers.Add(userName); continue; } if (userAccFlags.HasFlag(UserAccountControlFlags.DontRequirePreauth)) { Mq.Trace("Adding " + userName + " to target list because I think it's a service account."); domainUsers.Add(userName); continue; } if (userAccFlags.HasFlag(UserAccountControlFlags.TrustedForDelegation)) { Mq.Trace("Adding " + userName + " to target list because I think it's a service account."); domainUsers.Add(userName); continue; } if (userAccFlags.HasFlag(UserAccountControlFlags .TrustedToAuthenticateForDelegation)) { Mq.Trace("Adding " + userName + " to target list because I think it's a service account."); domainUsers.Add(userName); continue; } // if it matches a string we like, keep it foreach (string str in MyOptions.DomainUserMatchStrings) { if (userName.ToLower().Contains(str.ToLower())) { Mq.Trace("Adding " + userName + " to target list because it contained " + str + "."); domainUsers.Add(userName); break; } } } catch (Exception e) { Mq.Trace(e.ToString()); continue; } } } } this._domainUsers = domainUsers; } break; } catch (Exception e) { Mq.Trace(e.ToString()); throw; } } }
/// <summary> /// Enumerate and open accessible user objects. /// </summary> /// <param name="user_account_control">User account control flags.</param> /// <param name="desired_access">The desired access for the opened users.</param> /// <returns>The list of accessible users.</returns> public IReadOnlyList <SamUser> OpenAccessibleUsers(UserAccountControlFlags user_account_control, SamUserAccessRights desired_access) { return(OpenAccessibleUsers(user_account_control, desired_access, true).Result); }
/// <summary> /// Enumerate and open accessible user objects. /// </summary> /// <param name="user_account_control">User account control flags.</param> /// <param name="desired_access">The desired access for the opened users.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The list of accessible users.</returns> public NtResult <IReadOnlyList <SamUser> > OpenAccessibleUsers(UserAccountControlFlags user_account_control, SamUserAccessRights desired_access, bool throw_on_error) { return(EnumerateUsers(user_account_control, throw_on_error).Map <IReadOnlyList <SamUser> >(e => e.Select( s => OpenUser(s.RelativeId, s.Name, desired_access, false).GetResultOrDefault()).Where(a => a != null).ToList().AsReadOnly())); }
/// <summary> /// Enumerate users in a domain. /// </summary> /// <param name="user_account_control">User account control flags.</param> /// <returns>The list of users.</returns> public IReadOnlyList <SamRidEnumeration> EnumerateUsers(UserAccountControlFlags user_account_control) { return(EnumerateUsers(user_account_control, true).Result); }
public void SetDomainUsers() { DirectorySearch ds = GetDirectorySearcher(); List <string> domainUsers = new List <string>(); string[] ldapProperties = new string[] { "name", "adminCount", "sAMAccountName", "userAccountControl", "servicePrincipalName", "userPrincipalName" }; string ldapFilter = "(&(objectClass=user)(objectCategory=person))"; IEnumerable <SearchResultEntry> searchResultEntries = ds.QueryLdap(ldapFilter, ldapProperties, System.DirectoryServices.Protocols.SearchScope.Subtree); foreach (SearchResultEntry resEnt in searchResultEntries) { bool keepUser = false; try { //busted account name if (String.IsNullOrEmpty(resEnt.GetProperty("sAMAccountName"))) { continue; } int uacFlags; bool success = int.TryParse(resEnt.GetProperty("userAccountControl"), out uacFlags); UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags; if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled)) { continue; } string userName = resEnt.GetProperty("sAMAccountName"); if (userName.EndsWith("$")) { Mq.Trace("Skipping " + userName + " because it appears to be a computer or trust account."); continue; } //skip mailboxy accounts - domains always have a billion of these. if (userName.IndexOf("mailbox", StringComparison.OrdinalIgnoreCase) >= 0) { Mq.Trace("Skipping " + userName + " because it appears to be a mailbox."); continue; } if (userName.IndexOf("mbx", StringComparison.OrdinalIgnoreCase) >= 0) { Mq.Trace("Skipping " + userName + " because it appears to be a mailbox."); continue; } // if has an SPN, keep it if (!keepUser && resEnt.GetProperty("servicePrincipalName") != null) { Mq.Trace("Adding " + userName + " to target list because it has an SPN"); keepUser = true; } // if it's got adminCount, keep it if (!keepUser && resEnt.GetProperty("adminCount") == "1") { Mq.Trace("Adding " + userName + " to target list because it had adminCount=1."); keepUser = true; } // if the password doesn't expire it's probably a service account if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags.PasswordDoesNotExpire)) { Mq.Trace("Adding " + userName + " to target list because password does not expire, probably service account."); keepUser = true; } if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags.DontRequirePreauth)) { Mq.Trace("Adding " + userName + " to target list because it doesn't require Kerberos pre-auth."); keepUser = true; } if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags.TrustedForDelegation)) { Mq.Trace("Adding " + userName + " to target list because it is trusted for delegation."); keepUser = true; } if (!keepUser && userAccFlags.HasFlag(UserAccountControlFlags .TrustedToAuthenticateForDelegation)) { Mq.Trace("Adding " + userName + " to target list because it is trusted for delegation."); keepUser = true; } // Included patterns if (!keepUser) { foreach (string str in MyOptions.DomainUserMatchStrings) { if (userName.ToLower().Contains(str.ToLower())) { Mq.Trace("Adding " + userName + " to target list because it contained " + str + "."); keepUser = true; break; } } } // Finished testing if (!keepUser) { continue; } // Must have matched something // For common/frequent names, force fully-qualified strict formats if (MyOptions.DomainUserStrictStrings.Contains(userName, StringComparer.OrdinalIgnoreCase)) { Mq.Trace("Using strict formats for " + userName + "."); domainUsers.Add(String.Format(@"{0}\{1}", _targetDomainNetBIOSName, userName)); if (!string.IsNullOrEmpty(resEnt.GetProperty("userPrincipalName"))) { domainUsers.Add(resEnt.GetProperty("userPrincipalName")); } continue; } // Otherwise, go with the format preference from the config file foreach (DomainUserNamesFormat dnuf in MyOptions.DomainUserNameFormats) { switch (dnuf) { case DomainUserNamesFormat.NetBIOS: domainUsers.Add(String.Format(@"{0}\{1}", _targetDomainNetBIOSName, userName)); break; case DomainUserNamesFormat.UPN: if (!string.IsNullOrEmpty(resEnt.GetProperty("userPrincipalName"))) { domainUsers.Add(resEnt.GetProperty("userPrincipalName")); } else { Mq.Trace("Adding " + userName + " with simple sAMAccountName because UPN is missing."); domainUsers.Add(userName); } break; case DomainUserNamesFormat.sAMAccountName: domainUsers.Add(userName); break; } } } catch (Exception e) { Mq.Trace(e.ToString()); continue; } } this._domainUsers = domainUsers; }
public void SetDomainComputers(string LdapFilter) { DirectorySearch ds = GetDirectorySearcher(); List <string> domainComputers = new List <string>(); try { if (!MyOptions.DfsOnly) { // if we aren't limiting the scan to DFS shares then let's get some computer targets. List <string> ldapPropertiesList = new List <string> { "name", "dNSHostName", "lastLogonTimeStamp" }; string ldapFilter = LdapFilter; // extremely dirty hack to break a sig I once saw for Snaffler's LDAP queries. ;-) int num = random.Next(1, 5); while (num > 0) { Guid guid = Guid.NewGuid(); ldapPropertiesList.Add(guid.ToString()); --num; } string[] ldapProperties = ldapPropertiesList.ToArray(); IEnumerable <SearchResultEntry> searchResultEntries = ds.QueryLdap(ldapFilter, ldapProperties, System.DirectoryServices.Protocols.SearchScope.Subtree); // set a window of "the last 4 months" - if a computer hasn't logged in to the domain in 4 months it's probably gone. DateTime validLltsWindow = DateTime.Now.AddMonths(-4); foreach (SearchResultEntry resEnt in searchResultEntries) { int uacFlags; bool success = int.TryParse(resEnt.GetProperty("userAccountControl"), out uacFlags); UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags; if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled)) { continue; } try { // get the last logon timestamp value as a datetime string lltsString = resEnt.GetProperty("lastlogontimestamp"); long lltsLong; long.TryParse(lltsString, out lltsLong); DateTime lltsDateTime = DateTime.FromFileTime(lltsLong); // compare it to our window, and if lltsDateTime is older, skip the computer acct. if (lltsDateTime <= validLltsWindow) { continue; } } catch (Exception e) { Mq.Error("Error calculating lastLogonTimeStamp for computer account " + resEnt.DistinguishedName); } if (!String.IsNullOrEmpty(resEnt.GetProperty("dNSHostName"))) { string computerName = resEnt.GetProperty("dNSHostName"); domainComputers.Add(computerName); } } } } catch (Exception e) { Mq.Trace(e.ToString()); } this._domainComputers = domainComputers; }