Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / C#

WMI Namespace Security

Rate me:
Please Sign up or sign in to vote.
4.70/5 (13 votes)
4 Dec 2006CPOL15 min read 132.4K   3.5K   35  
Describes WMI namespace security, and introduces code to review and modify WMI Namespace security.
using System;

namespace WmiSecurity
{
	/// <summary>
	/// Main program
	/// </summary>
	/// [STAThread]
	class WmiSecurity
	{
		public const int npos = -1;
		
		public static string sTrustee="";
		public static string sMask="";

		// command line argument constants
		public const uint ARG_COMPUTERNAME =  1;
		public const uint ARG_ACETYPE =  2;
		public const uint ARG_NAMESPACE =  4;
		public const uint ARG_TRUSTEE =  8;
		public const uint ARG_RECURSE =  16;
		public const uint CL_MODIFY = 15;
		public const uint CL_MODIFYRECURSE = 31;
		public const uint CL_VIEW = 5;
		public const uint CL_VIEWRECURSE = 21;

		[STAThread]
		static void Main(string[] args)
		{
			bool bAccessAllowed=true;
			bool bRecurse = false;
			string sNameSpace="";
			string sComputer="";
			uint uiMask;
			uint uiCommandLine=0;
			
			//Below, we parse the command line and pull out parameters...
			try
			{
				foreach(string arg in args)
				{
					// Computer Name
					if(arg.Substring(0,2).ToUpper()=="/C")
					{
						sComputer=arg.Substring(3);
						uiCommandLine+=ARG_COMPUTERNAME;
					}
						// Computer Name
					else if(arg.Substring(0,2).ToUpper()=="/A")
					{
						bAccessAllowed=true;
						uiCommandLine+=ARG_ACETYPE;
					}
					else if(arg.Substring(0,2).ToUpper()=="/D")
					{
						bAccessAllowed=false;
						uiCommandLine+=ARG_ACETYPE;
					}
						// Namespace
					else if(arg.Substring(0,2).ToUpper()=="/N")
					{
						sNameSpace=arg.Substring(3);
						uiCommandLine+=ARG_NAMESPACE;
					}
						//trustees
					else if(arg.Substring(0,2).ToUpper()=="/M")
					{
						if(ExtractTrusteeAndRights(arg.Substring(3, arg.Length-3))==false)
						{
							Help();
							return;
						}
						uiCommandLine+=ARG_TRUSTEE;
					}
					else if(arg.Substring(0,2).ToUpper()=="/R")
					{
						bRecurse=true;
						uiCommandLine+=ARG_RECURSE;
					}
					else
					{
						Help();
						return;
					}
				}
			}
			catch(Exception clex)
			{
				Console.WriteLine("Command line format error: " + clex.Message);
				Help();
				return;
			}
				
			// Check parameters
			if(uiCommandLine!=CL_MODIFY && uiCommandLine!=CL_MODIFYRECURSE &&
				uiCommandLine!=CL_VIEW && uiCommandLine!=CL_VIEWRECURSE)
			{
				Help();
				return;
			}
			
			switch(uiCommandLine)
			{
				case CL_VIEW:
				case CL_VIEWRECURSE:
					try
					{
						// Now connect and read
						ViewNameSpaceSecurity viewns = new ViewNameSpaceSecurity(sNameSpace, bRecurse);
						viewns.ViewSecurity(sComputer);
					}
					catch(System.Exception vex)
					{
						Console.WriteLine("Error: " + vex.Message);
					}
				break;
				case CL_MODIFY:
				case CL_MODIFYRECURSE:
					try
					{
						uiMask=CreateAccessMask(sMask);
						if(uiMask !=0 )
						{
							ChangeNameSpaceSecurity changesec = new ChangeNameSpaceSecurity(sNameSpace, bRecurse);
							changesec.setAceFlags(bAccessAllowed, uiMask);
							// Look for a '\' seperator, meaning this is in domain\account format.
							// If this is not the case, then assume this is a 2 char well known sid constant
							if(sTrustee.IndexOf("\\")==npos)
								changesec.Modify(sComputer, sTrustee);
							else
							{
								changesec.Modify(sComputer, changesec.getSidStringFromName(sTrustee));
							}
						
							Console.WriteLine("Operation returned successfully");
						}
						else
						{
							Console.WriteLine("Invalid mask formatted, internal error");
							return;
						}
					}
					catch(Exception ex)
					{
						Console.WriteLine("Error: " + ex.Message);
					}
				break;
			}
			
			return;
		}
		/// <summary>
		/// Help() Display useage information for application
		/// </summary>
		public static void Help()
		{
			Console.WriteLine("WmiSecurity.exe");
			Console.WriteLine("--To modify WMI Namespace security:--");
			Console.WriteLine("Useage: WmiSecurity /C=yyy /A or /D /N=xxx /M=Trustee:AccessMask [/R]");
			Console.WriteLine("==================================================");
			Console.WriteLine("Where /C = Computer (without UNC specification) to modify");
			Console.WriteLine("Where /A = Access Allowed and /D = Access Denied Ace type");
			Console.WriteLine("Where /N = Namespace to target");
			Console.WriteLine("Where /R = Permissions all subsequent WMI namespaces as well as present one");
			Console.WriteLine("Where Access Mask can be one of:");
			Console.WriteLine("READ - Allows default read of WMI namespace");
			Console.WriteLine("REMOTEACCESS - Allows READ and remote access to WMI namespace");
			Console.WriteLine("PROVIDERWRITE - Allows writing classes and instances to providers,");
			Console.WriteLine("            as well as READ and REMOTEACCESS");
			Console.WriteLine("PARTIALWRITE - Allows writes of data to instances, as well");
			Console.WriteLine("            as REMOTEACCESS to WMI");
			Console.WriteLine("FULLWRITE - Allows writing classes and instances, as well");
			Console.WriteLine("            as REMOTEACCESS to WMI");
			Console.WriteLine("FULL - FULLWRITE, PARTIALWRITE, plus Security modifications to WMI");
			Console.WriteLine("");
			Console.WriteLine("Example: WmiSecurity /C=S001001 /A /N=Root/RSOP /M=DA:FULL /R");
			Console.WriteLine("Gives Full Access to the Domain Admins group for the Root/RSOP WMI");
			Console.WriteLine("namespace and all subsequent child containers thereof in the S001001 computer");
			Console.WriteLine("This example used Microsoft SID string constant (DA) for Domain Admins group");
			Console.WriteLine("");
			Console.WriteLine("Example: WmiSecurity /C=S001004 /A /N=Root/CCM/Events /M=\"MyDomain\\Domain Guests:FULL\"");
			Console.WriteLine("Gives Full Access to the MyDomain\\Domain Guests group for the Root/CCM/Events WMI");
			Console.WriteLine("namespace on the S001004 computer, non recursive");
			Console.WriteLine("This example used Domain\\Account format");
			Console.WriteLine("");
			Console.WriteLine("Note: You must supply domain\\account of the trustee or the well known SID");
			Console.WriteLine("string constants. (Microsoft supplies a list of these)");
			Console.WriteLine("Note: You can currently apply permission changes to WMI namspaces for");
			Console.WriteLine("one trustee at a time.");
			Console.WriteLine("");
			Console.WriteLine("--To view WMI Namespace security:--");
			Console.WriteLine("Useage: WmiSecurity /C=yyy /N=xxx [/R]");
			Console.WriteLine("==================================================");
			Console.WriteLine("Where /C = Computer (without UNC specification) to modify");
			Console.WriteLine("Where /N = Namespace to target");
			Console.WriteLine("Where /R = view all subsequent WMI namespaces as well as present one");
			Console.WriteLine("");
			return;
		}

