TraceView and Security

[Previous] [Next]

TraceSrv by itself is useful, but a viewer that shows the trace statements really enhances it. I wrote TraceView in Visual Basic because it was fairly simple to do. When you look at the source code for TraceView, you shouldn't see much that hasn't been done before.

I tried to make TraceView a little more useful than a plain edit control by giving it a toolbar and a status bar as well as adding support for saving and restoring the window position, saving files, searching forward and backward, and allowing the window to stay on top. For internalization ease, I kept all the strings in a resource file instead of hard-coding them. I won't get into the resource string loading, but I will mention that I modified the generated LoadResStrings function (which I renamed LoadFormResStrings) so that it notifies you about which resource items failed to load.

When I first started using TraceView, it worked great. Nevertheless, when I started testing all the different ways to connect TraceView to TraceSrv, I encountered some problems. If TraceView and TraceSrv were on the same machine, TraceView could connect to TraceSrv if it ran as a service or as a local server. TraceView could also connect properly if TraceSrv ran as a local server on another machine using COM+. When I tried to have TraceView connect to TraceSrv running as a COM+ service on another machine, however, it would always fail, giving me the Visual Basic error message "Run-time error -2147023071 (80070721) Automation Error." I looked up the error value in WINERROR.H; the ID is RPC_S_SEC_PKG_ERROR, "A security package specific error occurred."

I had never seen this error ID before. When I searched MSDN for it, all I got back was that it was in WINERROR.H and that it was listed in the system error appendixes. After fiddling with this problem for several days, I found that I could get a Visual Basic_based program to connect to the remote TraceSrv service only if I didn't use the WithEvents keyword in the declaration of the Trace object. If I used the WithEvents keyword, I'd always get the RPC_S_SEC_PKG_ ERROR error. I was perplexed by this bug until a friend pointed out that I didn't have the security for the service set correctly.

When I stepped back and walked through what happened, the bug started to make sense. The WithEvents keyword sets up an IConnectionPoint interface that the server uses to call in to the client—in essence a callback. To call back in to the client, the server must have the correct security permissions. When TraceSrv runs on the same machine as TraceView, TraceSrv—whether started as a local server or as a service—runs under the same user identification as TraceView or is trusted. Running TraceSrv on one machine as a COM+ remote server and TraceView on another machine worked because I was lucky. On both Windows NT Workstation machines without a domain controller, I was logged in as "John" with the same password. According to Knowledge Base article Q158508, "COM Security Frequently Asked Questions," Windows NT Workstation "falls back to a 'matching account names and passwords' mode. If you use the same ASCII names on the two machines running Windows NT Workstation and the accounts have the same passwords, then DCOM and other [Windows] NT security (such as filesystem) should work as though you were really logged on to the two machines with the same account." When I logged on to the remote machine as "Bob," started TraceSrv as a remote server, and tried to connect TraceView on the client machine logged on as "John," I got the RPC_S_SEC_PKG_ERROR error. My test case, running TraceSrv as a remote server on a separate machine, didn't take into account all the permutations for connections.

Getting a remote server started with proper security is fairly easy—just log on as a user who has network permission—but getting a Win32 service working with proper security takes a little more effort. By default, Win32 services have no security credentials, so TraceSrv caused a security error whenever it tried to do anything with the IConnectionPoint interface it was passed. What I needed was a way to have the client tell COM+ the security level it will allow for its own interfaces. You specify the security level for your client's interfaces through the CoInitializeSecurity function call, which should be called immediately after your application calls CoInitialize. In TraceView, which is written in Visual Basic, calling CoInitializeSecurity won't work. If you try calling CoInitializeSecurity as the first statement in your Sub Main, you'll get the error code 0x80010119 (RPC_E_ TOO_LATE), which means "Security must be initialized before any interfaces are marshaled or unmarshaled. It cannot be changed once initialized." As you can see, Visual Basic is happily marshaling away long before your code ever gets called.

You can get around this Visual Basic roadblock in two ways. The first way is to fire up DCOMCNFG and set the Default Authentication Level (on the Default Properties tab) to None. Although this solution might be fine for my little sealed network at home, it isn't the best fix in a real development shop. The second approach is more secure and appropriate: on the machine that will be running TraceSrv, register TraceSrv as a service, start up Control Panel, and click the Services icon. Select the TraceSrv entry, and click the Start Service button. Click the Properties button to display the TraceSrv Properties dialog box. On the Log On tab, under Log On As, select the This Account radio button and type the user name and password for the account TraceSrv is supposed to use in order to run. Now the service will be able to get the security it needs from a known account on the network. As the "COM Security Frequently Asked Questions" article points out, "Localsystem is a very privileged account locally.... However, it has no network privileges and cannot leave the machine via any [Windows] NT-secured mechanism, including file system, named pipes, DCOM, or secure RPC." Once I got the service started under the proper account, TraceView worked fine. If you're working with a domain server, you might want to consider creating a specific account that you can use just for starting tools such as TraceSrv. For example, if you have a Build account that your build machines use to send mail, you might want to use that.



Debugging Applications
Debugging Applications for MicrosoftВ® .NET and Microsoft WindowsВ® (Pro-Developer)
ISBN: 0735615365
EAN: 2147483647
Year: 2000
Pages: 122
Authors: John Robbins

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net