Building and Integrating a Small Office Intranet
Intranets have been around for a long time. They were one of the first alternate uses for World Wide Web technology back in the early 1990s. The idea of bringing a little bit of the Web experience in-house was very attractive, but integration with existing systems was difficult. Thus, a lot of intranets were nothing more than glorified bulletin boards with some user-publishing features thrown in. The landscape is different now, with open-source software ready to take most of the cost and some of the complexity away from a good intranet setup. The so-called LAMP stack provides the perfect neutral platform for integrating many different pieces of software into a single point of interaction for users. That's what we have tried to do at our company.
Our intranet started off in 1999 as a Web-based bulletin board and company calendar on a Red Hat 6.0 server running Apache. It was a static HTML site that was designed and kept current by our marketing manager. After she left the company in 2002, we needed to make the intranet more dynamic so that it didn't depend on one person to keep it up to date. As is usually the case, we added more and more features over the years and now have a very useful, user-friendly intranet site without a lot of unnecessary or static content that needs to be maintained. In this article, I use our intranet as an example of how to solve four of the more common integration tasks that small business admins may run into when setting up a LAMP-based intranet.
Our intranet currently serves about 70 employees and runs on an IBM x335 server running Fedora Core 4. We use a normal LAMP stack (Linux, Apache 1.3x, MySQL and Perl) with mod_perl to improve performance. Apache currently shares the server with our e-mail scanner, internal DNS, Jabber, Samba and some other services. It's nice having all of this running on a single Linux server, because it reduces the need for NFS mounts and cuts down on network traffic. Some sites will be too large for this approach, but nothing in our design would preclude it from working in a multiserver setup. All of our users run Windows XP and authenticate through Active Directory. We use GroupWise as our e-mail software running on a NetWare 6 server, and all of its information is handled by Novell's eDirectory. We also have a time and billing system that runs on a Windows NT 4.0 server and stores its data in a Microsoft SQL Server database. You can see a layout of how everything links together in Figure 1.
We decided early on that our users shouldn't have to authenticate in any way to our intranet. The site should automatically “know” who they are based on their IP address and information gleaned from the network about who is currently logged in from that address. We call this technique server-side credentialing (SSC). We accomplished this originally by using a piece of custom-written client-side software that was contacted by a CGI script any time the server needed to check a user's identity. This works, but it places too much trust on the client side. A sniffer and a Perl script could fake a user's identity nicely from any client computer. We now use Samba and winbindd for this task.
Because our intranet server resides on a trusted internal network, it is privy to the current state of affairs on the network, including who is logged in from where. Every computer in the office maps a drive letter to the Samba server during login, so any time the server needs the current user's identity, it simply looks up his or her IP address in the Samba connection list. The mapped drive is just a dummy drive explicitly for the SSC mechanism. I think this is an important feature, because it lowers the complexity of the site from a programming standpoint and allows users to browse freely without having to worry about registering or logging in. Users have enough user names and passwords to keep track of already without us adding to their burden.
The way you set up SSC depends on how your users authenticate on your network. We use Active Directory, so that is what I demonstrate here. Active Directory is annoying (surprise, surprise), because it doesn't store connection status information in its directory. You must use traditional RPC calls with Samba's net command to get reliable results. Our SSC script is called smbconn.sh, and it looks like this:
#!/bin/sh net status sessions parseable \ | grep -i "\\\\$1\\\\" \ | sed 's/^.*\\\(.*\)\\.*\\.*\\.*$/\1/g' \ | sed 's/DOMAIN+//g' | tr -d ' '
Pretty simple, eh? Just remember to change DOMAIN to whatever your Active Directory's domain name is. This script returns the name of the user object that is logged in to Samba from the IP address we pass to it on the command line. The name it returns corresponds to Active Directory's sAMAccountName property. Armed with this information, we now can run an LDAP lookup to get the user's full name or any other data we might need. The script we use to do this is found in Listing 1. It will take the user's sAMAccountName as its first argument and an optional attribute whose value you want returned as the second argument. If you don't provide the optional attribute, the script returns the user's full name. You could do all of this in a custom mod_perl handler so that its information always would be available, but this seems like overkill for most sites. Our site has only a handful of restricted sections where this information comes into play, so we just let each CGI script run it as needed. Here is a typical SSC call from one of our CGI scripts:
##: Get this connection's user credentials
my $remoteip=$ENV{'REMOTE_ADDR'};
open(SMBCONN,"smbconn.sh $remoteip |");
my $cn=<SMBCONN>;
$cn=~s/\s+//g; ##: Strip whitespace
close(SMBCONN);
open(GETEMPINFO,"getempinfo.pl $cn |");
my $username=<GETEMPINFO>;
close(GETEMPINFO);
if($username eq "") {
$username="Guest";
}
This section of code leaves us with the user's sAMAccountName in the $cn variable and the user's full name in the $username variable. If the $username variable contains Guest, either the lookup failed or the computer accessing this CGI script doesn't have a logged-in user operating it. We now can use this critical information to decide whether the user has access to the information this CGI script is meant to provide. We also can use this information to return a page customized for this particular user. I demonstrate this with a section of code from the index.cgi file that serves up our home page:
##: My Intranet section
my $mint="";
if(($username eq "Guest") || ($username eq "")) {
open(EMPSNAP,"./random-employee.pl 2>&1 |");
my @snap=<EMPSNAP>;
close(EMPSNAP);
$mint.=join("\n",@snap);
chop($mint);
} else {
$mint.=&get_emp_card($cn);
$mint.="<b>E-Mail Controls:</b><br>\n";
$mint.="<a href='selfserv.cgi'>My Mail</a>\n";
...
}
...
print STDOUT $mint;
You can see here that we check to see if the person viewing the home page is actually a credentialed user. If he or she is not, we serve up a random employee's picture and profile in this section of the home page. If the person is a credentialed user, we grab the appropriate personal information from the LDAP directory and proceed to assemble a My Intranet area in this section of the home page where the user can edit his or her employee profile, control mail preferences and so forth. The get_emp_card($cn) routine simply looks up the user's current info in Active Directory and returns a nicely formatted HTML section to display it (Figure 2).
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
| Introduction to MapReduce with Hadoop on Linux | Jun 05, 2013 |
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Linux Systems Administrator
- Validate an E-Mail Address with PHP, the Right Way
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Introduction to MapReduce with Hadoop on Linux
- RSS Feeds






1 hour 45 min ago
2 hours 11 min ago
4 hours 40 min ago
5 hours 13 min ago
5 hours 14 min ago
5 hours 15 min ago
5 hours 17 min ago
5 hours 18 min ago
5 hours 19 min ago
5 hours 20 min ago