(This node is for Windows users only. I'm sure the Linux kids can figure this out in their sleep.)

So, first things first: when you run Apache as a service on your Windows computer, it chooses to run as the LocalSystem account by default (usually SYSTEM). The LocalSystem account has no network privileges whatsoever which, while no doubt a good thing, makes it impossible to access networked resources (such as a shared drive) in your Apache service.

There is a lot of information scattered about the web on this subject, but I didn't find a single definitive resource to solving this issue, so I figured I'd post on here for everyone's elucidation - and possibly so if I have to do this again I won't be chasing down the same bits of ephemera twice. So here is the simple, 5 step process for accessing a network resource in Apache, on Windows:

  1. First, you have to change the user the Apache service runs as.
    1. Go to your Services panel (Start -> Run -> "services.msc").
    2. Find the Service labeled Apache, right-click, and hit Properties.
    3. Choose the "Log On" tab.
    4. Presumably you'll see that Apache is set up to run as the Local System Account. You'll want to change this to the second option, "This account", and then fill in the details of the User account you would like Apache to run under.
      1. Some sites tell you to create a special Apache-based user account just for this occasion. It's not a bad idea, but then you have to make sure it has all of the proper permissions that an Apache user would need, such as read/write to to htdocs and the .conf and .log files, and permissions to log on as a service, etc etc - as well as the permissions to access the network resource you're trying to get to in the first place.
      2. In light of that process, I chose to just run it under my own account instead. Once you get it working, you can go back and create that special account.
    5. Hit "Apply" - it'll pop up a box saying you need to restart Apache to take effect, but hold off on that for a moment.
  2. This is the tricky part: you have to give the user (the one you're running Apache as) permissions to act as part of the OS.
    1. Go to the Local Security Policy panel (Start -> Run -> "secpol.msc").
    2. Under the navigation section in the left sidebar, choose Local Policies -> User Rights Assignments.
    3. In the right-hand frame, double-click the item "Act as part of the operating system" to open up its properties.
    4. Select "Add User or Group, Enter the appropriate user in the box provided, and hit "OK."
  3. At this point, you are technically complete - Apache can now do the same things to the network resource that your user can - read, write, execute, whatever. However, in my case, I was trying to create an actual readable resource, so I edited my Apache config file to create an alias to my share.
    1. Open up your Apache configuration file. For most people it's httpd.conf in the conf subdirectory of your Apache install directory.
    2. Add the following text to your config file (obviously substituting your UNC for "//servername/sharename" and renaming ALIAS_DIRECTORY to whatever you'd like):

      Alias /ALIAS_DIRECTORY "//servername/sharename"

      <Directory "//servername/sharename">
          Options Indexes
          AllowOverride None
          Order allow,deny
          Allow from all
      </Directory
    3. The other thing that is tricky and caught me up is that unlike Windows UNCs, the Apache config file requires forward slashes, not backslashes. So if you're copying the UNC directly from Windows, you'll have to turn all those slashes around.

Now you can restart your Apache service. Take a swing over to http://your.site.name/ALIAS_DIRECTORY and you should be able to view the network resource just fine.

Special Addendum for PHP users

If you're trying to use PHP's file/directory functions to read networked directories, you're in luck. Just use the above set up. Then to read the networked drive, use the following code:

<?php

$dir = '\\\\SERVERNAME\\SHARE\\';

if (is_dir($dir)) {
	if ($dh = opendir($dir)) {
		while (($file = readdir($dh)) !== false) {
		echo "filename: $file : filetype: " . filetype($dir . $file) . "\n";
		}
	}
}

closedir($dh);

?>

Note the format of the directory name in the $dir var. Weird, I know, right? But that's what works. Now go forth and make me a code sammich.

Log in or registerto write something here or to contact authors.