The Nested Procedure Menace in Oberon

Just stumbled across this article and interview with Niklaus Wirth, from July 2 this year. There are quite a few interesting things in there, and also historical facts which are good to know. I’ve run into Wirth a couple of times when I was doing my master thesis at ETH. In fact, I’ve done my thesis in the group which was originally headed by Wirth and now is headed by Gutknecht (also a well-known name from the article).

That’s also when I detected the following flaw in Oberon. Imagine the following module:

MODULE NestedProcTest;

VAR SomeProc: PROCEDURE(val: LONGINT);

    PROCEDURE ProcA();
    VAR someLocalVar: LONGINT;

        PROCEDURE NestedProc(val: LONGINT);
        BEGIN
            someLocalVar := val
        END NestedProc;

    BEGIN
        someLocalVar := 1234H;
        SomeProc := NestedProc;
        NestedProc(5678H);
        SomeProc(0DEADH)
    END ProcA;

END NestedProcTest.

On line 15 we assign the nested procedure (‘NestedProc’) to the procedure variable ‘SomeProc’. This is valid because the signatures match, right? Wrong. The signature for ‘NestedProc’ is different: Because nested procedures have access to the parent procedures’ variables, their signature is added a hidden parameter, the so called Static Link. If this parameter is not passed to the procedure when it’s called, the procedure is going to read either its local variables or its parents’ variables from a wrong place (depending on the actual implementation of the calling convention). This of course is wrong and can even make this code crash in case we’d read from an unallocated or protected region.

That’s why I recommended disallowing the assignment of nested procedures to procedure variables. Back in 2006 I have also proposed a change for the Oberon compiler which comes with BlueBottle, but I cannot tell at this point whether it has made it in to the release or not.

This and other findings can be found in the report for my master thesis (dated March 2006): Improved Stackmanagement in the Active Object Kernel – Master Thesis, Roger Keller (742.85 kb)

Troubleshooting Authentication Issues with RGS Agent Tab

Sometimes – especially in lab environments – you’ll see issues around user authentication with the RGS Agent Tab of Office Communications Server 2007 R2. This post should help you in determining what could be the issue and how to work around it.

First of all, when the OCS 2007 R2 WebComponents get installed on a machine, by default Integrated Windows Authenticated (IWA) for the RGS parts of WebComponents are enabled. We don’t require IWA, but this is the recommended setting; anything but Anonymous Authentication should work. If Anonymous Authentication is set for the RGS virtual directory in IIS, you’ll find a warning in NT event log about that. In that case, you should turn back on authentication for the virtual directory.

Another problem I’ve seen a couple of times was as follows: Agent A’s credentials are used to sign in with Office Communicator, but the Agent Tab in OC shows the RGS Agent Group memberships of Agent B, or it shows that the “Current User is not an Agent”. In this case, you should start tracing the RgsClientsLib component and either wait until the Agent Tab in OC refreshes automatically (this should happen within 30 – 60 seconds) or you can open the tab URL in IE; it’s typically something like https://pool-1.contoso.com/Rgs/Clients/Tab.aspx. Then, stop tracing and check out the captured traces for RgsClientsLib. You should now find something along the lines of

Authentication type: [Negotiate]
Authenticated user: [CONTOSO\AgentB]
Authenticated user's SID: [S-1-5-21-2278291046-1170081271-1450921830-1285]
Authenticated user's SID maps to: [efa2cabd-462c-49e4-a021-4dd71bd97ce4]

Please note that I left out the less important information like timestamps etc. here. What you see is that instead of AgentA, AgentB is being authenticated. Usually, this happens when the credentials you pass in to OC are different from the credentials you used to log in to Windows. OC uses the IE engine to render the tabs and thus also leaves the authentication for IE. Then, IE performs the authentication based on the “User Authentication” / “Logon” settings for the zone the Agent Tab is in. The default setting for the “Local Intranet Zone” in IE is to automatically try loggin on with the current user’s credentials – i.e. AgentB’s credentials in this case, because AgentB is the currently logged on (Windows) user. Only if authentication for this user fails, IE is going to prompt you for a different set of credentials. To change this behavior, you can set the security settings in IE accordingly:

IeSecurityZoneUserAuth

Setting it to “Prompt for user name and password” will always prompt you for sites in the intranet zone. Once you’ve done that, exit OC and start it again. Now you should be prompted for the credentials to the Agent Tab and you can provide AgentA’s credentials. You then should see the correct list of groups AgentA is a member of.

Debugging Service Startup

If you are like me working on server development you may run into the situation that a service fails early during startup, i.e. within the first couple of seconds. You’ll soon realize that manually attaching a debugger doesn’t work well, if at all. Even if you’ll be running

windbg -pn MyService.exe

you may not actually be fast enough. Or there are multiple instances of that image running (e.g. SvcHost.exe) and the above command becomes kind of useless. Now if you have been reading the ‘Debugging Tools for Windows’ documentation (or have debugged services before) you’ll already know what I am about to tell you here.

As I mentioned above, the first problem you’re fighting with is that the failure happens very early. Another problem you may have is that your service is running e.g. as ‘NT AUTHORITY\NETWORK SERVICE’ and thus may not be able to interact with your desktop. But Windows’ right here to help you out with ‘Image File Execution Options’. This basically allows you to execute a command when a particular image is being executed.

You start by creating a key for the image file in the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\MyService.exe

There you create a new string value of the name ‘Debugger’ and set its value to the path of the debugger you want to invoke, e.g. something like ‘C:\Debuggers\cdb.exe’. To mitigate the problem of the non-interactive service, you’ll probably want to use the debugger remotely, so you’ll create a debugging server: ‘C:\Debuggers\cdb.exe -server npipe:pipe=MyDebuggingSession’. What you have now is a debugger which is attached as soon as the service starts and which is accessible remotely. Thus, you can either on the server itself or another machine which has access run for instance

windbg -remote npipe:server=my-machine,pipe=MyDebuggingSession

and there you go: you are now debugging the service. Use the various command line options for the debuggers to

  • ignore the initial break point (-g)
  • run commands right after the debugger is attached (-c)
  • create a script which sets some useful breakpoints and run it when the debugger is attached (e.g. -c “$<MyScript.txt”)

You may actually have to adjust the service control timeout. To do so, add a DWORD called ‘ServicesPipeTimeout’ to the registry key

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

and set its value to the number of milliseconds you want the service to wait before timing out.

You’ll find pretty much all of this information also in the help file for ‘Debugging Tools for Windows’ under ‘Debugging a Service Application’. Enjoy!

Agent Communications Panel for Microsoft Dynamics CRM 4.0 Released

Last week the Agent Communications Panel for Microsoft Dynamics CRM 4.0 has been released and is now available from the Microsoft Download Center. It allows a certain amount of customization such as integration with the Response Group Service of Office Communications Server 2007 R2. That said, it uses the Agent WebService of RGS to determine the agent group memberships. And given the title, it of course also integrates with Dynamics CRM 4.0.