Posts Tagged ‘feature’

When Guest is the administrator

May 5, 2011

Nommo was kind enough to point me to his latest blog entry which discusses a troubleshooting case where the Guest account had somehow wound up being the only active administrator account on a Windows Vista computer.  This was reasonably easy to reproduce (although I used Windows 7 instead) and, indeed, user management tools don’t work as might be expected.

This is interesting.  In most other respects the Guest account still functions as an administrative account.  At first I thought I understood exactly why this happened (to do with the way LAN Manager handled security way back in the days of DOS) but a bit of experimentation showed I was wrong.  It now looks as though a Guest logon is tagged in some way and prohibited from doing any user management – the Guest account can’t even look up its own details – unless you elevate to it from another account, in which case it has user-level access to account management but not administrator-level.  Weird, huh?

Only the actual Guest account is affected; other accounts that are in both Administrators and Guests are not.

Because only account management is blocked, you can get around this in a few ways.  Probably the simplest in most cases is to download the psexec tool from Microsoft.  Start an elevated command-line window by typing “cmd” into the “Search Programs and Files” box in the Start Menu and pressing Control-Shift-Enter.  Then type:

cd /d c:\directory\where\psexec\was\downloaded\to
psexec -s \\127.0.0.1 net localgroup Administrators /add myusername

pressing ENTER after each line and changing “myusername” to the username of the other (currently non-administrative) account.

Alternately, you could edit the registry as described in my earlier post but you don’t need to boot from external media:

  1. Go to the Start Menu and type “regedit” and press ENTER.
  2. Open HKEY_LOCAL_MACHINE, then SYSTEM, then Setup.
  3. Double-click on SetupType in the right-hand pane.  Enter 2 and press OK.
  4. Double-click on CmdLine.  Enter cmd.exe and press OK.
  5. Reboot the machine.  A command window should appear.
  6. Type “net localgroup Administrators /add myusername” and press ENTER.
  7. Type: “exit” and press ENTER.

Again, “myusername” should be replaced with the username of an existing, non-administrative account.  After this procedure, the account is administrative.  You could also use “net user myusername newpassword” to change the password if necessary.  (The same caveat applies as in my previous post: doing this permanently locks you out of any encrypted files in the account.)

Now, obviously Guest shouldn’t be an administrator.  The fact that things behave oddly in this situation is not a bug.  However, if Guest is an administrator the normal recovery options don’t work properly.  In particular you are supposed to be able to log in as Administrator if no usable administrative accounts exist, and in this situation you can’t, and this is a bug.

Hope this helps.

Installing 32-bit software as SYSTEM in Windows 7 x64

February 20, 2011

Hi,

I recently ran into an issue updating the Sun Java runtime on our x64 machines.  We don’t have the budget for fancy deployment solutions, so we just use a startup script (actually an executable, but that’s just fine-tuning) that checks the version number and runs the installer(s) as necessary.

Installing the 32-bit JRE results in error code 1619, which NET HELPMSG translates as “This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package.”  Running the installer in interactive mode produces the same message.  The installer works normally when run from the context of a logged-in user.

Several hours of troubleshooting later, I identified the source of the problem.  Startup scripts run as local system.  In Windows 7, processes that run as local system have a special profile found in c:\windows\system32\config\systemprofile.  Unfortunately, on 64-bit systems, there are two system32 folders; one for 64-bit processes,and another (whose real name is syswow64) for 32-bit processes.  As a result, there are two separate system profiles; one for 32-bit, one for 64-bit.

So what?  Well, the Sun Java installer unpacks into a subfolder of the LocalLow application data directory.  In this case, the folder in question is c:\windows\system32\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24.  Because this is a 32-bit process, though, it is really writing to syswow64 instead of system32.

The Windows Installer, however, is a 64-bit process.  So when it is asked to open the MSI file, it’s looking in the wrong place; hence error code 1619.  The file can’t be opened because it can’t be found.

The same underlying problem (duplication of the system profile) seems to be the cause of this problem with Known Folders warning 1002 appearing repeatedly in the event log.  Some 32-bit system process is registering folder paths inside the (32-bit) system profile and of course these folders can’t be found by 64-bit processes.

For the problem with installing 32-bit software, there are a number of possible workarounds.  You could manually extract the installer files, copy them to a suitable path on the local system, and run them directly.  Most installers won’t mind this, although some will balk or fail to function properly.  Alternatively (and this is the solution I chose) you could create the necessary directory ahead of time and add a junction point (mklink /J) from the 64-bit profile to the 32-bit profile (note that this command line assumes you are in a 32-bit context, and has been split for readability):

mklink /J c:\windows\sysnative\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24
 c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24

This is the equivalent command if you are in a 64-bit context:

mklink /J c:\windows\system32\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24
 c:\windows\syswow64\config\systemprofile\AppData\LocalLow\Sun\Java\jre1.6.0_24

Another possible approach would be to merge the two system profiles together and create a junction point from one to the other.  That would solve this issue for all installers, as well as the Known Folders issue and any other variants.  However, I can’t recommend doing this; it’s too broad a change, and there’s no way to predict what it might break.  If you’re very brave, go ahead, but test thoroughly – and don’t blame me!

Hope this helps.

Harry.

Incorrect Username or Password – or perhaps the clock is wrong

July 2, 2010

Greetings!

