You can create a machine account login for SQL Server with the following command:
CREATE USER [MACHINENAME] FOR LOGIN [DOMAIN\MACHINENAME$] WITH DEFAULT_SCHEMA=[dbo]
|
||||||||||||||||||||||||||||||||||||||
|
You can create a machine account login for SQL Server with the following command: CREATE USER [MACHINENAME] FOR LOGIN [DOMAIN\MACHINENAME$] WITH DEFAULT_SCHEMA=[dbo] When generating setup code or isolation code (for Side by Side assemblies and Registration-free COM), VB6 ActiveX Components can be a little troublesome. ActiveX exes in particular can be difficult, with the WiX heat tool and various SxS tools not being able to harvest COM registration information from them properly. A good way of avoiding these problems is to generate a type library (.tlb) from the VB6 component, and then pointing the code generation tools at the type library. In VB6, you can generate a Type Library (.tlb) file for an ActiveX component:
You should now see a .tlb and .vbr file next to your binary. The .vbr file is a text file containing registry information, which will be very helpful if the type library is still missing information you want to use for your isolation or installation authoring. ReferenceHow To Make a Typelib (.TLB) File for ActiveX Components @ MSDN This post covers the cause of a bug I ran into at work. Our application would check for available updates when it started, and if they were found, it would launch the installer directly and exit the application immediately, so that the installer could run without encountering file locks. The installer was complaining our executable was still locked, meaning it had to schedule the overwrite of the old file with the new one after a reboot. After quite a bit of troubleshooting, it looked like while the application was launching msiexec and closing down successfully, msiexec was still grabbing the same lock handle to the exe for no good reason. So what was happening? System.Diagnostics.ProcessWhen you create a new process from a .NET application, you would use the classes in the System.Diagnostics namespace. Specifically, Process and ProcessStartInfo. As we were in this case. These wrap the Windows API function CreateProcess and its alternatives and supporting types. If we look at the CreateProcess definition, there’s a boolean argument in there called bInheritHandles:
What does the Windows API documentation say about this?
Inheritable handles?
Well if we look at the internals of .NET, and look at how the Process class is calling CreateProcess, we find that it’s passing bInheritHandles as TRUE. So this means if we start a process using the System.Diagnostics classes, the child process will inherit our inheritable handles. What was happening is the locked file handle to wsClient.exe was being inherited from the parent process to the Windows Installer, so the executable was remaining locked even when the parent process exited. SolutionOne solution is to avoid System.Diagnostics in this particular instance, and use CreateProcess manually when we launch our child process, to ensure it doesn’t inherit handles. I would recommend you use the System.Diagnostics classes in any other case. Codeusing System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using Microsoft.Win32.SafeHandles; namespace CreateProcessTest { [StructLayout(LayoutKind.Sequential)] internal class ProcessInformation { public IntPtr hProcess = IntPtr.Zero; public IntPtr hThread = IntPtr.Zero; public int dwProcessId; public int dwThreadId; } [StructLayout(LayoutKind.Sequential)] internal class StartupInfo { public int cb; public IntPtr lpReserved = IntPtr.Zero; public IntPtr lpDesktop = IntPtr.Zero; public IntPtr lpTitle = IntPtr.Zero; public int dwX; public int dwY; public int dwXSize; public int dwYSize; public int dwXCountChars; public int dwYCountChars; public int dwFillAttribute; public int dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2 = IntPtr.Zero; public SafeFileHandle hStdInput = new SafeFileHandle(IntPtr.Zero, false); public SafeFileHandle hStdOutput = new SafeFileHandle(IntPtr.Zero, false); public SafeFileHandle hStdError = new SafeFileHandle(IntPtr.Zero, false); public StartupInfo() { dwY = 0; cb = Marshal.SizeOf(this); } public void Dispose() { // close the handles created for child process if (hStdInput != null && !hStdInput.IsInvalid) { hStdInput.Close(); hStdInput = null; } if (hStdOutput != null && !hStdOutput.IsInvalid) { hStdOutput.Close(); hStdOutput = null; } if (hStdError == null || hStdError.IsInvalid) return; hStdError.Close(); hStdError = null; } } [StructLayout(LayoutKind.Sequential)] internal class SecurityAttributes { public int nLength = 12; public SafeLocalMemHandle lpSecurityDescriptor = new SafeLocalMemHandle(IntPtr.Zero, false); public bool bInheritHandle; } [SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] internal sealed class SafeLocalMemHandle : SafeHandleZeroOrMinusOneIsInvalid { internal SafeLocalMemHandle() : base(true) { } [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] internal SafeLocalMemHandle(IntPtr existingHandle, bool ownsHandle) : base(ownsHandle) { SetHandle(existingHandle); } [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string stringSecurityDescriptor, int stringSDRevision, out SafeLocalMemHandle pSecurityDescriptor, IntPtr securityDescriptorSize); [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll")] private static extern IntPtr LocalFree(IntPtr hMem); protected override bool ReleaseHandle() { return (LocalFree(handle) == IntPtr.Zero); } } public static class Test { const int normalPriorityClass = 0x0020; [DllImport("Kernel32", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)] internal static extern bool CreateProcess( [MarshalAs(UnmanagedType.LPTStr)]string applicationName, StringBuilder commandLine, SecurityAttributes processAttributes, SecurityAttributes threadAttributes, bool inheritHandles, int creationFlags, IntPtr environment, [MarshalAs(UnmanagedType.LPTStr)]string currentDirectory, StartupInfo startupInfo, ProcessInformation processInformation ); public static void Main(string[] args) { // We can use the string builder to build up our full command line, including arguments var sb = new StringBuilder("notepad.exe"); var processInformation = new ProcessInformation(); var startupInfo = new StartupInfo(); var processSecurity = new SecurityAttributes(); var threadSecurity = new SecurityAttributes(); processSecurity.nLength = Marshal.SizeOf(processSecurity); threadSecurity.nLength = Marshal.SizeOf(threadSecurity); if (CreateProcess(null, sb, processSecurity, threadSecurity, false, normalPriorityClass, IntPtr.Zero, null, startupInfo, processInformation)) { // Process was created successfully return; } // We couldn't create the process, so raise an exception with the details. throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } } } UtilitiesI used the invaluable SysInternals tools Process Monitor, Process Explorer and Handle to diagnose what was going on. ReferencesReflector historyThe de facto .NET decompiler has been Reflector for what seems like forever. Reflector was originally developed by Lutz Roeder, and made freely available to the community. It was acquired by Red Gate Software in August 2008, who promised to maintain it as a free product. They reneged on this promise in February 2011, stating that Reflector would become a commercial product. This created a community backlash, culminating in creation and/or promotion of several free rival products through open source or offered by other vendors. Red Gate backpedalled in April 2011 by saying that the final 6.8 version of Reflector would continue to be free, while future releases of Reflector (moving forward with version 7.x) would be paid for. List of .NET Decompilers
There may be a scenario where you want to determine from code if the current user is an Administrator. One example of this which I have had to deal with is checking for software updates. Say your application contacts a service to see if there is a newer version of the application available; if so, you can download and run the installer. Imagine that the installer requires admin privileges; you don’t want to run the installer if the current user does not have administrative privileges. So how can we check if the user is an admin or not? In VB6, C++ etcThere is a Windows API function you can use very easily to see if the current user is an admin: IsUserAnAdmin.
Visual Basic 6 Declaration
While you can still use this, it is actually deprecated, and the documentation recommends you call the CheckTokenMembership function instead (which IsUserAnAdmin is a wrapper for). .NETC#.NETusing System; var identity = WindowsIdentity.GetCurrent(); if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity"); var principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); User Account Control (UAC)A problem arises when you use any of the above code on a machine that has UAC enabled, and the process is not elevated. While the user may be an administrator, when the process is not elevated yet, the user has a split token – which doesn’t have the administrator privileges. A way around this is to use the GetTokenInformation API call to inspect the token to see if it’s a split token. In most cases this will mean that UAC is on and the current user is an administrator. This is not 100% reliable (see References) but it’s probably the best we can do for now. C#.NETThis code is slightly easier in .NET, as there’s already a fair amount of code we don’t have to write to get the current process’s token. First, we’ll need some code to support the GetTokenInformation API call: [DllImport("advapi32.dll", SetLastError = true)] static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength); /// <summary> /// Passed to <see cref="GetTokenInformation"/> to specify what /// information about the token to return. /// </summary> enum TokenInformationClass { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin, TokenElevationType, TokenLinkedToken, TokenElevation, TokenHasRestrictions, TokenAccessInformation, TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenIntegrityLevel, TokenUiAccess, TokenMandatoryPolicy, TokenLogonSid, MaxTokenInfoClass } /// <summary> /// The elevation type for a user token. /// </summary> enum TokenElevationType { TokenElevationTypeDefault = 1, TokenElevationTypeFull, TokenElevationTypeLimited }
Then, the actual code to detect if the user is an Administrator (returning true if they are, otherwise false). var identity = WindowsIdentity.GetCurrent(); if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity"); var principal = new WindowsPrincipal(identity); // Check if this user has the Administrator role. If they do, return immediately. // If UAC is on, and the process is not elevated, then this will actually return false. if (principal.IsInRole(WindowsBuiltInRole.Administrator)) return true; // If we're not running in Vista onwards, we don't have to worry about checking for UAC. if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6) { // Operating system does not support UAC; skipping elevation check. return false; } int tokenInfLength = Marshal.SizeOf(typeof(int)); IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength); try { var token = identity.Token; var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength); if (!result) { var exception = Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error() ); throw new InvalidOperationException("Couldn't get token information", exception); } var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation); switch (elevationType) { case TokenElevationType.TokenElevationTypeDefault: // TokenElevationTypeDefault - User is not using a split token, so they cannot elevate. return false; case TokenElevationType.TokenElevationTypeFull: // TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator. return true; case TokenElevationType.TokenElevationTypeLimited: // TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator. return true; default: // Unknown token elevation type. return false; } } finally { if (tokenInformation != IntPtr.Zero) Marshal.FreeHGlobal(tokenInformation); } Visual Basic 6 (VB6)For Visual Basic 6, there’s some additional code, as we need to get the token for the current process, and use more calls to also get the operating system version. Type OSVERSIONINFO dwOSVersionInfoSize As Long dwMajorVersion As Long dwMinorVersion As Long dwBuildNumber As Long dwPlatformId As Long szCSDVersion As String * 128 End Type
‘ dwPlatformId values Public Const VER_PLATFORM_WIN32s = 0 Public Const VER_PLATFORM_WIN32_WINDOWS = 1 Public Const VER_PLATFORM_WIN32_NT = 2
Public Declare Function GetVersionEx Lib “kernel32″ Alias “GetVersionExA” (ByRef lpVersionInformation As OSVERSIONINFO) As Long
‘ These functions are for getting the process token information, which IsUserAnAdministrator uses to ‘ handle detecting an administrator that’s running in a non-elevated process under UAC. Private Const TOKEN_READ As Long = &H20008 Private Const TOKEN_ELEVATION_TYPE As Long = 18
Private Declare Function IsUserAnAdmin Lib “Shell32″ Alias “#680″ () As Integer Private Declare Function CloseHandle Lib “kernel32″ (ByVal hObject As Long) As Long Private Declare Function OpenProcessToken Lib “advapi32.dll” (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long Private Declare Function GetTokenInformation Lib “advapi32.dll” (ByVal TokenHandle As Long, ByVal TokenInformationClass As Long, TokenInformation As Any,_ ByVal TokenInformationLength As Long, ReturnLength As Long) As Long Public Function IsUserAnAdministrator() As Boolean
On Error GoTo IsUserAnAdministratorError
IsUserAnAdministrator = False
If IsUserAnAdmin() Then IsUserAnAdministrator = True Exit Function End If
‘ If we’re on Vista onwards, check for UAC elevation token ‘ as we may be an admin but we’re not elevated yet, so the ‘ IsUserAnAdmin() function will return false Dim osVersion As OSVERSIONINFO osVersion.dwOSVersionInfoSize = Len(osVersion)
If GetVersionEx(osVersion) = 0 Then Exit Function End If
If osVersion.dwPlatformId <> VER_PLATFORM_WIN32_NT Or osVersion.dwMajorVersion < 6 Then ‘ If the user is not on Vista or greater, then there’s no UAC, so don’t bother checking. Exit Function End If
Dim result As Long Dim hProcessID As Long Dim hToken As Long Dim lReturnLength As Long Dim tokenElevationType As Long
‘ We need to get the token for the current process hProcessID = GetCurrentProcess() If hProcessID <> 0 Then If OpenProcessToken(hProcessID, TOKEN_READ, hToken) = 1 Then
result = GetTokenInformation(hToken, TOKEN_ELEVATION_TYPE, tokenElevationType, 4, lReturnLength)
If result = 0 Then ‘ Couldn’t get token information Exit Function End If
If tokenElevationType <> 1 Then IsUserAnAdministrator = True End If
CloseHandle hToken End If CloseHandle hProcessID End If
Exit Function
IsUserAnAdministratorError: ‘ Handle errors End Function ReferencesSome cool looking movies on the distant horizon. Sylvester Stallone, Arnold Schwarzenegger, Jason Statham, Mickey Rourke, Dolph Lundgren, Jet Li, Randy Couture, Steve Austin, Eric Roberts, Terry Crews, Danny Trejo… The Expendables cast is wicked! This could be an awesome unabashed 80s-style action movie if the script is good enough and it doesn’t take itself too seriously. Then we have Michel Gondry directing Seth Rogen and Stephen Chow in The Green Hornet. Nice. And much much further ahead, Lars von Trier is still working on this mysterious and ambitious film called Dimension. It’s starring Udo Kier, who said:
Introducing Keyboard Cat Play them off, Keyboard Cat This one’s pretty brutal, I’m going to hell: Otherwise, spoilers! |
||||||||||||||||||||||||||||||||||||||
|
Copyright © 2013 David's Blog - All Rights Reserved |
||||||||||||||||||||||||||||||||||||||