summaryrefslogtreecommitdiff
path: root/Mailman/MTA/Postfix.py
Commit message (Collapse)AuthorAgeFilesLines
* Bite the bullet: rename the Mailman package to mailman.Barry Warsaw2008-02-271-413/+0
|
* Tweak copyright years.Barry Warsaw2008-02-071-1/+1
|
* Initial pylint/pyflakes cleanupBarry Warsaw2007-11-171-2/+4
|
* Much progress, though not perfect, on migrating to SQLAlchemy 0.4 and ElixirBarry Warsaw2007-10-311-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 0.4. Lots of things changes, which broke lots of our code. There are still a couple of failures in the test suite that I don't understand. It seems that for pending.txt and requests.txt, sometimes strings come back from the database as 8-bit strings and other times as unicodes. It's impossible to make these tests work both separately and together. users.txt is also failing intermittently. Lots of different behavior between running the full test suite all together and running individual tests. Sigh. Note also that actually, Elixir 0.4.0 doesn't work for us. There's a bug in that version that prevented zope.interfaces and Elixir working together. Get the latest 0.4.0 from source to fix this. Other changes include: - Remove Mailman/lockfile.py. While I haven't totally eliminated locking, I have released the lockfile as a separate Python package called locknix, which Mailman 3.0 now depends on. - Renamed Mailman/interfaces/messagestore.py and added an IMessage interface. - bin/testall raises turns on SQLALCHEMY_ECHO when the verbosity is above 3 (that's three -v's because the default verbosity is 1). - add_domain() in config files now allows url_host to be optional. If not given, it defaults to email_host. - Added a non-public interface IDatabase._reset() used by the test suite to zap the database between doctests. Added an implementation in the model which just runs through all rows in all entities, deleting them. - [I]Pending renamed to [I]Pended - Don't allow Pendings.add() to infloop. - In the model's User impelementations, we don't need to append or remove the address when linking and unlinking. By setting the address.user attribute, SQLAlchemy appears to do the right thing, though I'm not 100% sure of that (see the above mentioned failures).
* General cleanups some of which is even tested <wink>. Mailman.LockFile moduleBarry Warsaw2007-10-101-10/+6
| | | | | | | | | | | | | is moved to Mailman.lockfile. Remove a few more MailList methods that aren't used any more, e.g. the lock related stuff, the Save() and CheckValues() methods, as well as ChangeMemberName(). Add a missing import to lifecycle.py. We no longer need withlist to unlock the mailing list. Also, expose config.db.flush() in the namespace of withlist directly, under 'flush'.
* Clean up file permissions and umask settings. Now we set the umask to 007bwarsaw2007-01-051-16/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | during early initialization so that we're guaranteed to get the right value regardless of the shell umask used to invoke the command line script. While we're at it, we can remove almost all individual umask settings previously in the code, and make file permissions consistently -rw-rw---- (IOW, files are no longer other readable). The only subsystem that wasn't changed was the archiver, because it uses its own umask settings to ensure that private archives have the proper permissions. Eventually we'll mess with this, but if it ain't broken... Note that check_perms complains about directory permissions, but I think check_perms can be fixed (or perhaps, even removed?!). If we decide to use LMTPRunner and HTTPRunner exclusively then no outside process will be touching our files potentially with the incorrect permissions, umask, owner, or group. If we control all of our own touch points then I think we can lock out 'other'. Another open question is whether Utils.set_global_password() can have its umask setting removed. It locks permissions down so even the group can't write to the site password file, but the default umask of 007 might be good enough even for this file. Utils.makedirs() now takes an optional mode argument, which defaults to 02775 for backward compatibility. First, the default mode can probably be changed to 02770 (see above). Second, all code that was tweaking the umask in order to do a platform compatible os.mkdir() has now been refactored to use Utils.makedirs(). Another tricky thing was getting SQLite via SQLAlchemy to create its data/mailman.db file with the proper permissions. From the comment in dbcontext.py: # XXX By design of SQLite, database file creation does not honor # umask. See their ticket #1193: # http://www.sqlite.org/cvstrac/tktview?tn=1193,31 More details in that file, but the work around is to essentially 'touch' the database file if 'sqlite' is the scheme of the SQLAlchemy URL. This little pre-touch sets the right umask honoring permission and won't hurt if the file already exists. SQLite will happily keep the existing permissions, and in fact that ticket referenced above recommends doing things this way. In the Mailman.database.initialize(), create a global lock that prevents more than one process from entering this init function at the same time. It's probably not strictly necessary given that I believe all the operations in dbcontext.connect() are multi-processing safe, but it also doesn't seem to hurt and prevents race conditions regardless of the database's own safeguards (or lack thereof). Make sure nightly_gzip.py calls initialize().
* Merged revisions 8113-8121 via svnmerge from bwarsaw2006-12-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | https://mailman.svn.sourceforge.net/svnroot/mailman/branches/tmp-sqlalchemy-branch ................ r8114 | bwarsaw | 2006-12-06 00:16:54 -0500 (Wed, 06 Dec 2006) | 44 lines Initial take on using SQLAlchemy to store list data in lieu of Python pickles. While all the list data (including OldStyleMemberships attributes) are stored in the database, many attributes are stored as PickleTypes binary data. This isn't idea but it gets things working until a more sophisticated schema can be developed. MailList class is now a new-style class, as is required by SQLAlchemy. This makes several things, er, interesting. Rip out all the low-level pickle reading and writing stuff. Hook SA transaction events into Lock() and Unlock(). Move the hooking of the _memberadaptor into InitTempVars(), which gets called by the SQLAlchemy hooks (MailList.__init__() never is). Add an initialize.py module which centralizes all the initialization bits that command line scripts have to do, including configuration, logging, and atabase initialization. This change also converts bin/withlist to mmshell wrapper. Update to SQLAlchemy 0.3.1. Revamp paths.py.in considerably. There were several problems with the old way. We no longer disable default loading of site-packages so we don't need to add Python's site-packages back to sys.path. Also, because site.addsitedir() causes things like .pth paths to be /appended/ to sys.path, they actually won't override any site-installed packages. E.g. if SQLAlchemy is installed in the system Python, our version will not override. IIUC, setuptools-based packages can be configured to work properly in the face of package versions, however not all packages we currently depend on are setuptools-based. So instead, we steal a bit of stuff from site.py but change things so the prepend .pth stuff to sys.path. Update several modules to use True/False and whitespace normalization. Convert from mm_cfg to config object. Modernize a few coding constructs. Add a couple of exceptions to handle database problems. In the export script, include the widget type in the elements. This helped in my stupid little throw away conversion script, but I think it will be more generally useful. Add an interact.py module which refactors interactive interpreter access. Mostly this is used by withlist -i, but it lets us import Mailman.interact and drop into a prompt just about anywhere (e.g. debugging). ................ r8115 | bwarsaw | 2006-12-07 09:13:56 -0500 (Thu, 07 Dec 2006) | 22 lines Start to flesh out more of the SQLAlchemy mechanisms. Added a MailList.__new__() which hooks instantiation to use a query on dbcontext to get an existing mailing list. A 'no-args' call means we're doing a Create(), though eventually that will change too. For now, disable the CheckVersion() call. Eventually this will be folded into schema migration. list_exists(): Rewrite to use the dbcontext query to determine if the named mailing list exists or not. Requires the fqdn_listname. Eradicate two failed member adaptors: BDBMemberAdaptor and SAMemberships. Change the way the DBContext holds onto tables. It now keeps a dictionary mapping the table's name to the SA Table instance. This makes it easier to look up and use the individual tables. Add 'web_page_url' as an attribute managed by SA, and remove a debugging print. ................ r8116 | bwarsaw | 2006-12-11 07:27:47 -0500 (Mon, 11 Dec 2006) | 29 lines Rework the whole dbcontext and transaction framework. SA already handles nested transactions so we don't have to worry about them. However, we do have the weird situation where some transactions are tied to MailList .Lock()/.Unlock()/.Save() and some are tied to non-mlist actions. So now we use an @txn decorator to put methods in a session transaction, but then we also hook into the above MailList methods as possibly sub-transactions. We use a weakref subclass to manage the MailList interface, with a dictionary mapping MailList fqdn_listnames against transactions. The weakrefs come in by giving us a callback when a MailList gets derefed such that we're guaranteed to rollback any outstanding transaction. Also, we have one global DBContext instance but rather than force the rest of Mailman to deal with context objects, instead we expose API methods on that object into the Mailman.database module, which the rest of the code will use. Such methods must be prepended with 'api_' to get exposed this way. bin/rmlist now works with the SA-backend. I refactored the code here so that other code (namely, the test suite) can more easily and consistently remove a mailing list. This isn't the best place for it ultimately, but it's good enough for now. New convenience functions Utils.split_listname(), .fqdn_listname(). Convert testall to use Mailman.initialize.initialize(). Not all tests work, but I'm down to only 8 failures and 7 errors. Also, do a better job of recovering from failures in setUp(). MailList.__new__() now takes keyword arguments. ................ r8117 | bwarsaw | 2006-12-11 22:58:06 -0500 (Mon, 11 Dec 2006) | 7 lines Unit test repairs; even though the unit tests are still pretty fragile, everything now passes with the SQLAlchemy storage of list data. Added missing 'personalize' column. Converted mailmanctl and qrunner to initialize() interface. Fixed _cookie_path() to not fail if SCRIPT_NAME is not in the environment. ................ r8118 | bwarsaw | 2006-12-27 18:45:41 -0500 (Wed, 27 Dec 2006) | 21 lines Utils.list_names(): Use a database query to get all the list names. dbcontext.py: Added api_get_list_names() to support Utils.list_names(). listdata.py: Added two additional MailList attributes which need to be stored in the database. The first is 'admin_member_chunksize' which isn't modifiable from the web. The second is 'password' which holds the list's password. HTMLFormatObject: item strings can now be unicodes. bin/list_lists.py: Must call initialize() to get the database properly initialized, not just config.load(). This will be a common theme. SecurityManager.py: - Remove md5 and crypt support - Added mailman.debug logger, though it will be only used during debugging. - The 'secret' can be a unicode now. - A few coding style updates; repr() instead of backticks, 'key in dict' instead of 'dict.has_key(key)' ................ r8119 | bwarsaw | 2006-12-27 19:13:09 -0500 (Wed, 27 Dec 2006) | 2 lines genaliases.py: config.load() -> initialize() ................ r8120 | bwarsaw | 2006-12-27 19:17:26 -0500 (Wed, 27 Dec 2006) | 9 lines Blocked revisions 8113 via svnmerge ........ r8113 | bwarsaw | 2006-12-05 23:54:30 -0500 (Tue, 05 Dec 2006) | 3 lines Initialized merge tracking via "svnmerge" with revisions "1-8112" from https://mailman.svn.sourceforge.net/svnroot/mailman/branches/tmp-sqlalchemy-branch ........ ................ r8121 | bwarsaw | 2006-12-28 23:34:52 -0500 (Thu, 28 Dec 2006) | 20 lines Remove SIGTERM handling from all the CGI scripts. This messes with HTTPRunner because when you issue "mailmanctl stop" after the signal handler has been installed, the process will get a SIGTERM, the signal handler will run, and the process will exit with a normal zero code. This will cause mailmanctl to try to restart the HTTPRunner. I don't think we need that stuff at all when running under wsgi with a SQLAlchemy backend. If mailmanctl kills the HTTPRunner in the middle of the process, I believe (but have not tested) that the transaction should get properly rolled back at process exit. We need to make sure about this, and also we need to test the signal handling functionality under traditional CGI environment (if we even still want to support that). Also, make sure that we don't try to initialize the loggers twice in qrunner. This was the cause of all the double entries in logs/qrunner. Fix a coding style nit in mailmanctl.py. De-DOS-ify line endings in loginit.py. ................
* Postfix LMTP related brushups.tkikuchi2006-11-261-12/+33
| | | | | | | | | | | | | | - Configurable no-list error. - Ultimate loop stop address in transport -> aliases. - LMTP_ONLY_DOMAIN needs no individual transport entry. - Use of alias/lmtp is exclusive. WSGI brushups. - _cookie_path() was made simple and retain common cookie for admin/admindb/... etc. - Removed absolute=1 from admindb/confirm/create/options. configuration.py - Use of add_runner() in etc/mailman.cfg needs change. config is not loaded yet?
* Some cleanups of code.tkikuchi2006-11-231-36/+24
| | | | | | | - if config.USE_LMTP immediately after ALIASFILE add/remove; we need to keep alias settings because postfix rejects as unknown if not present. - STANZA listname@hostname. - convert tabs to spaces.
* Repair a problem with cookie paths reported by Tokio when HTTPRunner is usedbwarsaw2006-10-301-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | but a reverse proxy maps our wsgiref server into an upstream server's web space. Here's the basic problem: the Set-Cookie header we return has a Path attribute which must match subsequent request uri's in order for the client to send the cookie data back to us later in a Cookie header of that subsequent request. The problem though is that we cannot guarantee that we know how our wsgi server is mapped into the upstream proxy. It's probably '/mailman/' for backward compatibility, but there's no way for us to tell, because there's nothing specifically included in the request that tells us what the originally requested uri is. If we get the cookie path wrong, the effect is to require a login every time an admin page is hit, because the client will not see a matching path prefix and will not send us the cookie data. We solve this (albeit, by hack) by looking at the HTTP_REFERER environment variable we see. This will point to the admin login page on which the admin password was entered. We'll pick this uri apart to attempt to find the prefix at which our wsgi server was mapped. If we find this, we'll use it to craft an appropriate cookie path. Hopefully. If that cgi environment variable is not available, we just return the path as we've seen it. This approach allows for accessing the admin pages either through a reverse proxy or directly, with no additional configuration necessary. In fact, both access mechanisms can work at the same time; try hitting these two uri's with different browsers: http://example.com/mailman/admin/mylist@example.com/general http://example.com:2580/admin/mylist@example.com/general The first will hit our reverse proxy, and the second will hit our wsgi server directly. The responses will included two different cookie paths, but both will work! This is an important principle to uphold, especially for debugging purposes. Note that I could have added a configuration variable to handle the cookie path remapping, but then we'd have to support either the reverse proxy or the wsgi server, but not (easily) both. Plus, it's another configuration variable. Yuck. Note that Apache 2.2 has something called the ProxyPassReverseCookiePath directive, which should probably be used if available. It's not in Apache 2.0, which is probably the most prevalent server in use with Mailman right now, so we can't count on it. Plus, if ProxyPassReverseCookiePath is available, our algorithm should still work. What about other proxy servers? Dunno. We'll have to wait for feedback from users. This change also fixes a buglet with MTA/Postfix.py when POSTFIX_STYLE_VIRTUAL_DOMAINS is used. You can end up trying to call _update_maps() before data/aliases exist. This just defers that call until it's guaranteed both the transport and the alias files have been created. Also, finish converting SecurityManager.py to use the configuration object (and the Defaults module where appropriate) instead of mm_cfg.py.
* Postfix support functions for LMTP and configurations.tkikuchi2006-10-021-1/+53
|
* Here are the patches needed in order to create new lists on my testtkikuchi2006-09-281-2/+10
| | | | | | | installation. I've tested four cases of combination of POSTFIX_STYLE_VIRTUAL_DOMAINS (Any/None) and USE_MAIL_DIR (Yes/No). Also, I've added POSTFIX_VIRTUAL_SEPARATOR = '_at_' for unique mapping of local part in the virtual-mailman/aliases files.
* Convert genaliases to mmshell, optparse, and configuration.configbwarsaw2006-09-251-14/+14
| | | | | | | | | | | | | | | | bin/withlist: If there's no '@' in the listname, append the DEFAULT_EMAIL_HOST so we always get a fully qualified list name. bin/mmsitepass: plumb through -C/--config switch and be sure to call config.load(). Convert Mailman/MTA/Postfix.py to configuration.config, and update MTA/Manual. In mailman/Cgi/create, we can't convert straight from a string to a bool, because bool('0') is True. We need to go through int first. MailList.InitTempVars(): The logic here looked weird because we could get 'name' = None and that would break. Assume name is never None.
* Fix some buglets with virtual domain support and repair unit tests broken bybwarsaw2006-07-081-2/+2
| | | | | | | | | | | | | | | | | | | | | | | this change. More unit tests should be added. misc/sitelist.cfg is removed -- this is an ex-site list. MailList.GetNoReplyEmail() -> MailList.no_reply_address (property) UserNotification._enqueue(), OwnerNotification._enqueue(): when queing the message to the virgin queue, be sure to use the fully qualified (i.e. posting) address for the list. In the MTA modules, be sure to set up the target of the mail commands as the fqdn listname because otherwise we can't find the correct list. This needs some tweaking/testing for Postfix's virtual domain support. MailList.Load() has to grow an optional argument specifying the fqdn listname. The problem is that in some situations, we can't calculate that because we don't know _internal_name, so it has to be passed in. This is mostly the case in the MailList ctor where a Load hasn't happened yet. For backward compatibility though, if it's not passed in, just use mlist.fqdn_listname.
* First crack at real virtual domain support, i.e. mailing lists with the samebwarsaw2006-07-081-5/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | name in more than one domain. - Totally eradicate MAILMAN_SITE_LIST, and in fact the entire need for a site list. The functions that the site list previously performed are either removed or supported in other ways. For example, instead of forwarding owner bounces to the site list, we now have a SITE_OWNER_ADDRESS which should point to a human, and such bounces are sent there instead. There's also a "no reply" email address that should be set up to go to devnull. For any message that never expects a reply, the sender is set to this address. - Remove the Site.py module. It was an experimental approach to trying to support virtual domains, and we're going to do it so much better now that this module is no longer necessary. Site._makedirs() -> Utils.makedir(). - VIRTUAL_HOST_OVERVIEW is completely removed, since now virtual hosts are always enabled. Virtual domains should be added to mailman.cfg by using the new add_domain() function. add_virtualhost() is gone. If no virtual domains are added explicitly, we add the default one that configure guessed (but we never add that if domains are added explicitly). - Utils.get_domain() -> Utils.get_request_domain() - withlist code cleanup and make sure that we load etc/mailman.cfg - A new base exception called MailmanException is added, from which all exceptions defined in Errors.py ultimately derive. MailmanError is retained and derives from MailmanException. - BadDomainSpecificationError is added. - Remove the -V/--virtual-host-overview option from list_lists and add instead -d/--domain and -f/--full. - bin/update probably works but needs more testing. - bin/newlist and bin/rmlist take fqdn list names, but default to the default domain if @whatever isn't given. newlist's -u/--urlhost and -e/--emailhost options are removed. The domain that the list is being added to must already exist. - Minor code cleanup in Message.py - Bump version to 2.2.0a1 - The Configuration object grows a .domain dictionary which maps email hosts to url hosts. The reverse mapping is supported, but not directly; use Configuration.get_email_host() instead. - Mailman/Cgi/create is converted from mm_cfg to config, and some minor code cleanup is performed. Also, convert to __i18n_templates__ = True. - New MailList APIs: + property .fqdn_listname + GetNoReplyEmail() + Create() API changes and refactoring.
* - Convert all logging to Python's standard logging module. Get rid of allbwarsaw2006-04-171-7/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | traces of our crufty old Syslog. Most of this work was purely mechanical, except for: 1) Initializing the loggers. For this, there's a new module Mailman/loginit.py (yes all modules from now on will use PEP 8 names). We can't call this 'logging.py' because that will interfere with importing the stdlib module of the same name (can you say Python 2.5 and absolute imports?). If you want to write log messages both to the log file and to stderr, pass True to loginit.initialize(). This will turn on propagation of log messages to the parent 'mailman' logger, which is set up to print to stderr. This is how bin/qrunner works when not running as a subprocess of mailmanctl. 2) The driver script. I had to untwist the StampedLogger stuff and implement differently printing exceptions and such to log/error because standard logging objects don't have a write() method. So we write to a cStringIO and then pass that to the logger. 3) SMTPDirect.py because of the configurability of the log messages. This required changing SafeDict into a dict subclass (which is better than using UserDicts anyway -- yay Python 2.3!). It's probably still possible to flummox things up if you change the name of the loggers in the SMTP_LOG_* variables in mm_cfg.py. However, the worst you can do is cause output to go to stderr and not go to a log file. Note too that all entry points into the Mailman system must call Mailman.loginit.initialize() or the log output will go to stderr (which may occasionally be what you want). Currently all CGIs and qrunners should be working properly. I wish I could have tested all code paths that touch the logger, but that's infeasible. I have tested this, but it's possible that there were some mistakes in the translation. - Mailman.Bouncers.BounceAPI.Stop is a singleton, but not a class instance any more. - True/False code cleanup, PEP 8 import restructuring, whitespace normalization, and copyright year updates, as appropriate.
* Now that Python 2.3 is the minimum requirement for Mailman 2.2:bwarsaw2006-04-151-12/+7
| | | | | | | | | | | - Remove True/False binding cruft - Remove __future__ statements for nested scopes - Remove ascii_letters import hack from Utils.py - Remove mimetypes.guess_all_extensions import hack from Scrubber.py - In Pending.py, set _missing to object() (better than using []) Also, update copyright years where appropriate, and re-order imports more to my PEP 8 tastes. Whitespace normalize.
* Port cleaning changes forward from 2.1-maint branch.bwarsaw2005-12-301-4/+4
|
* SF bug tracker 1378270. Fix aliases permission check in Postfix.py.tkikuchi2005-12-131-1/+10
| | | | Documents will be checked in later for MAIN.
* FSF office has moved. chdcking in for MAIN branch.tkikuchi2005-08-271-1/+1
|
* Back out last patch -- the real fix should be to the documentation.bwarsaw2003-09-141-4/+1
|
* _addvirtual(): Steve Alexander's patch to include the "hostnamebwarsaw2003-09-131-1/+4
| | | | | IGNORED" line, which may be redundant, but doesn't seem to cause harm, and may help some sites.
* create(): Add a `quiet' flag which (for this MTA at least) is ignored.bwarsaw2003-03-221-14/+20
| | | | Use True/False where appropriate.
* _do_remove(): Patch by Jon Parise to fix a bug in the stanza matchingbwarsaw2003-01-021-3/+3
| | | | | | code which would delete any list with a matching prefix (i.e. "bin/rmlist foo" would also delete the stanza for "foo-one" and "foo-two").
* Patch set for SF bug #596565. Use symbolic user/group names insteadbwarsaw2002-08-231-8/+12
| | | | | | | | | | of numeric ids. Initial idea and patch by Todd Vierling, fleshed out by Barry. Specific changes here: checkperms(): Use MAILMAN_USER instead of MAILMAN_UID and getpwnam() and getgrnam() where appropriate.
* _check_for_virtual_loopaddr(): Fixed this so duplicate virtual hostbwarsaw2002-03-051-5/+22
| | | | | | | | | | loop addresses don't get written. _do_create(): Fixed this so that the check for loop addrs happens after the original files get closed (otherwise they'd be zero lengthed). Also, fixed some formatting issues.
* checkperms(): Fix this for the new files aliases and virtual-mailman.bwarsaw2002-03-011-33/+43
|
* _addlist(): Do some better formatting. -unsubscribe is now thebwarsaw2002-02-231-2/+2
| | | | longest alias. Also, there's no need to add 1 to the field size.
* clear(): Fix the file names given to _zapfile().bwarsaw2002-02-141-2/+2
|
* Massive simplification to avoid making all the BerkeleyDB callsbwarsaw2002-02-091-155/+62
| | | | | | | | | | | | | | | | | | | | | ourselves. Given the incompatible state of BDB libraries on most modern Linux distros, and given the sorry state of affairs in Python's BDB wrappers, this is the only sensible solution. Essentially, I've kept all the plain text (data/aliases and data/virtual-mailman) update code, and then we just call postalias and postmap on the files to get the .db counterparts regenerated. This should be foolproof since only Postfix itself needs to use consistent libraries -- attempting to match Postfix and Python would be a nightmare. I don't believe we're opening ourselves up to any vulnerabilities by using os.system() in this case. Also: all functions which are not meant to be part of the public MTA interface are now prefixed by a single underscore. I'm too tired to give detailed changes...
* Sigh. I think BerkeleyDB support is just plain broken in standardbwarsaw2001-12-241-1/+9
| | | | | | | Python. Fall back to the PyBSDDB module (a.k.a. bsddb3) if bsddb fails. Note to self: we need to fix the BerkeleyDB module for Python 2.3.
* Updates to work better with virgin invocation.bwarsaw2001-12-061-23/+33
| | | | | | | | | | | | | | | | | _zapfile(), _zapdb(): Only truncate the file if it already exists (so we don't accidently create it before we're ready to). addlist(): Make this robust for when mlist == None, as it will when there are no lists yet, but we want the preamble and minimal aliases and aliases.db files to get created. Moved the YP_* key settings up before the predicate shortcircuit. do_create(): Do the hashopen() before the built-in open() so it gets created properly by bsddb when it doesn't yet exist. create(): Check for mlist == None before digging out more attributes. Also, rewrote the big comment at the top concerning locking.
* Much changes for better virtual domain support.bwarsaw2001-11-261-33/+88
| | | | | | | | | | | | | | - Import bsddb directly instead of dbhash - delete virtual_files() - _zapfile(), _zapdb(): New internal function - clear(): New public function for clearing out both the plain text files and the db files. - addlist(), and friends: better support for writing virtual alias entries based on the value of POSTFIX_STYLE_VIRTUAL_DOMAINS.
* Support for Postfix-style virtual domains.bwarsaw2001-11-241-33/+105
| | | | | | | | | | | | | | | | | virtual_files(): Return the .db filename and text filename based on the host_name. addlist(): Some generalizations for the writing of the site list's loop entry. addvirtual(): Implements writing the virtual file plain text and dbhash files. do_create(), create(): Reorg to call both addlist() and addvirtual() if necessary. do_remove(), remove(): Reorg so that both the entries from the aliases file and the virtual file will be removed.
* addlist(): When creating the aliases file for the first time, be surebwarsaw2001-11-201-1/+7
| | | | | | | | | | | to write out the mailman-loop address which is used to consume all messages sent to the mailman-owners address that bounces. This is now the best way to break bounce loops. All mail to mailman-loop@dom.ain will get appended to an mbox file called $prefix/data/owner-bounces.mbox. Similarly, make sure the mailman-loop address is in the database.
* addlist(): Don't rely on the brilliant new feature in Python 2.1, wheretwouters2001-08-111-1/+1
| | | | the argument to time.ctime() defaults to 'the current time'.
* checkperms(): 'mode' -> 'stat[ST_MODE]'.twouters2001-07-101-1/+1
| | | | | | Slight style nit, too: code is using 'oct()' to convert mode to a string, instead of a '0%(mode)o' format. Changing this to make more sense would break translations, though :P
* create(), remove(): Take an optional flag `cgi' which indicatesbwarsaw2001-05-221-2/+2
| | | | | whether this is being invoked through-the-web (ttw). This is required by the API but ignored by the functions in this module.
* checkperms(): aliases.db should be owned by mailman now, not root.bwarsaw2001-05-111-2/+2
|
* create(), remove(): Before we write to the aliases.db file, we mustbwarsaw2001-05-111-2/+47
| | | | | | drop an exclusive advisory lock on it, so Postfix doesn't try to read the file while we're updating it. See the comment at the top of the file for a discussion of why we have to do this so cruftily.
* List creation/removal hooks now keep both the plain text filebwarsaw2001-05-101-29/+120
| | | | | | | | | | | | | | | | | | | | | | | | `aliases' and dbhash file `aliases.db' in sync. Specifically, _addlist() => addlist() _rmlist(): Removed. addlist(): This now takes both a dbhash file and a file pointer to the plain text file and adds the new list entries into both. If the plain text file is empty (seek to end, tell() == 0), then an informative comment is added to the top. In the plain text file, `stanza' marker comments are used around the list alias entries. A trailing blank line is always added after the stanza. create(): This is now just a wrapper for addlist() (since addlist() is now used by bin/genaliases). remove(): Does the bulk of what _rmlist() used to do, plus it keeps the plain text file in sync. It searches for the appropriate stanza marker and removes every line between it and the stanza end marker. (Actually, it does this by copying to a tmp file and shuffling the tmp file to the real file.)
* checkperms(): Postfix-specific permission checks: make sure thebwarsaw2001-05-091-2/+48
| | | | | aliases.db file is perm'd 066x and that it's owned by root. The group-ownership by mailman is already checked by check_perms.
* intermediatebwarsaw2001-05-091-1/+0
|
* Checking in the usual .cvsignore, Makefile.in, and __init__.py files.bwarsaw2001-05-091-0/+74
Also, Postfix.py which contains the Postfix-specific code to run when creating or removing a mailing list.