OK, this one had me puzzled for an hour or two.  My main test box having failed, I had taken one of the older machines hanging around my office and given it a once-over; some extra RAM, a bigger hard disk drive, that sort of thing.  I noticed the motherboard battery had died, but figured I could live without it.  What the hey; the machine stays connected to the mains most of the time anyway.

So I go to install Windows 7 on the box, using our automated install system on my USB stick.  This is a Windows PE image which runs Windows Setup in unattended mode over the network.  It also includes a bit of in-house code so that you can provide an administrator password to join the machine to the domain in advance; once this password has been accepted, everything else happens automatically.  A few hours later the machine will be ready to use, software and all.  This sort of streamlining may seem unnecessary, but it does make life easier.

Except that this time the domain controller wouldn’t accept my password.  Typed it in again; no luck.  After trying once more, well, okay, several times more, and logging in on another machine to make sure I hadn’t gotten confused about which password went with which account, I realised there really was something wrong.

So I try it on another machine, and it works perfectly.  I try booting the first machine from a copy on CD instead of the one on my USB stick; no difference.  Bringing up a command line window allows me to explicitly attempt to connect to the domain controllers as well as other network servers, with both my own account and a test account with a simpler password – just in case!

The results were puzzling to say the least.  Error code 86 – the network password is not correct – for any user account but only from that one machine and only when connecting to a domain controller.  The file server, by comparison, was perfectly happy to accept the supposedly “incorrect” passwords.  In case there was something wrong with the Windows PE image, I repeated the experiment using the standard Windows 7 install DVD, but this exhibited the same problem.  Swapping the keyboards and network cables between the machines was a long shot at best, this didn’t pan out either.  The event log on the domain controller showed the logon failures but provided no additional information.  For some reason, the problem didn’t occur when booted to a copy of Windows PE 2 (which is based on Vista rather than Windows 7) but this didn’t help me much.

Eventually it dawned on me that the flat motherboard battery meant that the on-board clock would have been reset; the computer thought the year was 2004.  Mismatched clocks have been known to cause authentication problems, and sure enough, once I had corrected the date and time via the BIOS the domain controller accepted my password and the automated installer set to work.

I’m not sure what the moral of this story is exactly.  I suppose I should have remembered the failed battery as soon as the machine started behaving oddly, and stopped to think about whether there could be a connection.  Anyway, I’ve tagged this as a bug, not because the authentication should necessarily have worked, but because the error code (or at least the event log!) should have indicated the actual problem instead of insisting that the password was wrong.

Harry.

IOCTL_DISK_GET_LENGTH_INFO doesn’t work on floppy disks

January 12, 2010

I was trying to write a floppy disk image to a physical disk the other day, and my home-made imaging tool was refusing to work.  Once I got around to tracking this down, it turned out that IOCTL_DISK_GET_LENGTH_INFO simply doesn’t work on floppy disks, returning error code 1, ERROR_INVALID_FUNCTION, Incorrect Function.

This happens on both Windows XP and Windows 7, and presumably on other versions as well.  I suspect Microsoft would categorise this as a feature rather than a bug. :-)

I’m not sure if this is the best workaround, but it’s what I came up with.  Note that IOCTL_DISK_GET_DRIVE_GEOMETRY_EX also doesn’t work for floppy disks.

I haven’t tested this with, e.g., ZIP disks, or with a wide range of USB memory sticks.  Feel free to copy-and-paste this code segment into your own project if it will help, but it comes without any warranty, express or implied.

if (!DeviceIoControl
 (
  houtput,
  IOCTL_DISK_GET_DRIVE_GEOMETRY,
  NULL,
  0,
  &target_diskgeometry,
  sizeof(target_diskgeometry),
  &byte_count,
  NULL
 ))
{
 err = GetLastError();
 fprintf(stderr, "Error %u getting output device geometry.\n", err);
 return err;
}

switch (target_diskgeometry.MediaType)
{
case Unknown:
case RemovableMedia:
case FixedMedia:

 if (!DeviceIoControl
  (
   houtput,
   IOCTL_DISK_GET_LENGTH_INFO,
   NULL,
   0,
   &target_disklength,
   sizeof(target_disklength),
   &byte_count,
   NULL
  ))
 {
  err = GetLastError();
  fprintf(stderr, "Error %u getting output device length.\n", err);
  return err;
 }

 fprintf(stderr, "Output disk has %I64i bytes.\n\n", target_disklength.Length.QuadPart);
 break;

default:

 target_disklength.Length.QuadPart =
  target_diskgeometry.Cylinders.QuadPart *
  target_diskgeometry.TracksPerCylinder *
  target_diskgeometry.SectorsPerTrack *
  target_diskgeometry.BytesPerSector;

 fprintf(stderr,
  "\n"
  "Output device appears to be a floppy disk.  WARNING: if this is not a\n"
  "floppy disk the calculated output device size is probably incorrect,\n"
  "which might result in an incomplete copy.\n"
  "\n"
  "Output disk has %I64i bytes.\n"
  "\n",
  target_disklength.Length.QuadPart);

 break;
}

Hope this helps.

Addendum: note that the figures returned by IOCTL_DISK_GET_DRIVE_GEOMETRY don’t give you the correct device length for hard disk drives, so that’s why this code uses IOCTL_DISK_GET_LENGTH_INFO unless the device is a floppy disk.


Follow

Get every new post delivered to your Inbox.