		// Look for the ':' seperator which defines when the command line trustee
		// ends and the permission requested begins...
		public static bool ExtractTrusteeAndRights(string sRawFormat)
		{
			int iLoc;
			if((iLoc=sRawFormat.IndexOf(":"))==npos)
				return false;
			try
			{
				sMask = sRawFormat.Substring(iLoc+1, sRawFormat.Length-(iLoc+1));
				sTrustee = sRawFormat.Substring(0, iLoc);
			}
			catch(Exception exFormat)
			{
				Console.WriteLine("Trustee:Mask Format error: " + exFormat.Message);
				return false;
			}
			return true;
		}

		public static uint CreateAccessMask(string sAccess)
		{
			if(sAccess.ToUpper()=="READ")
			{
				return AceStringManager.WBEM_ENABLE;
			}
			else if (sAccess.ToUpper()=="REMOTEACCESS")
			{
				return AceStringManager.WBEM_ENABLE|AceStringManager.WBEM_REMOTE_ACCESS;
			}
			else if (sAccess.ToUpper()=="PROVIDERWRITE")
			{
				return AceStringManager.WBEM_ENABLE|AceStringManager.WBEM_WRITE_PROVIDER;
			}
			else if (sAccess.ToUpper()=="PARTIALWRITE")
			{
				return AceStringManager.WBEM_ENABLE|AceStringManager.WBEM_PARTIAL_WRITE_REP;
			}
			else if (sAccess.ToUpper()=="FULLWRITE")
			{
				return AceStringManager.WBEM_ENABLE|AceStringManager.WBEM_FULL_WRITE_REP;
			}
			else if (sAccess.ToUpper()=="FULL")
			{
				return AceStringManager.WBEM_REMOTE_ACCESS|AceStringManager.WBEM_METHOD_EXECUTE|AceStringManager.WBEM_FULL_WRITE_REP|
					AceStringManager.WBEM_ENABLE|AceStringManager.READ_CONTROL|AceStringManager.WRITE_DAC;
			}
			else
				return 0;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Software developer for the past 10 years in the Windows environment. Married, with two teenagers, and no money!

Comments and Discussions