/// <summary> /// Creates a local group on the host. /// </summary> /// <param name="name"></param> /// <param name="description"></param> public NTLocalGroup CreateLocalGroup(string name, string description) { var error = 0; var newLocalGroup = new WinAPI.NETAPI32.LOCALGROUP_INFO_1(); newLocalGroup.lgrpi1_name = name; newLocalGroup.lgrpi1_comment = description; var result = WinAPI.NETAPI32.NetLocalGroupAdd(this.NTCompatibleHostName, 1, ref newLocalGroup, ref error); if (result != 0) { throw new NetApiException( result, "Unable to create local group '{0}' on host '{1}'", name, Host ); } NTLocalGroup localGroup = new NTLocalGroup(); localGroup.Host = Host; localGroup.Name = name; localGroup.Description = description; localGroup.Refresh(); return(localGroup); }
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> /// Gets all the security groups this object has membership to. /// </summary> /// <returns></returns> public NTLocalGroup[] GetMembership() { var bufPtr = IntPtr.Zero; var members = new List <NTLocalGroup>(); try { int entriesRead, totalEntries; var result = WinAPI.NETAPI32.NetUserGetLocalGroups( this.Host, this.Name, 0, 0, out bufPtr, 8192, out entriesRead, out totalEntries ); if (result != 0) { throw new NetApiException( result, "Unable to get user '{0}' list of membership on host '{1}'", Name, Host ); } var structSize = Marshal.SizeOf(typeof(WinAPI.NETAPI32.LOCALGROUP_USERS_INFO_0)); var startAddr = bufPtr.ToInt64(); var endAddr = startAddr + (int)totalEntries * structSize; for (var i = startAddr; i < endAddr; i += structSize) { var groupInfo = (WinAPI.NETAPI32.LOCALGROUP_USERS_INFO_0)Marshal.PtrToStructure( new IntPtr(i), typeof(WinAPI.NETAPI32.LOCALGROUP_USERS_INFO_0) ); #region Local object NTLocalGroup localGroup = new NTLocalGroup(); localGroup.Host = Host; localGroup.Name = groupInfo.groupname; localGroup.Refresh(); members.Add(localGroup); #endregion } } finally { if (bufPtr != IntPtr.Zero) { WinAPI.NETAPI32.NetApiBufferFree(bufPtr); } } return(members.ToArray()); }
/// <summary> /// Returns the local users on the host. /// </summary> /// <returns></returns> public NTLocalGroup[] GetLocalGroups() { var bufPtr = IntPtr.Zero; var localGroups = new List <NTLocalGroup>(); try { uint entriesRead; uint totalEntries; int resumeHandle; var result = WinAPI.NETAPI32.NetLocalGroupEnum( this.NTCompatibleHostName, (uint)0, out bufPtr, (int)-1, out entriesRead, out totalEntries, out resumeHandle ); if (result != 0) { throw new NetApiException( result, "Failed to enumerate local groups on host '{0}'", Host ); } var iter = bufPtr; var structSize = Marshal.SizeOf(typeof(WinAPI.NETAPI32.LOCALGROUP_INFO_0)); var startAddr = bufPtr.ToInt64(); var endAddr = startAddr + (int)entriesRead * structSize; for (var offset = startAddr; offset < endAddr; offset += structSize) { var groupInfo = (WinAPI.NETAPI32.LOCALGROUP_INFO_0)Marshal.PtrToStructure( new IntPtr(offset), typeof(WinAPI.NETAPI32.LOCALGROUP_INFO_0) ); var group = new NTLocalGroup(); group.Host = Host; group.Name = groupInfo.name; group.Refresh(); localGroups.Add(group); } } finally { if (bufPtr != IntPtr.Zero) { WinAPI.NETAPI32.NetApiBufferFree(bufPtr); } } return(localGroups.ToArray()); }
public bool TryGetLocalGroup(string name, out NTLocalGroup group) { group = new NTLocalGroup(); if (NTLocalGroup.TryLoadLocalGroup(NTCompatibleHostName, name, group) == 0) { return(true); } else { group = null; return(false); } }
public void AddMembership(NTLocalGroup localGroup) { if (localGroup.Host.ToUpper() != Host.ToUpper()) { throw new WindowsException( "Could not add group membership '{0}\\{1}' to user '{1}\\{2}' as the two objects differed by owner host", localGroup.Host, localGroup.Name, Host, Name ); } AddMembership(localGroup.Name); }
public void CopyRemoteGroupMembership(NTLocalGroup sourceRemoteGroup, NTLocalGroup destinationLocalGroup, NTObject[] destinationLocalGroupMembers) { ActionObserver.NotifyAction("Copy", "Remote Group Membership", sourceRemoteGroup.FullName, destinationLocalGroup.FullName); TextBank existingMembers = new TextBank( from obj in destinationLocalGroupMembers where obj is NTObject select(object) obj ); #region debug region NTRemoteObject[] tmpObjects = sourceRemoteGroup.GetRemoteMembers(); if (tmpObjects == null) { tmpObjects = new NTRemoteObject[0]; } ActionObserver.NotifyInformation("Detected a total of {0} members for remote local group {1}", tmpObjects.Length, sourceRemoteGroup.FullName); foreach (NTRemoteObject remoteObject in tmpObjects) { ActionObserver.NotifyInformation("Member '{0}' its type is {1}", remoteObject.FullName, remoteObject.GetType().FullName); } #endregion NTRemoteObject[] remoteObjects = sourceRemoteGroup.GetRemoteMembers(); if (remoteObjects == null) { remoteObjects = new NTRemoteObject[0]; } ActionObserver.NotifyInformation("Detected a total of {0} AD members for remote local group {1}", remoteObjects.Length, sourceRemoteGroup.FullName); foreach (NTRemoteObject remoteObject in remoteObjects) { ActionObserver.NotifyInformation("AD Member '{0}' its is {1}", remoteObject.FullName, remoteObject.GetType().FullName); } foreach (NTRemoteObject remoteObject in remoteObjects) { string remoteObjectName = remoteObject.Domain + "\\" + remoteObject.Name; if (!existingMembers.ContainsText(remoteObjectName)) { destinationLocalGroup.AddMember(remoteObjectName); } } }
public NTLocalGroup CopyRemoteGroupToLocalMachine(NTLocalGroup remoteGroup) { ActionObserver.NotifyAction("Querying", "Group", remoteGroup.Name, string.Empty); NTLocalGroup localGroup = null; if (!NTHost.CurrentMachine.TryGetLocalGroup(remoteGroup.Name, out localGroup)) { ActionObserver.NotifyAction("Creating", "Group", NTHost.CurrentMachine.Name + '\\' + remoteGroup.Name, string.Empty); localGroup = NTHost.CurrentMachine.CreateLocalGroup( remoteGroup.Name, remoteGroup.Description ); } else { ActionObserver.NotifyAction("Copying", "Group", localGroup.FullName, remoteGroup.FullName); localGroup.Description = remoteGroup.Description; localGroup.Update(); } Debug.Assert(localGroup != null); NTObject[] localMembers = localGroup.GetMembers(); if (_applyMembershipDeletions) { foreach (NTObject obj in localMembers) { ActionObserver.NotifyAction("Deleting", "Group Membership", localGroup.FullName, obj.FullName); localGroup.DeleteMember(obj); } } if (_copyLocalMembership) { CopyLocalGroupMembership(remoteGroup, localGroup, localMembers); } if (_copyDomainMembership) { CopyRemoteGroupMembership(remoteGroup, localGroup, localMembers); } return(localGroup); }
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 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()); }
internal static WinAPI.NETAPI32.NET_API_STATUS TryLoadLocalGroup(string host, string name, NTLocalGroup group) { WinAPI.NETAPI32.NET_API_STATUS result; var bufPtr = IntPtr.Zero; try { result = WinAPI.NETAPI32.NetLocalGroupGetInfo(host, name, 1, out bufPtr); if (result != 0) { return(result); } var groupInfo = (WinAPI.NETAPI32.LOCALGROUP_INFO_1)Marshal.PtrToStructure( bufPtr, typeof(WinAPI.NETAPI32.LOCALGROUP_INFO_1) ); group.Host = host; group.Name = groupInfo.lgrpi1_name; group.Description = groupInfo.lgrpi1_comment; #region Get the group SID var resolver = new SidNameResolver(group.NTCompatibleHostName); WinAPI.ADVAPI32.SidNameUse nameUse; SecurityIdentifier sid; string resolvedDomain; string resolveError; if (resolver.TryReverseResolve(group.Name, out sid, out resolvedDomain, out nameUse, out resolveError)) { if (nameUse != WinAPI.ADVAPI32.SidNameUse.Group && nameUse != WinAPI.ADVAPI32.SidNameUse.Alias) { throw new WindowsException( "Group '{0}' on host '{1}' had a non-group and/or non-alias SID name use.", group.Name, group.Host ); } group.SID = sid; group.SidNameUsage = nameUse; } else { throw new WindowsException( "Unable to resolve SID for group '{0}' on host '{1}'. {2}", group.Name, group.Host, resolveError ); } #endregion } finally { if (bufPtr != IntPtr.Zero) { WinAPI.NETAPI32.NetApiBufferFree(bufPtr); } } return(result); }