/// <summary> /// Creates a local user on the host. /// </summary> /// <param name="name"></param> public NTLocalUser CreateLocalUser(string name, string password) { var newUser = new WinAPI.NETAPI32.USER_INFO_1 { usri1_name = name, usri1_password = password, usri1_priv = (int)UserPrivilege.User, usri1_home_dir = null, comment = null, usri1_script_path = null }; // Create an new instance of the USER_INFO_1 struct var result = WinAPI.NETAPI32.NetUserAdd(this.NTCompatibleHostName, 1, ref newUser, 0); if (result != 0) { throw new NetApiException( result, "Unable to create local user '{0}' on host '{1}'", name, Host ); } var user = new NTLocalUser { Host = Host, Name = name }; user.Refresh(); return(user); }
public void CopyUserMembership(NTLocalUser sourceRemoteUser, NTLocalUser destLocalUser) { ActionObserver.NotifyAction("Copying", "User Membership", sourceRemoteUser.FullName, destLocalUser.FullName); TextBank existingMembers = new TextBank(destLocalUser.GetMembership()); GroupCopier groupCopier = new GroupCopier(false, false, true, DefaultUserPassword, false, ActionObserver); foreach (NTLocalGroup remoteGroup in sourceRemoteUser.GetMembership()) { if (!existingMembers.ContainsText(remoteGroup.Name)) { NTLocalGroup localGroup = null; // find a user by the same name of local machine if (!NTHost.CurrentMachine.TryGetLocalGroup(remoteGroup.Name, out localGroup)) { if (_importLocalGroups) { groupCopier.CopyRemoteGroupToLocalMachine(remoteGroup); } } if (localGroup != null) { if (!existingMembers.ContainsText(localGroup.Name)) { destLocalUser.AddMembership(localGroup); } } } } }
/// <summary> /// Returns the local users on the host. /// </summary> /// <returns></returns> public NTLocalUser[] GetLocalUsers() { var bufPtr = IntPtr.Zero; var localUsers = new List <NTLocalUser>(); try { int entriesRead; int totalEntries; int resumeHandle; var result = WinAPI.NETAPI32.NetUserEnum( this.NTCompatibleHostName, 3, 2, out bufPtr, -1, out entriesRead, out totalEntries, out resumeHandle ); if (result != 0) { throw new NetApiException( result, "Failed to enumerate local users on host '{0}'", Host ); } var structSize = Marshal.SizeOf(typeof(WinAPI.NETAPI32.USER_INFO_3)); var startAddr = bufPtr.ToInt64(); var endAddr = startAddr + entriesRead * structSize; for (var offset = startAddr; offset < endAddr; offset += structSize) { var userInfo = (WinAPI.NETAPI32.USER_INFO_3)Marshal.PtrToStructure( new IntPtr(offset), typeof(WinAPI.NETAPI32.USER_INFO_3) ); var user = new NTLocalUser { Host = Host, Name = !string.IsNullOrEmpty(userInfo.usri3_name) ? userInfo.usri3_name : string.Empty }; user.Refresh(); localUsers.Add(user); } } catch (Exception error) { #warning Need to fix this //throw new ApplicationException( } finally { if (bufPtr != IntPtr.Zero) { WinAPI.NETAPI32.NetApiBufferFree(bufPtr); } } return(localUsers.ToArray()); }
public bool TryGetLocalUser(string name, out NTLocalUser user) { user = new NTLocalUser(); if (NTLocalUser.TryLoadLocalUser(NTCompatibleHostName, name, user) == 0) { return(true); } user = null; return(false); }
public void AddLocalMember(NTLocalUser localUser) { if (localUser.Host.ToUpper() != Host.ToUpper()) { throw new WindowsException( "Could not add user '{0}\\{1}' to group '{1}\\{2}' as the two objects differed by owner host", localUser.Host, localUser.Name, Host, Name ); } AddLocalMember(localUser.Name); }
public void CopyUserData(NTLocalUser sourceRemoteUser, NTLocalUser destLocalUser) { ActionObserver.NotifyAction("Copying", "User", sourceRemoteUser.FullName, destLocalUser.FullName); destLocalUser.FullName = sourceRemoteUser.FullName; destLocalUser.AccountExpires = sourceRemoteUser.AccountExpires; destLocalUser.CodePage = sourceRemoteUser.CodePage; destLocalUser.Comment = sourceRemoteUser.Comment; destLocalUser.CountryCode = sourceRemoteUser.CountryCode; destLocalUser.Description = sourceRemoteUser.Description; destLocalUser.Flags = sourceRemoteUser.Flags; destLocalUser.HomeDirectory = sourceRemoteUser.HomeDirectory; destLocalUser.LogonHours = sourceRemoteUser.LogonHours; destLocalUser.LogonServer = sourceRemoteUser.LogonServer; destLocalUser.MaxStorage = sourceRemoteUser.MaxStorage; destLocalUser.ScriptPath = sourceRemoteUser.ScriptPath; destLocalUser.UnitsPerWeek = sourceRemoteUser.UnitsPerWeek; destLocalUser.Workstations = sourceRemoteUser.Workstations; destLocalUser.Update(); }
public void CopyLocalGroupMembership(NTLocalGroup sourceRemoteGroup, NTLocalGroup destinationLocalGroup, NTObject[] destinationLocalGroupMembers) { ActionObserver.NotifyAction("Copy", "Local Group Membership", sourceRemoteGroup.FullName, destinationLocalGroup.FullName); TextBank existingMembers = new TextBank( from obj in destinationLocalGroupMembers where obj is NTLocalObject select(object) obj ); UserCopier userCopier = new UserCopier( false, false, DefaultUserPassword, false, ActionObserver ); foreach (NTLocalUser remoteUser in sourceRemoteGroup.GetLocalMembers()) { NTLocalUser localUser = null; // find a user by the same name of local machine if (!NTHost.CurrentMachine.TryGetLocalUser(remoteUser.Name, out localUser)) { // import the user if required if (_importLocalUsers) { localUser = userCopier.CopyRemoteUserToLocalMachine(remoteUser); } } if (localUser != null) { if (!existingMembers.ContainsText(localUser.Name)) { destinationLocalGroup.AddLocalMember(localUser); } } } }
public NTLocalUser CopyRemoteUserToLocalMachine(NTLocalUser remoteUser) { #region Validation Debug.Assert(remoteUser.Host.ToUpper() != NTHost.CurrentMachine.Name.ToUpper()); if (remoteUser.Host.ToUpper() == NTHost.CurrentMachine.Name.ToUpper()) { throw new WindowsException( "Cannot copy user '{0}\\{1}' onto itself", remoteUser.Host, remoteUser.Name ); } #endregion NTLocalUser localUser; ActionObserver.NotifyAction("Querying", "User", remoteUser.Name, string.Empty); if (!NTHost.CurrentMachine.TryGetLocalUser(remoteUser.Name, out localUser)) { ActionObserver.NotifyAction("Creating", "User", NTHost.CurrentMachine.Name + '\\' + remoteUser.Name, string.Empty); localUser = NTHost.CurrentMachine.CreateLocalUser( remoteUser.Name, DefaultUserPassword ); } CopyUserData(remoteUser, localUser); if (_copyGroupMembership) { CopyUserMembership(remoteUser, localUser); } return(localUser); }
internal static WinAPI.NETAPI32.NET_API_STATUS TryLoadLocalUser(string host, string username, NTLocalUser user) { WinAPI.NETAPI32.NET_API_STATUS result; var bufPtr = IntPtr.Zero; try { result = WinAPI.NETAPI32.NetUserGetInfo( host, username, 2, out bufPtr ); if (result != 0) { return(result); } var userInfo = (WinAPI.NETAPI32.USER_INFO_2)Marshal.PtrToStructure(bufPtr, typeof(WinAPI.NETAPI32.USER_INFO_2)); user.Host = host; user._acct_expires = userInfo.usri2_acct_expires; user._auth_flags = userInfo.usri2_auth_flags; user.BadPasswordCount = userInfo.usri2_bad_pw_count; user.CodePage = userInfo.usri2_code_page; user.Description = userInfo.usri2_comment; user.CountryCode = userInfo.usri2_country_code; user._flags = userInfo.usri2_flags; user._full_name = userInfo.usri2_full_name; user._home_dir = userInfo.usri2_home_dir; user._comment = userInfo.usri2_usr_comment; user._last_logoff = userInfo.usri2_last_logoff; user._last_logon = userInfo.usri2_last_logon; user._logon_server = userInfo.usri2_logon_server; user.MaxStorage = userInfo.usri2_max_storage; user.Name = userInfo.usri2_name; user.NumberOfLogons = userInfo.usri2_num_logons; user._parms = userInfo.usri2_parms; user._password = userInfo.usri2_password; user._password_age = userInfo.usri2_password_age; user._priv = userInfo.usri2_priv; user._script_path = userInfo.usri2_script_path; user.UnitsPerWeek = userInfo.usri2_units_per_week; user.usri2_workstations = userInfo.usri2_workstations; if (userInfo.usri2_logon_hours != IntPtr.Zero) { Marshal.Copy(userInfo.usri2_logon_hours, user.LogonHours, 0, 21); WinAPI.NETAPI32.NetApiBufferFree(userInfo.usri2_logon_hours); } else { user.LogonHours = new byte[0]; } #region Get the group SID var resolver = new SidNameResolver(user.NTCompatibleHostName); WinAPI.ADVAPI32.SidNameUse nameUse; SecurityIdentifier sid; string resolvedDomain; string resolveError; if (resolver.TryReverseResolve(user.Name, out sid, out resolvedDomain, out nameUse, out resolveError)) { if (nameUse != WinAPI.ADVAPI32.SidNameUse.User && nameUse != WinAPI.ADVAPI32.SidNameUse.Alias) { throw new WindowsException( "User '{0}' on host '{1}' had a non-user and non-alias SID name", user.Name, user.Host ); } user.SID = sid; user.SidNameUsage = nameUse; } else { throw new WindowsException( "Unable to resolve SID for user '{0}' on host '{1}. {2}", user.Name, user.Host, resolveError ); } #endregion } finally { WinAPI.NETAPI32.NetApiBufferFree(bufPtr); } return(result); }
public bool TryTranslate( string remoteHost, string remoteName, WinAPI.ADVAPI32.SidNameUse remoteNameUse, out string translatedAccountName ) { ActionObserver.NotifyAction("Translating", remoteNameUse.ToString(), remoteName, string.Empty); bool retval = false; translatedAccountName = string.Empty; string key = string.Format("{0}\\{1}", remoteHost, remoteName); if (_translations.ContainsKey(key)) { translatedAccountName = _translations[key]; retval = true; } else { // attempt to resolve with local user/group of same name if (AccountExistsLocally(remoteName)) { _translations[key] = remoteName; translatedAccountName = _translations[key]; retval = true; ActionObserver.NotifyInformation("Translated remote account '{0}\\{1}' to already existing local account '{2}'", remoteHost, remoteName, translatedAccountName); } else if (_importObject) { #region Import remote object NTHost host = new NTHost(remoteHost); NTLocalObject obj; if (host.TryGetLocalObject(remoteName, out obj)) { if (obj is NTLocalUser) { NTLocalUser remoteUser = (NTLocalUser)obj; UserCopier userCopier = new UserCopier( true, false, _defaultPassword, false, ActionObserver ); NTLocalUser localUser = userCopier.CopyRemoteUserToLocalMachine(remoteUser); translatedAccountName = localUser.Name; ActionObserver.NotifyInformation("Copied and translated remote user '{0}\\{1}' to local group '{2}'", remoteHost, remoteName, translatedAccountName); } else if (obj is NTLocalGroup) { NTLocalGroup remoteGroup = (NTLocalGroup)obj; GroupCopier groupCopier = new GroupCopier( true, false, true, _defaultPassword, false, ActionObserver ); NTLocalGroup localGroup = groupCopier.CopyRemoteGroupToLocalMachine(remoteGroup); translatedAccountName = remoteGroup.Name; ActionObserver.NotifyInformation("Copied and translated remote group '{0}\\{1}' to local group '{2}'", remoteHost, remoteName, translatedAccountName); } } #endregion _translations[key] = translatedAccountName; retval = true; } } if (!retval) { ActionObserver.NotifyWarning("Failed to translate '{0}\\{1}' into a local object.", remoteHost, remoteName); } return(retval); }
/// <summary> /// Gets all the members belonging to this group. /// </summary> /// <returns>List of members.</returns> public NTObject[] GetMembers() { var members = new List <NTObject>(); var memberInfoPtr = IntPtr.Zero; try { var resumeHandle = 0; const uint prefmaxlen1 = 0xffffffff; uint entriesread1, totalentries1; var result = WinAPI.NETAPI32.NetLocalGroupGetMembers(this.NTCompatibleHostName, this.Name, 2, out memberInfoPtr, prefmaxlen1, out entriesread1, out totalentries1, out resumeHandle); if (result != 0) { throw new NetApiException( result, "Unable to get members of group '{0}' on host '{1}'", Name, Host ); } var structSize = Marshal.SizeOf(typeof(WinAPI.NETAPI32.LOCALGROUP_MEMBERS_INFO_2)); var startAddr = memberInfoPtr.ToInt64(); var endAddr = startAddr + (int)totalentries1 * structSize; for (var offset = startAddr; offset < endAddr; offset += structSize) { var memberInfo = (WinAPI.NETAPI32.LOCALGROUP_MEMBERS_INFO_2)Marshal.PtrToStructure( new IntPtr(offset), typeof(WinAPI.NETAPI32.LOCALGROUP_MEMBERS_INFO_2) ); var memberDomainName = Marshal.PtrToStringAuto(memberInfo.lgrmi2_domainandname); var memberDomain = SecurityTool.GetDomainFromDomainUserString(memberDomainName); var memberName = SecurityTool.GetUserFromDomainUserString(memberDomainName); var memberSid = new SecurityIdentifier(memberInfo.lgrmi2_sid); var memberSidUsage = (WinAPI.ADVAPI32.SidNameUse)memberInfo.lgrmi2_sidusage; if (memberSidUsage == WinAPI.ADVAPI32.SidNameUse.DeletedAccount || memberSidUsage == WinAPI.ADVAPI32.SidNameUse.Unknown) { #region It's Dangling object members.Add( new NTDanglingObject( Host, memberSid, memberSidUsage ) ); #endregion } else if (memberDomain.ToUpper() != this.Host.ToUpper()) { #region It's a remote object members.Add( new NTRemoteObject( Host, memberDomain, memberName, memberSid, memberSidUsage ) ); #endregion } else { #region It's a local object switch (memberSidUsage) { case WinAPI.ADVAPI32.SidNameUse.User: var user = new NTLocalUser { Host = Host, Name = memberName, SID = memberSid }; user.Refresh(); members.Add(user); break; case WinAPI.ADVAPI32.SidNameUse.Group: case WinAPI.ADVAPI32.SidNameUse.WellKnownGroup: var group = new NTLocalGroup(); group.Host = Host; group.Name = memberName; group.Refresh(); members.Add(group); break; default: members.Add( new NTDanglingObject( Host, memberSid, memberSidUsage ) ); break; } #endregion } } } finally { if (memberInfoPtr != IntPtr.Zero) { WinAPI.NETAPI32.NetApiBufferFree(memberInfoPtr); } } return(members.ToArray()); }