source: server/common/oursrc/whoisd/whoisd.tac @ 762

Last change on this file since 762 was 762, checked in by quentin, 16 years ago
Don't scan vhosts if there isn't a vhost directory
File size: 3.6 KB
Line 
1from twisted.application import internet, service
2from twisted.internet import protocol, reactor, defer
3from twisted.protocols import basic
4import ldap, ldap.filter
5import os, sys, pwd, glob
6
7class WhoisProtocol(basic.LineReceiver):
8    def lineReceived(self, hostname):
9        self.factory.getWhois(hostname
10        ).addErrback(lambda _: "Internal error in server"
11        ).addCallback(lambda m:
12                      (self.transport.write(m+"\r\n"),
13                       self.transport.loseConnection()))
14class WhoisFactory(protocol.ServerFactory):
15    protocol = WhoisProtocol
16    def __init__(self, vhostDir, ldap_URL, ldap_base):
17        self.vhostDir = vhostDir
18        self.ldap_URL = ldap_URL
19        self.ldap = ldap.initialize(self.ldap_URL)
20        self.ldap_base = ldap_base
21        self.vhosts = {}
22        if vhostDir:
23            self.rescanVhosts()
24    def rescanVhosts(self):
25        newVhosts = {}
26        for f in glob.iglob(os.path.join(self.vhostDir, "*.conf")):
27            locker = os.path.splitext(os.path.basename(f))[0]
28            newVhosts.update(self.parseApacheConf(file(f)))
29        self.vhosts = newVhosts
30        self.vhostTime = os.stat(self.vhostDir).st_mtime
31    def parseApacheConf(self, f):
32        vhosts = {}
33        hostnames = []
34        locker = None
35        docroot = None
36        for l in f:
37            parts = l.split()
38            if not parts: continue
39            command = parts.pop(0)
40            if command in ("ServerName", "ServerAlias"):
41                hostnames.extend(parts)
42            elif command in ("SuExecUserGroup",):
43                locker = parts[0]
44            elif command in ("DocumentRoot",):
45                docroot = parts[0]
46            elif command == "</VirtualHost>":
47                d = {'locker': locker, 'apacheDocumentRoot': docroot, 'apacheServerName': hostnames[0]}
48                for h in hostnames: vhosts[h] = d
49                hostnames = []
50                locker = None
51                docroot = None
52        return vhosts
53    def canonicalize(self, vhost):
54        vhost = vhost.lower().rstrip(".")
55        return vhost
56#        if vhost.endswith(".mit.edu"):
57#            return vhost
58#        else:
59#            return vhost + ".mit.edu"
60    def searchLDAP(self, vhost):
61        results = self.ldap.search_s(self.ldap_base, ldap.SCOPE_SUBTREE,
62            ldap.filter.filter_format(
63                '(|(apacheServername=%s)(apacheServerAlias=%s))', (vhost,)*2))
64        if len(results) >= 1:
65            result = results[0]
66            attrs = result[1]
67            for attr in ('apacheServerName','apacheDocumentRoot', 'apacheSuexecUid', 'apacheSuexecGid'):
68                attrs[attr] = attrs[attr][0]
69            user = pwd.getpwuid(int(attrs['apacheSuexecUid']))
70            if user:
71                attrs['locker'] = user.pw_namep
72            else:
73                attrs['locker'] = None
74            return attrs
75        else:
76            return None
77    def getWhois(self, vhost):
78        vhost = self.canonicalize(vhost)
79        info = self.vhosts.get(vhost)
80        if not info:
81            info = self.searchLDAP(vhost)
82        if info:
83            ret = "Hostname: %s\nAlias: %s\nLocker: %s\nDocument Root: %s" % \
84                (info['apacheServerName'], vhost, info['locker'], info['apacheDocumentRoot'])
85        else:
86            ret = "No such hostname"
87        return defer.succeed(ret)
88
89application = service.Application('whois', uid=99, gid=99)
90factory = WhoisFactory(None,
91    "ldap://localhost", "ou=VirtualHosts,dc=scripts,dc=mit,dc=edu")
92internet.TCPServer(43, factory).setServiceParent(
93    service.IServiceCollection(application))
Note: See TracBrowser for help on using the repository browser.