Commits

Zhang Huangbin  committed 8ac86f0

Use MySQLdb directly for SQL related operations. Avoid 'too many connections' issue.
Fixed incorrect policy name in plugin 'sql_alias_access_policy.py': allowedOnly -> allowedonly (convert to lower case).

  • Participants
  • Parent commits ace1c80

Comments (0)

Files changed (4)

+iRedAPD-1.3.6:
+    * Use MySQLdb directly for SQL related operations. Avoid 'too many
+      connections' issue.
+    * Fixed incorrect policy name in plugin 'sql_alias_access_policy.py':
+      allowedOnly -> allowedonly (convert to lower case).
+
 iRedAPD-1.3.5:
     * Fix incorrect ldap search scope in plugin 'ldap_maillist_access_policy'.
 

File src/iredapd-rr.py

 import logging
 import daemon
 
-__version__ = "1.3.5"
+__version__ = '1.3.6'
 
 ACTION_ACCEPT = 'DUNNO'
 ACTION_DEFER = 'DEFER_IF_PERMIT Service temporarily unavailable'

File src/iredapd.py

 import logging
 import daemon
 
-__version__ = "1.3.5"
+__version__ = '1.3.6'
 
 ACTION_ACCEPT = 'DUNNO'
 ACTION_DEFER = 'DEFER_IF_PERMIT Service temporarily unavailable'
     def found_terminator(self):
         if len(self.buffer) is not 0:
             line = self.buffer.pop()
-            logging.debug("smtp session: " + line)
+            #logging.debug("smtp session: " + line)
             if line.find('=') != -1:
                 key = line.split('=')[0]
                 value = line.split('=', 1)[1]
 
 
 class MySQLModeler:
-    def __init__(self):
-        import web
-
-        # Turn off debug mode.
-        web.config.debug = False
-
-        try:
-            self.db = web.database(
-                dbn='mysql',
-                host=cfg.get('mysql', 'server', 'localhost'),
-                db=cfg.get('mysql', 'db', 'vmail'),
-                user=cfg.get('mysql', 'user', 'vmail'),
-                pw=cfg.get('mysql', 'password'),
-            )
-        except Exception, e:
-            logging.error("Error while creating database connection: %s" % str(e))
-
     def handle_data(self, map):
         if 'sender' in map.keys() and 'recipient' in map.keys():
             if len(map['sender']) < 6:
                 for module in self.modules:
                     try:
                         logging.debug('Apply plugin (%s).' % (module.__name__, ))
+                        import MySQLdb
+                        try:
+                            db = MySQLdb.connect(
+                                host=cfg.get('mysql', 'server', 'localhost'),
+                                db=cfg.get('mysql', 'db', 'vmail'),
+                                user=cfg.get('mysql', 'user', 'vmail'),
+                                passwd=cfg.get('mysql', 'password'),
+                            )
+                            cursor= db.cursor()
+                        except Exception, e:
+                            logging.error("Error while creating database connection: %s" % str(e))
+
                         pluginAction = module.restriction(
-                            dbConn=self.db,
+                            dbConn=cursor,
                             senderReceiver=senderReceiver,
                             smtpSessionData=map,
                             logger=logging,
                         )
 
+                        try:
+                            cursor.close()
+                            logging.debug('Closed SQL connection.')
+                        except Exception, e:
+                            logging.debug('%s' % str(e))
+
                         logging.debug('Response from plugin (%s): %s' % (module.__name__, pluginAction))
                         if not pluginAction.startswith('DUNNO'):
                             logging.info('Response from plugin (%s): %s' % (module.__name__, pluginAction))

File src/plugins/sql_alias_access_policy.py

 #   - membersAndModeratorsOnly: Only members and moderators are allowed.
 
 import os
+from web import sqlquote
 
 ACTION_REJECT = 'REJECT Not Authorized'
 PLUGIN_NAME = os.path.basename(__file__)
 POLICY_SUBDOMAIN = 'subdomain'
 POLICY_MEMBERSONLY = 'membersonly'
 POLICY_MODERATORSONLY = 'moderatorsonly'
-POLICY_ALLOWEDONLY = 'allowedOnly'      # Same as @POLICY_MODERATORSONLY
+POLICY_ALLOWEDONLY = 'allowedonly'      # Same as @POLICY_MODERATORSONLY
 POLICY_MEMBERSANDMODERATORSONLY = 'membersandmoderatorsonly'
 
 def restriction(dbConn, senderReceiver, smtpSessionData, logger, **kargs):
-    # Get alias account from alias table.
-    # If you need to run RAW SQL command, use dbConn.query() instead.
-    # Reference: http://webpy.org/cookbook/query
-    # Sample:
-    #   result = dbConn.query('''SELECT * FROM alias WHERE address=$recipient''', vars=senderReceiver,)
 
-    result = dbConn.select(
-        'alias',
-        senderReceiver,
-        where='address = $recipient AND domain = $recipient_domain',
-        limit=1,
-    )
+    sql = '''SELECT accesspolicy, goto, moderators \
+            FROM alias \
+            WHERE address=%s AND domain=%s AND active=1 \
+            LIMIT 1 \
+    ''' % (sqlquote(senderReceiver.get('recipient')), sqlquote(senderReceiver.get('recipient_domain')),)
+    logger.debug('SQL: %s' % sql)
+
+    dbConn.execute(sql)
+    sqlRecord = dbConn.fetchone()
+    logger.debug('SQL Record: %s' % str(sqlRecord))
 
     # Recipient account doesn't exist.
-    if len(result) != 1:
-        return 'DUNNO Account does not exist.'
+    if sqlRecord is None:
+        return 'DUNNO Alias account does not exist.'
 
-    # Use the first SQL record.
-    sqlRecord = result[0]
+    policy = str(sqlRecord[0]).lower()
 
-    policy = sqlRecord.get('accesspolicy', 'public').lower()
-
-    members = [str(v.lower()) for v in sqlRecord.get('goto', '').split(',')]
-    moderators = [str(v.lower()) for v in sqlRecord.get('moderators', '').split(',')]
+    members = [str(v.lower()) for v in str(sqlRecord[1]).split(',')]
+    moderators = [str(v.lower()) for v in str(sqlRecord[2]).split(',')]
 
     logger.debug('(%s) policy: %s' % (PLUGIN_NAME, policy))
     logger.debug('(%s) members: %s' % (PLUGIN_NAME, ', '.join(members)))