141 Commits

Author SHA1 Message Date
alexhudson 629034815d Tagging 0.3.1 release 2008-02-02 16:30:43 +00:00
alexhudson 09405d9e83 Tweak version number for 0.3.1 2008-02-02 16:28:52 +00:00
alexhudson 2fd6ea3402 Merge post-release fixes from trunk in preperation for 0.3.1. This covers r611:619 2008-02-02 15:42:41 +00:00
alexhudson 924bff9489 Minor changes to make 0.3.0 releasable 2008-01-31 09:34:30 +00:00
alexhudson 068c0aa700 Branching trunk for M3 2008-01-29 18:46:58 +00:00
jonnylamb 09a199e94b Fixed path handling in Sundial. This makes Evolution and Sundial work again. 2008-01-29 18:42:43 +00:00
alexhudson 6cccc8a82b * check for lxml, but don't fail if it's not found
* make the end output slightly more consistent
2008-01-29 13:51:15 +00:00
alexhudson 3de6d55404 Partial fix for POP3 TOP command - bug #10918 2008-01-29 12:01:21 +00:00
alexhudson 5b672baffd * Make bongo-config output less geek when you run it
* Remove bongo-calcmd from the default configuration
2008-01-29 10:52:18 +00:00
alexhudson 542e5aab8d Remove calcmd agent from the build 2008-01-29 10:51:41 +00:00
alexhudson 113dbce285 Fix segfault in bongocollector agent due to change in MsgAuthUserList API 2008-01-29 10:36:53 +00:00
alexhudson 4d1e47dcad Remove legacy bongo-setup application 2008-01-29 10:18:56 +00:00
alexhudson 60073c01ec Fix build system for import clucene/sqlite3 on clean svn check-outs 2008-01-29 10:03:44 +00:00
alexhudson 233fee2c29 Remove mdbtool and some last cruft 2008-01-28 18:53:06 +00:00
jonnylamb 0223238bb8 Updated bongo-config man page. 2008-01-28 18:40:35 +00:00
alexhudson 238fa58cdc New exciting 'list user' functionality! 2008-01-28 17:45:00 +00:00
alexhudson 81d9301e0d Initial changes to auth to stop duplicate user accounts being registered. auth api needs a bit of a clean-up; too many changes :) 2008-01-28 11:35:27 +00:00
pfelt afc9a21829 -- hopefully this will fix the odd bug where we think there is a loop in the aliasing when there is not. 2008-01-27 17:27:28 +00:00
alexhudson 85bbccebb7 Fix up two JS errors which get the composer working again 2008-01-24 08:59:39 +00:00
alexhudson d337c3d486 Merge remove-mdb branch onto trunk, branch is now closed! 2008-01-23 08:20:27 +00:00
pfelt 39d68be761 -- apply r513 and r514 to the trunk. i apologize if this messes anything up when we go to merge branch! 2007-10-23 16:05:33 +00:00
alexhudson 88f5d2eafd Make autogen/configure fail if we're using plain CLucene on x86_64 2007-10-05 20:48:48 +00:00
alexhudson 1c9d457e50 Fix potential segfault in smtpd 2007-09-17 13:45:20 +00:00
halex e7e3999b8a Woops. 2007-09-11 08:42:13 +00:00
halex 29743facc4 * Use same quote colours throughout all conversations and replies.
* Can be manually overridden by browser using alternate stylesheet delerations - eg: .mailreply-1 { color: black !important; }
2007-09-10 11:12:23 +00:00
alexhudson 204abc232d Fix up some DNS packet boundary checking 2007-09-06 16:28:06 +00:00
alexhudson bf0efbcb3e Don't try to redeliver failed/delivered mail 2007-09-05 14:33:33 +00:00
alexhudson 2d889da6ba New smtp outgoing mail code 2007-09-05 12:08:33 +00:00
halex 54c24172d7 Fixes the new-user issues (with regards to composition) that crept into the code since the last 'fix'. At least, I think it does. 2007-08-30 07:33:45 +00:00
halex 8bd7e42e98 * Updated a considerable number of icons to gnome-icon-theme icons. These are under the GPL. Gifs still need to be updated.
* Removed some old toolbar icons, that were unused.
* Added 'switch-mode.png' for composer toolbar.
* Removed toolbar-seperator.png image, which was also unused.
2007-08-29 10:25:11 +00:00
halex 98359611ea * Don't warn about missing attachments when we try and save a draft, only when we want to actually send the mail.
* If we're sending plain-text, strip the HTML entities on the client side before giving the data to the server.
* Noted an issue (TODO) with regards to not being able to set the composer to contain text on-load (ie signature, editing a reply etc).
* We now handle the HTML->text conversion properly - no more missing new lines.
* Removed some unused functions in the eArea code.
* Stopped us from failing is the user is missing prefs (specifically, any composer preferences).
2007-08-27 02:21:39 +00:00
halex 55a32cd4e7 * Removed some old cruft relating to some AttachmentForm done as a test from many a year ago.
* Small misc. fixups.
* If you mention attaching a file in your email (not in replies) and haven't actually attached any files, Dragonfly'll give you a hint when you try to send.
2007-08-26 03:53:20 +00:00
halex 701525175d Line width and composition mode are both now controlled via user preferences, instead of being hardwired. 2007-08-26 02:41:00 +00:00
halex 51a8b612db Wooh, preference editor! \o/ 2007-08-26 00:54:28 +00:00
halex 35526da57b Some more preference bug fixes. Saving preferences using a blocking method doesn't quite work yet. 2007-08-25 08:58:23 +00:00
jonnylamb 4252a2496d Fixes to build system, so not only does it build, but it also creates the MO files correctly now. 2007-08-24 17:32:22 +00:00
jonnylamb f9be78b58a Rename compiled translation files from *.gmo, to *.mo. These are identical in type except extension. It seems *.mo is more the industry standard (also on request from Trisk). 2007-08-24 11:24:04 +00:00
alexhudson 5b388b76f4 Make Bongo compile again for dist users 2007-08-20 08:34:04 +00:00
halex 22741b815e Some small preferences fix ups! profileEditor is still completely and royally screwed up, however. 2007-08-20 08:13:35 +00:00
alexhudson 1fc05b93c7 Slightly more honest message in tool output 2007-08-18 08:48:55 +00:00
alexhudson e13eeb8e3a Another attempt at stopping SIGPIPEs killing our agents. 2007-08-17 20:34:08 +00:00
alexhudson cc9178ccd6 Missed a file for r355 :) 2007-08-17 20:20:36 +00:00
alexhudson 698cda51d7 Initial stab at DNS code, including:
* new check tool for querying MX records,
* dns test harness
2007-08-17 20:11:44 +00:00
alexhudson a05bf36889 Don't try to access part of a variable if we don't know it's actually set. 2007-08-14 11:52:03 +00:00
alexhudson aa8cdd6ab0 Ignore SIGPIPE on broken connection. This should fix/mitigate bug #9726. 2007-08-14 10:20:51 +00:00
halex c7ad8f8df2 Adds the ability to switch between HTML and text-based composition.
Three notes: all the HTML buttons are still available when you're in plain-text mode; we don't check your prefs as to what default composer mode you'd like; and line breaks are a bit whacky when you switch modes (I think :).
Please expect and report breakage.
2007-08-14 07:53:13 +00:00
alexhudson 6ce6bd184f * Fix up the check system so that we can run unit tests again
* Start new dns bits to Xpl with tests
2007-08-08 19:49:13 +00:00
alexhudson 95aa64d386 Remove python/bongo/Makefile, stops dist tarballs building. 2007-07-31 08:55:39 +00:00
halex 3b1507bc7b Users without a valid From name doesn't crash the composer anymore. This really doesn't fix any 'problem' with prefs, more of a workaround. 2007-07-31 07:54:07 +00:00
halex 2d37fb62db Note to self: mistakenly serialising page elements is bad. 2007-07-30 09:34:38 +00:00
halex 5eb4f67e99 * Fixes the User-Agent from mails sent via Dragonfly.
* Adds a new HTML composer - plain-text does not work at the moment.
* Adds plugins code; note that this is not hooked up _at all_, I was just merely too lazy to checkout a clean version, modify the patch, apply and commit. This will be *sure to change very soon*.
2007-07-28 10:28:56 +00:00
alexhudson cb74eae670 Correct file closing logic for QRETR 2007-07-27 17:06:03 +00:00
alexhudson 9c52b028ae Missed initializing a file handle, oops 2007-07-27 16:22:58 +00:00
alexhudson 785476ba0f Even more stringent file checking in the queue 2007-07-27 16:01:37 +00:00
trisk da1c898909 * Add rule for missing src/libs/python/bongo/Makefile.
* Don't remove bongo-python-wrapper in clean, it's generated by config.status.
2007-07-26 13:35:00 +00:00
trisk f37e40d9aa * Fix some obvious bugs in smtpd's remote host resolution. 2007-07-26 13:31:26 +00:00
alexhudson c8f9670d70 Fixed a bug in a temporary file handle, and made the file open/close checks more correct 2007-07-26 10:38:10 +00:00
halex 50617cbc10 Un-breaks the composer. Requires you RE-SAVE YOUR PREFS. 2007-07-26 09:25:18 +00:00
alexhudson a289b56729 Remove some DMC cruft we missed 2007-07-25 20:20:29 +00:00
alexhudson 8ed1e89fe1 A couple of compiler blatherings fixed. 2007-07-25 19:50:19 +00:00
alexhudson ce0211995d Instrument the queue with some file checking. 2007-07-25 19:46:18 +00:00
alexhudson 05e8852440 Minor logic nit in assertion :D 2007-07-25 19:45:49 +00:00
alexhudson deb78542ce smtp now correctly logs, slight change to API used in queue 2007-07-25 18:01:27 +00:00
alexhudson cf114834d9 Put some logging and assertions into the queue 2007-07-25 17:37:14 +00:00
alexhudson 5878c5116e Another attempt at detecting the CLucene API "correctly" 2007-07-25 16:31:43 +00:00
alexhudson 18441d2231 Hopefully get the API right on more versions of clucene 2007-07-24 22:42:16 +00:00
halex f5b85d0515 Fixes the From: address with a sender name specified in the preferences. 2007-07-23 10:44:32 +00:00
halex fbde82b235 * Fix logged out message.
* Dragonfly version is now 'M3' in SVN, not SVN r2483+.
* Added popup-hide handler (isn't hooked up yet).
* Removed FakeFriendPopup - wasn't used.
* Removed 'This is Me'.
* We now have a user profile in preferences.
* Cleaned up a bit of the Prefs builder, including translated and clickable labels.
2007-07-21 06:02:55 +00:00
dostrow 168af364e8 * Add support for importing maildir format mailboxes in bongo-storetool with the new -t flag
* Add support for importing to collections other then /mail/INBOX with the new -f flag
* Add support for exporting to both maildir and mbox format
* Split the old mail-store subcommand into mail-import (mi) and mail-export (me)
2007-07-20 17:31:21 +00:00
halex bbdfc1d6e3 Fixes the Big Cheese (aka bug #9541). 2007-07-19 11:51:30 +00:00
alexhudson b901178411 Disable outgoing TLS in SMTP, causes bug #9536. 2007-07-18 19:32:48 +00:00
alexhudson cc2146f14b Two fixes to python errors preventing logins 2007-07-18 11:31:11 +00:00
jonnylamb d81014a674 * Added support to Dragonfly preferences to determine how many items to be shown on a mail list view. This first tries to use the DF pref from the store, but if that cannot be used/is invalid then it falls back on ConversationsHandler.defaultPageSize, which is set to 30.
* Started documenting variables and methods in ConversationsHandler using Doxygen syntax.
2007-07-16 23:05:45 +00:00
halex 38b5be0c8d * More colors! :)
* Don't hide the logged out message after loading language.
* Colorise quotes in emails.
2007-07-16 06:50:16 +00:00
halex b186eca218 No more crazy composer POST loops! \o/ 2007-07-16 04:59:25 +00:00
halex 9010d916ab * More noop translations for set names in Mail view.
* It helps to store the pageSize value, you know!
* Update Dragonfly.go so that we check both the handler AND the tab for a getData(loc) function.
* Fixed up MailListView and co. so that we do what pageSize says, not anything else.
  |- Server side still has troubles with values besides 30. No touchy.
2007-07-16 02:40:01 +00:00
alexhudson 79673b9d1b Slightly naughty config fix to make dist work again, and update a python rule 2007-07-15 22:31:31 +00:00
halex 8d72093cd6 * Added ability to adjust default calendar view in Preferences.
* Changed one of my 'bad translation ways' - we now use d.format instead for Logout link.
* Even more event arg bug fixes - this one closes bug #9408.
* We now perform a noop/lazy/late translation for mailbox labels (drafts, sent, inbox etc).
2007-07-15 08:58:13 +00:00
halex 012f72a874 More composer fixes. 2007-07-15 02:24:29 +00:00
halex 97eb5c1356 Remove all reminants of old i10n labels. 2007-07-15 01:58:01 +00:00
trisk 5f533850e0 * Align hashtable entries correctly so that Python modules don't crash! 2007-07-15 01:42:22 +00:00
trisk 6a1aa7b881 * Doh, malloc is not calloc! >< 2007-07-14 18:18:58 +00:00
trisk 1d3b79c1e2 * Prevent potential free of static string. 2007-07-14 18:17:10 +00:00
alexhudson c8d8cdaf9a Fix a lookup table in the mdb-xldap MDB driver, fixes managed-ldap 2007-07-14 11:31:58 +00:00
halex bd5e101f5f * Some more translation string fixups - Prefs, DateTime entry, Calendars.
* Translated most of the Preferences dialog.
* Changed behaviour of untitled conversations in composer - we now call them 'Untitled' (translatable) if there's no subject when we try to save to backend.
* Neater signature stuff.
2007-07-14 10:50:13 +00:00
jonnylamb 968577911d * Move to a more unified python www system. Instead of components being used in both DF and HE calling bongo.dragonfly methods, these "commonweb" things have been moved into bongo.commonweb.
* Removed bongo.admin.BongoSession as bongo.commonweb.BongoSession  is more developed.
* The Auth and *{Handler,Path} modules should probably be merged across DF and HE next, but have been lleft separate foor this commit, for now.
2007-07-13 22:58:05 +00:00
alexhudson a913e011c4 Correct(?!) dist and inst rules for config files and sets 2007-07-13 22:35:08 +00:00
alexhudson d3ddf20189 Friendly-looking Python patch which should clear up lib vs. lib64 issues on RH-type distros 2007-07-13 22:06:45 +00:00
alexhudson fb042f0ac5 Scary looking python patch; separate the C-module stuff from pure python for the benefit of OSes which keep them separately. 2007-07-13 21:17:21 +00:00
alexhudson 1764749c58 Stop Lucene crashing on x86_64 (import only, sadly...), and 'make clean' works again 2007-07-13 16:34:13 +00:00
trisk ba713d88e0 * Go over mdbldap and fix at least a dozen memory leaks. 2007-07-13 15:57:13 +00:00
halex 17eefc5a79 More language fixups (specifically the error on login). 2007-07-13 12:52:17 +00:00
halex 305477029b Fixes unescaped translation string which caused Dragonfly to go haywire (especially the compiled version, which didn't load at all). 2007-07-13 12:19:03 +00:00
jonnylamb 78d49fd7a8 Little fix to make po2json a little more flexible when building. Oh, and removing that horrible temporary line that was meant for me only.. 2007-07-13 11:50:14 +00:00
jonnylamb 1fd6ff820c Update build rules to point to $lang.js, instead of $lang.json. 2007-07-13 11:32:37 +00:00
jonnylamb 9370449931 Remove src/www/l10n/dragonfly.properties from dist_noinst_DATA. 2007-07-13 11:15:57 +00:00
jonnylamb 1de36a6c67 Changed $lang.json to $lang.js, to be more correct. Or, to be correct in the first place. 2007-07-13 10:59:12 +00:00
jonnylamb 67c91f6090 * Change l10n stuff in Dragonfly from labels to strings. This is all Alex Hixon's work.
* Alex also added a different gettext scheme to use the po/ system as opposed to the dragonfly.properties file.
* I have added a po2json script. This uses polib to take strings out of /po/bongo-web.pot and create a json file.
* Currently a few issues are here though:
  + src/www/js/JCal.js is commented out in po/POTFILES.bongo-web because it's creating errors of some charset or something when 'make update-pot' is called. This should be resolved shortly.
  + The po2json script is absolutely disgusting at the moment. It works, but the source is in need of a little cleanup. This should also be rather quick and easy to cut-down.
  + I have edited src/www/js/Gettext.js to use a different directory from what is desired. Ultimately, /l10n/$lang/LC_MESSAGES/dragonfly.js will be used, but at the moment, /l10n/$lang.js is being used. This is also another TODO thing..
  + It currently doesn't work. No joke. This is some JS-issue. However, it pretty much does work if you're using English because now that all gettext msgids are now strings, and not labels, DF falls back on them, and all is fine. There are just some warnings spaffed out on the logs and on the login screen.
  + I have just seen that I made a silly mistake in configure.ac. I'll fix that on the next commit, in a few seconds..
So, please do not try out this commit (or the next) unless your name is Alexander Hixon.
2007-07-13 10:57:11 +00:00
alexhudson c2fbb8f61e Look harder for SQLite libraries on 64bit RH-type distros 2007-07-12 22:28:23 +00:00
trisk 4b0476a596 * Unbreak BongoJsonParserNextNode - leak was actually caused by missing frees.
* Apparent double free in ReadBongoConfiguration (should only BongoJsonNodeFree() parent node, not BongoJsonJPath() node).
2007-07-12 21:45:15 +00:00
alexhudson ca45b1417f * Hopefully the 'dist' is correct again with new config files
* Look for CLucene in 64bit locations on RH-type distros
2007-07-12 21:13:03 +00:00
trisk 8d1f10ad98 * Memory leak in BongoJsonParserNextNode() - duplicated string at return.
* Memory leak in LdapToRelativeMdb() - forgot to free string.
2007-07-12 20:53:52 +00:00
jonnylamb 277769e69d Add directory that SVN previously didn't. Apparently it was already under revision control.. *sigh* 2007-07-12 13:29:36 +00:00
jonnylamb 8ea2a88dcc * Added another gettext package: bongo-web. This is for Dragonfly+Hawkeye translations. The old bongo package remains. This is for the core of Bongo, for example the CLI apps.
* Made the po/ system more flexible. Simply drop a .po file in either po/bongo/ or po/bongo-web/ and everything's done for you.
* Fixed a dirty hack about dist_noinst_DATA. $POFILES was being used ~2000 lines before being set. Thiss is now set much earlier on, from configure.ac.
* POTFILES.in split into .bongo and .bongo-web for the respective gettext package.
2007-07-12 13:15:48 +00:00
alexhudson 41ed4dedc7 Small fix to stop cmuser module leaking handles to a directory 2007-07-12 09:42:13 +00:00
halex ace52e75c4 * New compression code.
* Compression of CSS is now also performed.
* Javascript compression works again - we save about 1/3 bandwidth.
2007-07-12 07:17:11 +00:00
trisk a30612eac7 * Add missing IDs to "small mode" menu.
* Anchor new event popup correctly in "small mode".
2007-07-11 21:46:02 +00:00
alexhudson 25f1a34250 * Update default config for antivirus and antispam
* Hopefully corrected a config bug where we crash on malformed json data
2007-07-11 21:40:55 +00:00
trisk 2bb2877866 * Make avirus crash a bit less. 2007-07-11 20:59:10 +00:00
trisk 9fb528dd0e * default.set should depend on config files. 2007-07-11 20:43:22 +00:00
trisk f9f0282aa0 (Hopefully) fix more issues in new config code. 2007-07-11 19:52:32 +00:00
alexhudson af379dd929 Another way of invoking tar :) 2007-07-11 19:51:16 +00:00
trisk 2e706f5349 Don't crash if parts of schema are missing. 2007-07-11 18:28:31 +00:00
trisk 9816a936e2 Clean up sketchy parts of the store. 2007-07-11 17:58:45 +00:00
alexhudson 4973b31a27 More compatible tar invocation 2007-07-11 16:55:25 +00:00
alexhudson 2963a454c7 * New configuration system
* Default config now comes from a backup file, not hard-coded
2007-07-11 12:11:55 +00:00
halex 8559b8bdb8 * /me is starting to hate Composer.js
* Fixes both Send (save draft first) and Save Draft (trying to assign message to event - similar issue found in Addressbook.Contacts) on Composer view.
2007-07-11 10:51:40 +00:00
halex 58564815a6 * When searching for contacts, provide a ContactPopup, rather than a link to the contact's conversations.
* Get's rid of a minor niggle with 'html' being undefined at login screen.
2007-07-11 07:25:30 +00:00
halex 65a20db8f9 * Entering data into the Subject field in the composer updates the title.
* When we dispose of the Preferences editor, send the user back to whatever page they were on before, not just summary.
2007-07-11 05:53:12 +00:00
trisk f4b73dc601 * Previous message link in conversation always points to first message.
* Tweak composer, make discarding a message go to the previous location.
2007-07-11 05:30:58 +00:00
halex a7af92dcc5 Finally, no more composer scrolling issues! \o/ 2007-07-11 03:27:11 +00:00
halex ff3ec35d27 * Small touchup in compiled Dragonfly HTML to stop search box and button touching.
* Textarea style does not inherit non-monospace fonts (only from browser).
* We now have signature support!
* Ability to adjust items per page in mail list view.
2007-07-11 01:47:59 +00:00
halex 68e73006b5 * Put the links for compiled/uncompiled Dragonfly in the wrong place.
* When we discard a draft, don't bomb out if we try and delete something that didn't exist
* More preference changes - new fields are yet to be hooked up.
* Fixes the scrollable composer window problem.
2007-07-11 00:54:52 +00:00
trisk 01d7e89470 * final.js needs to update when its components change. 2007-07-10 17:08:02 +00:00
trisk 60fdae4c69 * Actually print to the buffer in LoggerOpen(). 2007-07-10 15:23:14 +00:00
alexhudson e355a6fb18 Turn on logging! Thanks to Lance Haig for figuring most of this out. Includes:
* Lance's configuration file
* Small changes to log4c and slapd to make them shut up a bit
2007-07-10 13:21:19 +00:00
jonnylamb 1641302e0d Fixes to the po/ build system. Thanks to Daniel Ostrow for this. 2007-07-10 09:41:10 +00:00
halex d4d0629203 * Speedups in the HTML dept.
* We now have a 'debug' version of Dragonfly.
2007-07-10 09:37:42 +00:00
halex 1a59960bd9 Reset back to no compression, just (in theory) cat-ting the files together. 2007-07-10 06:57:55 +00:00
halex 087ab3dcb5 Hopefully makes standalone composer scrollable. 2007-07-10 05:17:14 +00:00
halex d59c6e89ff Wrong order of script.aculo.us includes. 2007-07-10 03:32:27 +00:00
halex afa1db57b0 * Speeds up Dragonfly load times (a lot). 2007-07-10 01:25:40 +00:00
trisk e52ab32f26 * Fix crash in bongoimap - session->user.name is only set after UserLogin(). 2007-07-09 17:18:17 +00:00
trisk 145b53ca2c * Correct bongo-manager pid file formatting.
* Fix bongo-setup pid handling (thanks to Chris Lamb!).
2007-07-09 15:13:01 +00:00
trisk b6001cdb0b * Use slapdadd (same binary as slapd and has a configurable path) instead of ldapdd in bongo-setup.
* Use Privs module functions for Bongo user.
2007-07-09 15:10:59 +00:00
alexhudson 014f94da0d 'make distclean' fix for po/ files 2007-07-08 19:57:27 +00:00
trisk 1e573957ef Generate a Message-Id if the an email did not include one, to prevent crashing the store on import. 2007-07-08 12:30:04 +00:00
alexhudson 8826f58c02 Some .gmo install rule fixes 2007-07-08 10:00:19 +00:00
alexhudson 741331701e Fix search for clucene-config.h file on self-compiled CLucene install (thanks to dostrow) 2007-07-08 09:14:34 +00:00
halex 9def52095f * Got rid of SummaryView.py (didn't actually do anything)
* Hooray for breadcrumbs!
2007-07-08 01:38:00 +00:00
trisk 26471cf430 Doh. 2007-07-08 00:25:57 +00:00
70 changed files with 14439 additions and 4668 deletions
+2 -9
View File
@@ -89,10 +89,7 @@ clean: clean-recursive
# disabled agents
# src/agents/mailprox
# src/agents/rules
# src/libs/mdb
# src/libs/mdb-file
# src/libs/mdb-xldap
# src/agents/calcmd
include_subdirs = \
include \
@@ -118,7 +115,6 @@ include_subdirs = \
src/agents/alarm \
src/agents/antispam \
src/agents/avirus \
src/agents/calcmd \
src/agents/collector \
src/agents/generic \
src/agents/imap \
@@ -155,9 +151,6 @@ include src/libs/bongoutil/tests/Bongo.rules
include src/libs/connio/Bongo.rules
include src/libs/connio/tests/Bongo.rules
include src/libs/json/Bongo.rules
#include src/libs/mdb/Bongo.rules
#include src/libs/mdb-file/Bongo.rules
#include src/libs/mdb-xldap/Bongo.rules
include src/libs/logger/Bongo.rules
include src/libs/streamio/Bongo.rules
include src/libs/streamio/codec/Bongo.rules
@@ -172,7 +165,7 @@ include src/libs/python/libbongo/Bongo.rules
include src/agents/alarm/Bongo.rules
include src/agents/antispam/Bongo.rules
include src/agents/avirus/Bongo.rules
include src/agents/calcmd/Bongo.rules
#include src/agents/calcmd/Bongo.rules
include src/agents/collector/Bongo.rules
include src/agents/generic/Bongo.rules
include src/agents/imap/Bongo.rules
+9 -12
View File
@@ -347,10 +347,16 @@ fi
for arg in $@; do
case $arg in
--with-clucene=*import*)
rm -f import/clucene/NO-AUTO-GEN
;;
--with-clucene=*)
touch import/clucene/NO-AUTO-GEN
echo "Flagging import/clucene as no auto-gen as source is external"
;;
--with-sqlite3=*import*)
rm -f import/sqlite3/NO-AUTO-GEN
;;
--with-sqlite3=*)
touch import/sqlite3/NO-AUTO-GEN
echo "Flagging import/sqlite3 as no auto-gen as source is external"
@@ -450,18 +456,9 @@ done
rm -f import/clucene/NO-AUTO-GEN
rm -f import/sqlite3/NO-AUTO-GEN
SVNREV="`svnversion . 2>/dev/null`"
if test x$SVNREV = x; then
echo Unable to discern build version
echo \#define BONGO_BUILD_BRANCH \"unknown\" > ./include/bongo-buildinfo.h
echo \#define BONGO_BUILD_VSTR \"\" >> ./include/bongo-buildinfo.h
echo \#define BONGO_BUILD_VER \"0\" >> ./include/bongo-buildinfo.h
else
echo SVN Rev at $SVNREV
echo \#define BONGO_BUILD_BRANCH \"trunk\" > ./include/bongo-buildinfo.h
echo \#define BONGO_BUILD_VSTR \"r\" >> ./include/bongo-buildinfo.h
echo \#define BONGO_BUILD_VER \"$SVNREV\" >> ./include/bongo-buildinfo.h
fi
echo \#define BONGO_BUILD_BRANCH \"0.3\" > ./include/bongo-buildinfo.h
echo \#define BONGO_BUILD_VSTR \"v\" >> ./include/bongo-buildinfo.h
echo \#define BONGO_BUILD_VER \"0\" >> ./include/bongo-buildinfo.h
conf_flags="--enable-maintainer-mode"
+32 -15
View File
@@ -3,7 +3,7 @@ AC_PREREQ(2.52)
AC_INIT(src/libs/msgapi/msgapi.c)
AM_INIT_AUTOMAKE(bongo, 0.1.0)
AM_INIT_AUTOMAKE(bongo, 0.3.1)
# this space is here to trick autogen.sh
AM_GNU_GETTEXT([external])
@@ -329,11 +329,11 @@ if test "x$PKG_CONFIG" = "xno"; then
fi
have_check=no
info_check="Not installed. Unit tests will not be run."
info_check="No. Unit tests will not be run."
AM_PATH_CHECK(0.9.0,
[
have_check=yes
info_check="Installed. Unit tests may be run."
info_check="Yes."
AC_DEFINE(BONGO_HAVE_CHECK, [], [Controls how tests that depend on check compile.])
],
[
@@ -384,8 +384,10 @@ import lxml.etree as et
if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC
then
AC_MSG_RESULT([Found ElementTree lxml])
info_lxml="Yes."
else
AC_MSG_ERROR([Couldn't find ElementTree lxml module for python])
AC_MSG_RESULT([Couldn't find ElementTree lxml module for python])
info_lxml="No. CalDAV runtime requires this library"
fi
LIBS_save="$LIBS"
@@ -619,9 +621,19 @@ fi
# import libraries
ACX_CLUCENE()
if test "x$CLUCENE_LIBS" = "x"; then
case "x$CLUCENE_LIBS" in
x)
info_clucene="import"
;;
*import*)
info_clucene="import"
;;
*)
info_clucene="system"
;;
esac
if test "x$info_clucene" = "ximport"; then
AC_MSG_RESULT(Using imported CLucene)
info_clucene="import"
AC_CONFIG_SUBDIRS([import/clucene])
AC_SUBST(CLUCENE_BONGO_API, "1")
AC_SUBST(CLUCENE_LIBS, "\$(top_srcdir)/import/clucene/src/libclucene.la")
@@ -631,19 +643,27 @@ else
AC_MSG_ERROR([Compiling against CLucene system libraries on x86_64 is known to be buggy. Recommend you use --with-clucene=import/clucene])
fi
AC_MSG_RESULT(Using system CLucene)
info_clucene="system"
fi
AC_CHECK_SQLITE3()
if test "x$SQLITE_LIBS" = "x"; then
case "x$SQLITE_LIBS" in
x)
info_sqlite="import"
;;
*import*)
info_sqlite="import"
;;
*)
info_sqlite="system"
;;
esac
if test "x$info_sqlite" = "ximport"; then
AC_MSG_RESULT(Using imported SQLite)
info_sqlite="import"
AC_CONFIG_SUBDIRS([import/sqlite3])
AC_SUBST(SQLITE_CFLAGS, "-I\$(top_srcdir)/import/sqlite3")
AC_SUBST(SQLITE_LIBS, "\$(top_srcdir)/import/sqlite3/libbongosqlite3.la")
else
AC_MSG_RESULT(Using system SQLite)
info_sqlite="system"
fi
info_libical="import"
@@ -662,10 +682,7 @@ ac_configure_args="$ac_configure_args --enable-threadsafe --enable-cross-thread-
# src/agents/mailprox/Makefile
# src/agents/rules/Makefile
# src/agents/pluspack/Makefile
#src/libs/mdb/Makefile
#src/libs/mdb-file/Makefile
#src/libs/mdb-xldap/Makefile
# src/agents/calcmd/Makefile
AC_OUTPUT([
Makefile
@@ -684,7 +701,6 @@ init/svc-bongo.solaris-smf
src/agents/alarm/Makefile
src/agents/antispam/Makefile
src/agents/avirus/Makefile
src/agents/calcmd/Makefile
src/agents/collector/Makefile
src/agents/generic/Makefile
src/agents/imap/Makefile
@@ -751,4 +767,5 @@ Optional libraries:
LDAP: ${info_ldap}
ODBC: ${info_odbc}
Check: ${info_check}
lxml: ${info_lxml}
])
+4 -1
View File
@@ -36,8 +36,10 @@ EXPORT BOOL MsgAuthVerifyPassword(const char *user, const char *password);
EXPORT int MsgAuthChangePassword(const char *user, const char *oldpassword, const char *newpassword);
EXPORT int MsgAuthSetPassword(const char *user, const char *password);
EXPORT int MsgAuthGetUserStore(const char *user, struct sockaddr_in *store);
EXPORT int MsgAuthInitDB(void);
EXPORT int MsgAuthInitDB(void);
EXPORT int MsgAuthAddUser(const char *user);
EXPORT int MsgAuthUserList(char **list[]);
EXPORT void MsgAuthUserListFree(char **list[]);
// Auth / cookie functions
@@ -123,6 +125,7 @@ int MsgSQLBindString(MsgSQLStatement *stmt, int var, const char *str, BOOL nulli
int MsgSQLExecute(MsgSQLHandle *handle, MsgSQLStatement *_stmt);
int MsgSQLResults(MsgSQLHandle *handle, MsgSQLStatement *_stmt);
void MsgSQLFinalize(MsgSQLStatement *stmt);
int MsgSQLStatementStep(MsgSQLHandle *handle, MsgSQLStatement *_stmt);
// Misc. util functions
+12
View File
@@ -14,7 +14,19 @@ on execution to specify its action.
.TP
.BR \-v ", " \-\^\-verbose
Show verbose output.
.TP
.BR \-s ", " \-\^\-silent
Non-interactive mode.
.SH COMMANDS
.BI "user add " USER
Add a user to the system.
.TP
.BR "user list"
List the users on the system.
.TP
.BI "user password " USER
Set the password of
.I USER
.TP
.BR install
Do the initial Bongo install.
+35
View File
@@ -0,0 +1,35 @@
# -*- Makefile -*-
cmmoduledir = $(libdir)/connmgr
cmmodule_LTLIBRARIES :=
sbin_PROGRAMS += bongoconnmgr
bongoconnmgr_SOURCES := \
src/agents/connmgr/connmgr.c \
src/agents/connmgr/connmgrp.h \
src/agents/connmgr/modules.c
bongoconnmgr_LDADD := \
libbongomanagement.la \
libbongomsgapi.la \
libbongomdb.la \
libbongologger.la \
libbongoconnio.la \
libbongomemmgr.la \
libbongoutil.la \
libbongoxpl.la \
$(top_builddir)/import/log4c/log4c/libbongolog4c.la \
$(SQLITE_LIBS) \
$(PTHREAD_LIBS) \
$(ALL_LIBS)
src/agents/connmgr/all: bongoconnmgr \
src/agents/connmgr/cmmodules/rbl/all \
src/agents/connmgr/cmmodules/rdns/all \
src/agents/connmgr/cmmodules/user/all \
src/agents/connmgr/cmmodules/lists/all
src/agents/connmgr/clean: clean
src/agents/connmgr/install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) sbin_PROGRAMS=bongoconnmgr \
install-sbinPROGRAMS install-cmmoduleLTLIBRARIES
@@ -0,0 +1,19 @@
# -*- Makefile -*-
cmmodule_LTLIBRARIES += libcmlists.la
libcmlists_la_SOURCES := \
src/agents/connmgr/cmmodules/lists/cmlists.c \
src/agents/connmgr/cmmodules/lists/cmlists.h
libcmlists_la_LDFLAGS := -module -avoid-version
libcmlists_la_LIBADD := \
libbongomsgapi.la \
libbongologger.la \
libbongomemmgr.la \
libbongomdb.la \
libbongoxpl.la \
$(PTHREAD_LIBS) \
$(ALL_LIBS)
src/agents/connmgr/cmmodules/lists/all: libcmlists.la
src/agents/connmgr/cmmodules/lists/clean: clean
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
@@ -0,0 +1,350 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include "cmlists.h"
/* Globals */
BOOL ListUnloadOk = TRUE;
ListGlobal List;
static BOOL ReadConfiguration(void);
EXPORT int ListsVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
unsigned long i;
/* Check Allowed List */
if ((XplStrCaseCmp(command->event, CM_EVENT_RELAY) == 0) || (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0)) {
for (i = 0; i < List.allowed.count; i++) {
if ((List.allowed.start[i] <= (long) command->address) && ((long) command->address <= List.allowed.end[i])) {
/* We like the guy */
return(CM_MODULE_ACCEPT | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
}
}
}
/* Check Blocked List */
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
for (i = 0; i < List.blocked.count; i++) {
if ((List.blocked.start[i] <= (long) command->address) && ((long) command->address <= List.blocked.end[i])) {
/* We don't like the guy */
return(CM_MODULE_DENY | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
}
}
}
return(0);
}
EXPORT BOOL
CMLISTSInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (ListUnloadOk == TRUE) {
XplSafeWrite(List.threadCount, 0);
List.directoryHandle = (MDBHandle) MsgInit();
if (List.directoryHandle) {
ListUnloadOk = FALSE;
List.logHandle = LoggerOpen("cmlist");
if (List.logHandle == NULL) {
XplConsolePrintf("cmlist: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 1; /* It is important that the lists are early */
registration->Shutdown = ListsShutdown;
registration->Verify = ListsVerify;
registration->Notify = NULL;
XplSafeIncrement(List.threadCount);
strcpy(List.config.datadir, datadir);
return(ReadConfiguration());
} else {
XplConsolePrintf("cmlist: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
static void
AddBlockedAddress(const unsigned char *AddressStart, const unsigned char *AddressEnd)
{
if ((List.blocked.count + 1) > List.blocked.allocated) {
List.blocked.start = MemRealloc(List.blocked.start, (List.blocked.allocated + 5) * sizeof(unsigned long));
List.blocked.end = MemRealloc(List.blocked.end, (List.blocked.allocated + 5) * sizeof(unsigned long));
if (!List.blocked.start || !List.blocked.end) {
LoggerEvent(List.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, ((List.blocked.allocated+5) + (List.blocked.allocated+5)) * sizeof(unsigned long), __LINE__, NULL, 0);
return;
}
List.blocked.allocated += 5;
}
if ((List.blocked.start[List.blocked.count] = inet_addr(AddressStart)) != -1) {
List.blocked.start[List.blocked.count] = ntohl(List.blocked.start[List.blocked.count]);
if ((List.blocked.end[List.blocked.count] = inet_addr(AddressEnd)) != -1) {
List.blocked.end[List.blocked.count] = ntohl(List.blocked.end[List.blocked.count]);
List.blocked.count++;
}
}
}
static void
FreeBlockedAddresses(void)
{
if (List.blocked.start) {
MemFree(List.blocked.start);
}
List.blocked.start = NULL;
if (List.blocked.end) {
MemFree(List.blocked.end);
}
List.blocked.end = NULL;
List.blocked.allocated = 0;
List.blocked.count = 0;
}
static void
AddAllowedAddress(const unsigned char *AddressStart, const unsigned char *AddressEnd)
{
if ((List.allowed.count + 1) > List.allowed.allocated) {
List.allowed.start = MemRealloc(List.allowed.start, (List.allowed.allocated + 5) * sizeof(unsigned long));
List.allowed.end = MemRealloc(List.allowed.end, (List.allowed.allocated + 5) * sizeof(unsigned long));
if (!List.allowed.start || !List.allowed.end) {
LoggerEvent(List.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, ((List.allowed.allocated+5) + (List.allowed.allocated+5)) * sizeof(unsigned long), __LINE__, NULL, 0);
return;
}
List.allowed.allocated += 5;
}
if ((List.allowed.start[List.allowed.count] = inet_addr(AddressStart)) != -1) {
List.allowed.start[List.allowed.count] = ntohl(List.allowed.start[List.allowed.count]);
if ((List.allowed.end[List.allowed.count] = inet_addr(AddressEnd)) != -1) {
List.allowed.end[List.allowed.count] = ntohl(List.allowed.end[List.allowed.count]);
List.allowed.count++;
}
}
}
static void
FreeAllowedAddresses(void)
{
if (List.allowed.start) {
MemFree(List.allowed.start);
}
List.allowed.start = NULL;
if (List.allowed.end) {
MemFree(List.allowed.end);
}
List.allowed.end = NULL;
List.allowed.allocated = 0;
List.allowed.count = 0;
}
EXPORT BOOL
ListsShutdown(void)
{
XplSafeDecrement(List.threadCount);
if (ListUnloadOk == FALSE) {
ListUnloadOk = TRUE;
/*
Make sure the library lists are gone before beginning to
shutdown.
*/
while (XplSafeRead(List.threadCount)) {
XplDelay(33);
}
LoggerClose(List.logHandle);
FreeBlockedAddresses();
FreeAllowedAddresses();
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(List.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(List.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(List.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
const unsigned char *Address;
MDBEnumStruct *e;
unsigned char *ptr;
config = MDBCreateValueStruct(List.directoryHandle, MsgGetServerDN(NULL));
e = MDBCreateEnumStruct(config);
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
ListsShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_CONFIG_CHANGED, config)) {
List.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
List.config.last = 0;
}
while ((Address = MDBReadEx(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_BLOCKED_ADDRESS, e, config)) != NULL) {
ptr = strchr(Address, '-');
if (ptr) {
*ptr = '\0';
AddBlockedAddress(Address, ptr + 1);
*ptr = '-';
} else {
AddBlockedAddress(Address, Address);
}
}
MDBFreeValues(config);
while ((Address = MDBReadEx(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_ALLOWED_ADDRESS, e, config)) != NULL) {
ptr = strchr(Address, '-');
if (ptr) {
*ptr = '\0';
AddAllowedAddress(Address, ptr + 1);
*ptr = '-';
} else {
AddAllowedAddress(Address, Address);
}
}
MDBFreeValues(config);
MDBDestroyEnumStruct(e, config);
MDBDestroyValueStruct(config);
if (List.blocked.count == 0 && List.allowed.count == 0) {
#if VERBOSE
XplConsolePrintf("cmlists: No addresses blocked or allowed\n");
#endif
ListsShutdown();
return(FALSE);
}
return(TRUE);
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
ListShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(List.tgid);
if (ListUnloadOk == FALSE) {
ListUnloadOk = TRUE;
/*
Make sure the library lists are gone before beginning to
shutdown.
*/
while (XplSafeRead(List.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(List.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(List.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(List.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(List.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (ListUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
List.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper List Module");
XplOpenLocalSemaphore(List.shutdownSemaphore, 0);
XplSignalHandler(ListShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(List.shutdownSemaphore);
XplSignalLocalSemaphore(List.shutdownSemaphore);
return(0);
}
@@ -0,0 +1,73 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmlist.nlm"
#define PRODUCT_NAME "Bongo Connection Manager Block and Allow List Module"
typedef struct _ListGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
unsigned char datadir[XPL_MAX_PATH + 1];
} config;
struct {
long *start;
long *end;
unsigned long count;
unsigned long allocated;
} blocked;
struct {
long *start;
long *end;
unsigned long count;
unsigned long allocated;
} allowed;
} ListGlobal;
extern ListGlobal List;
/* cmlist.c */
void ListShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMLISTSInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL ListsShutdown(void);
EXPORT int ListsVerify(ConnMgrCommand *command, ConnMgrResult *result);
@@ -0,0 +1,23 @@
# -*- Makefile -*-
cmmodule_LTLIBRARIES += libcmrbl.la
libcmrbl_la_SOURCES := \
src/agents/connmgr/cmmodules/rbl/cmrbl.c \
src/agents/connmgr/cmmodules/rbl/cmrbl.h
libcmrbl_la_CPPFLAGS := $(AM_CPPFLAGS) \
$(SQLITE_CFLAGS)
libcmrbl_la_LDFLAGS := -module -avoid-version
libcmrbl_la_LIBADD := \
libbongomsgapi.la \
libbongologger.la \
libbongomemmgr.la \
libbongomdb.la \
libbongoxpl.la \
$(SQLITE_LIBS) \
$(PTHREAD_LIBS) \
$(ALL_LIBS)
src/agents/connmgr/cmmodules/rbl/all: libcmrbl.la
src/agents/connmgr/cmmodules/rbl/clean: clean
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
+495
View File
@@ -0,0 +1,495 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include <sqlite3.h>
#include "cmrbl.h"
/* Globals */
BOOL RBLUnloadOk = TRUE;
RBLGlobal RBL;
static BOOL ReadConfiguration(void);
EXPORT int RBLVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
unsigned long i;
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
XplDnsRecord *dns = NULL;
BOOL blocked = FALSE;
int rc = -1;
int commentID = -1;
/* Check for a cached value */
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
sqlite3_bind_int(RBL.sqlite.stmt.get, 1, command->address);
if ((rc = sqlite3_step(RBL.sqlite.stmt.get)) == SQLITE_ROW) {
blocked = sqlite3_column_int(RBL.sqlite.stmt.get, 0);
strncpy(result->comment, sqlite3_column_text(RBL.sqlite.stmt.get, 1), sizeof(result->comment));
}
sqlite3_reset(RBL.sqlite.stmt.get);
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
if (rc != SQLITE_ROW) {
/* Perform the RBL check */
for (i = 0; i < RBL.rbl.count; i++) {
unsigned char buffer[MAXEMAILNAMESIZE];
struct in_addr ip;
ip.s_addr = command->address;
/* address is in host byte order. RBL checks require least significant first. */
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.%s",
ip.s_net,
ip.s_host,
ip.s_lh,
ip.s_impno,
RBL.rbl.hosts[i]);
rc = XplDnsResolve(buffer, &dns, XPL_RR_A);
if (dns) {
MemFree(dns);
}
if (rc == XPL_DNS_SUCCESS) {
blocked = TRUE;
commentID = RBL.rbl.ids[i];
strncpy(result->comment, RBL.rbl.comments[i], sizeof(result->comment));
continue;
}
}
/* Store new value */
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
/*
Insert the new value into the table. The time for a negative result is a
full day. The time for a positive result is only 15 minutes however,
because a positive result simply means that the servers do not know anything
about the address.
*/
sqlite3_bind_int(RBL.sqlite.stmt.add, 1, command->address);
sqlite3_bind_text(RBL.sqlite.stmt.add, 2, blocked ? RBL.config.blockTimeout : RBL.config.allowTimeout, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(RBL.sqlite.stmt.add, 3, blocked);
sqlite3_bind_int(RBL.sqlite.stmt.add, 4, commentID);
sqlite3_step(RBL.sqlite.stmt.add);
sqlite3_reset(RBL.sqlite.stmt.add);
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
}
if (blocked) {
/* He was blocked by RBL */
return(CM_MODULE_DENY | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
} else {
/* He was not blocked, don't force it though */
return(CM_MODULE_ACCEPT);
}
}
return(0);
}
static void
TransactionController(void *ignored)
{
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
if (sqlite3_exec(RBL.sqlite.handle, SQL_BEGIN, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrbl: Failed to start transaction controller\n");
}
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
while (!RBLUnloadOk) {
unsigned long i;
for (i = 0; i < 15 && !RBLUnloadOk; i++) {
XplDelay(1000);
}
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
if (sqlite3_exec(RBL.sqlite.handle, SQL_SAVE, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrbl: Failed to save cache data\n");
}
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
}
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
if (sqlite3_exec(RBL.sqlite.handle, SQL_END, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrbl: Failed to end transaction controller\n");
}
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
}
EXPORT BOOL
CMRBLInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (RBLUnloadOk == TRUE) {
XplSafeWrite(RBL.threadCount, 0);
RBL.directoryHandle = (MDBHandle) MsgInit();
if (RBL.directoryHandle) {
RBLUnloadOk = FALSE;
RBL.logHandle = LoggerOpen("cmrbl");
if (RBL.logHandle == NULL) {
XplConsolePrintf("cmrbl: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 1; /* It is important that the rbl are early */
registration->Shutdown = RBLShutdown;
registration->Verify = RBLVerify;
registration->Notify = NULL;
XplSafeIncrement(RBL.threadCount);
strcpy(RBL.config.datadir, datadir);
XplOpenLocalSemaphore(RBL.sqlite.semaphore, 1);
if (ReadConfiguration()) {
unsigned char buffer[XPL_MAX_PATH + 1];
int ccode;
XplThreadID id;
sqlite3_stmt *stmt;
sqlite3_stmt *stmt2;
unsigned long i;
snprintf(buffer, sizeof(buffer), "%s/cache.db", datadir);
if (sqlite3_open(buffer, &RBL.sqlite.handle) != SQLITE_OK) {
printf("cmrbl: Failed to open database: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
}
if (sqlite3_exec(RBL.sqlite.handle, SQL_CREATE, NULL, NULL, NULL) != SQLITE_OK) {
#if 0
printf("bongogatekeeper: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
#endif
sqlite3_exec(RBL.sqlite.handle, SQL_ROLLBACK, NULL, NULL, NULL);
}
if ((sqlite3_prepare(RBL.sqlite.handle, SQL_ADD, -1, &RBL.sqlite.stmt.add, 0) != SQLITE_OK) ||
(sqlite3_prepare(RBL.sqlite.handle, SQL_GET, -1, &RBL.sqlite.stmt.get, 0) != SQLITE_OK) ||
(sqlite3_prepare(RBL.sqlite.handle, SQL_CLEAN, -1, &RBL.sqlite.stmt.clean,0) != SQLITE_OK))
{
printf("cmrbl: Failed to prepare sql: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
}
/* Cleanup */
sqlite3_exec(RBL.sqlite.handle, SQL_COMMENTS_CLEAN1, NULL, NULL, NULL);
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_CLEAN2, -1, &stmt, 0);
for (i = 0; i < RBL.rbl.count; i++) {
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
sqlite3_exec(RBL.sqlite.handle, SQL_COMMENTS_CLEAN3, NULL, NULL, NULL);
/* Ok, add any new ones */
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_ADD, -1, &stmt, 0);
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_UPDATE, -1, &stmt2, 0);
for (i = 0; i < RBL.rbl.count; i++) {
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, RBL.rbl.comments[i], -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) != SQLITE_DONE) {
/* It is already there, so just update the comment in case it changed */
sqlite3_bind_text(stmt2, 1, RBL.rbl.comments[i], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt2, 2, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
sqlite3_step(stmt2);
sqlite3_reset(stmt2);
}
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
sqlite3_finalize(stmt2);
/* Get the IDs for them */
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_GET_ID, -1, &stmt, 0);
for (i = 0; i < RBL.rbl.count; i++) {
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) == SQLITE_ROW) {
RBL.rbl.ids[i] = sqlite3_column_int(RBL.sqlite.stmt.get, 0);
} else {
RBL.rbl.ids[i] = -1;
}
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
/* Begin the transaction controller thread */
XplBeginThread(&id, TransactionController, (1024 * 32), NULL, ccode);
return(TRUE);
}
} else {
XplConsolePrintf("cmrbl: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
EXPORT BOOL
RBLShutdown(void)
{
XplSafeDecrement(RBL.threadCount);
if (RBLUnloadOk == FALSE) {
unsigned long i;
RBLUnloadOk = TRUE;
/*
Make sure the library rbl are gone before beginning to
shutdown.
*/
while (XplSafeRead(RBL.threadCount)) {
XplDelay(33);
}
LoggerClose(RBL.logHandle);
sqlite3_finalize(RBL.sqlite.stmt.add);
sqlite3_finalize(RBL.sqlite.stmt.get);
sqlite3_finalize(RBL.sqlite.stmt.clean);
sqlite3_close(RBL.sqlite.handle);
XplCloseLocalSemaphore(RBL.sqlite.semaphore);
for (i = 0; i < RBL.rbl.count; i++) {
MemFree(RBL.rbl.hosts[i]);
MemFree(RBL.rbl.comments[i]);
}
if (RBL.rbl.hosts) {
MemFree(RBL.rbl.hosts);
}
if (RBL.rbl.comments) {
MemFree(RBL.rbl.comments);
}
if (RBL.rbl.ids) {
MemFree(RBL.rbl.ids);
}
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RBL.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RBL.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
config = MDBCreateValueStruct(RBL.directoryHandle, MsgGetServerDN(NULL));
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
RBLShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_CONFIG_CHANGED, config)) {
RBL.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
RBL.config.last = 0;
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_RBL_HOST, config) > 0) {
unsigned long i;
for (i = 0; i < RBL.rbl.count; i++) {
MemFree(RBL.rbl.hosts[i]);
MemFree(RBL.rbl.comments[i]);
}
if (RBL.rbl.hosts) {
MemFree(RBL.rbl.hosts);
}
if (RBL.rbl.comments) {
MemFree(RBL.rbl.comments);
}
if (RBL.rbl.ids) {
MemFree(RBL.rbl.ids);
}
RBL.rbl.count = config->Used;
RBL.rbl.hosts = MemMalloc(config->Used * sizeof(char *));
RBL.rbl.comments = MemMalloc(config->Used * sizeof(char *));
RBL.rbl.ids = MemMalloc(config->Used * sizeof(long));
if (!RBL.rbl.hosts || !RBL.rbl.comments || !RBL.rbl.ids) {
LoggerEvent(RBL.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, config->Used * sizeof(char *) * 2, __LINE__, NULL, 0);
} else {
for (i = 0; i < RBL.rbl.count; i++) {
unsigned char *ptr = strchr(config->Value[i], ';');
if (ptr) {
ptr[0] = '\0';
}
RBL.rbl.hosts[i] = MemStrdup(config->Value[i]);
if (ptr) {
RBL.rbl.comments[i] = MemStrdup(ptr + 1);
} else {
RBL.rbl.comments[i] = MemMalloc(sizeof(BLOCKED_STRING) + strlen(RBL.rbl.hosts[i]));
sprintf(RBL.rbl.comments[i], BLOCKED_STRING, RBL.rbl.hosts[i]);
}
LoggerEvent(RBL.logHandle, LOGGER_SUBSYSTEM_CONFIGURATION, LOGGER_EVENT_CONFIGURATION_STRING, LOG_INFO, 0, "MSGSRV_A_RBL_HOST", config->Value[i], 0, 0, NULL, 0);
}
}
MDBFreeValues(config);
}
/*
Store the timeout strings. It is faster to do this once, instead of storing the long value
and creating the string each time, since it must be a string that is bound to the SQL statement.
*/
snprintf(RBL.config.blockTimeout, sizeof(RBL.config.blockTimeout), "%d minutes", (24 * 60)); /* Default to 1 day for a block */
snprintf(RBL.config.allowTimeout, sizeof(RBL.config.blockTimeout), "%d minutes", 15); /* Default to 15 minutes for allow */
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_CONFIGURATION, config) > 0) {
unsigned long i;
for (i = 0; i < config->Used; i++) {
if (XplStrNCaseCmp(config->Value[i], BLOCK_TIMEOUT_PREFIX, sizeof(BLOCK_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RBL.config.blockTimeout, sizeof(RBL.config.blockTimeout), "%lu minutes", atol(config->Value[i] + sizeof(BLOCK_TIMEOUT_PREFIX) - 1));
} else if (XplStrNCaseCmp(config->Value[i], ALLOW_TIMEOUT_PREFIX, sizeof(ALLOW_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RBL.config.allowTimeout, sizeof(RBL.config.allowTimeout), "%lu minutes", atol(config->Value[i] + sizeof(ALLOW_TIMEOUT_PREFIX) - 1));
}
}
}
MDBDestroyValueStruct(config);
if (RBL.rbl.count == 0) {
#if VERBOSE
XplConsolePrintf("cmrbl: No RBL zones configured. RBL check is disabled.\n");
#endif
RBLShutdown();
return(FALSE);
}
return(TRUE);
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
RBLShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(RBL.tgid);
if (RBLUnloadOk == FALSE) {
RBLUnloadOk = TRUE;
/*
Make sure the library rbl are gone before beginning to
shutdown.
*/
while (XplSafeRead(RBL.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(RBL.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RBL.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RBL.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (RBLUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
RBL.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper RBL Module");
XplOpenLocalSemaphore(RBL.shutdownSemaphore, 0);
XplSignalHandler(RBLShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore);
XplSignalLocalSemaphore(RBL.shutdownSemaphore);
return(0);
}
+123
View File
@@ -0,0 +1,123 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <sqlite3.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmrbl.nlm"
#define PRODUCT_NAME "Bongo Connection Manager RBL Module"
#define BLOCKED_STRING "Blocked by RBL %s"
typedef struct _RBLGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
unsigned char datadir[XPL_MAX_PATH + 1];
unsigned char blockTimeout[256];
unsigned char allowTimeout[256];
} config;
struct {
unsigned char **hosts;
unsigned char **comments;
unsigned long *ids;
unsigned long count;
unsigned long allocated;
} rbl;
struct {
sqlite3 *handle;
XplSemaphore semaphore;
struct {
sqlite3_stmt *add;
sqlite3_stmt *get;
sqlite3_stmt *clean;
} stmt;
} sqlite;
} RBLGlobal;
extern RBLGlobal RBL;
/* cmrbl.c */
void RBLShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMRBLInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL RBLShutdown(void);
EXPORT int RBLVerify(ConnMgrCommand *command, ConnMgrResult *result);
/* Config Prefixes */
#define BLOCK_TIMEOUT_PREFIX "RBLBlockTimeout:"
#define ALLOW_TIMEOUT_PREFIX "RBLAllowTimeout:"
/* SQL */
#define SQL_CREATE "BEGIN TRANSACTION;" \
"CREATE TABLE cache (" \
"ip INTEGER PRIMARY KEY NOT NULL," \
"timeout DATETIME," \
"block BOOL," \
"commentID INTEGER" \
");" \
"CREATE TABLE comments (" \
"key INTEGER PRIMARY KEY AUTOINCREMENT," \
"zone TEXT UNIQUE," \
"comment TEXT," \
"keep BOOL default 1" \
");" \
"CREATE INDEX timeout_idx ON cache (timeout);" \
"CREATE INDEX comment_idx ON cache (commentID);"\
"END TRANSACTION;"
#define SQL_ROLLBACK "ROLLBACK;"
#define SQL_ADD "INSERT OR REPLACE INTO cache (ip, timeout, block, commentID) VALUES (?, DATETIME('now', ?), ?, ?);"
#define SQL_GET "SELECT cache.block, comments.comment FROM cache INNER JOIN comments ON cache.commentID=comments.key WHERE ip=? AND julianday('now') < julianday(timeout);"
#define SQL_CLEAN "DELETE FROM cache WHERE julianday('now') >= julianday(timeout);"
#define SQL_BEGIN "BEGIN TRANSACTION;"
#define SQL_END "END TRANSACTION;"
#define SQL_SAVE SQL_CLEAN SQL_END SQL_BEGIN
#define SQL_COMMENTS_CLEAN1 "UPDATE comments SET keep=0;"
#define SQL_COMMENTS_CLEAN2 "UPDATE comments SET keep=1 WHERE zone=?;"
#define SQL_COMMENTS_CLEAN3 "DELETE FROM comments WHERE keep=0"
#define SQL_COMMENTS_ADD "INSERT INTO comments (zone, comment) VALUES (?, ?);"
#define SQL_COMMENTS_UPDATE "UPDATE comments SET comment=? WHERE zone=?;"
#define SQL_COMMENTS_GET_ID "SELECT key FROM comments WHERE zone=?;"
@@ -0,0 +1,23 @@
# -*- Makefile -*-
cmmodule_LTLIBRARIES += libcmrdns.la
libcmrdns_la_SOURCES := \
src/agents/connmgr/cmmodules/rdns/cmrdns.c \
src/agents/connmgr/cmmodules/rdns/cmrdns.h
libcmrdns_la_CPPFLAGS := $(AM_CPPFLAGS) \
$(SQLITE_CFLAGS)
libcmrdns_la_LDFLAGS := -module -avoid-version
libcmrdns_la_LIBADD := \
libbongomsgapi.la \
libbongologger.la \
libbongomemmgr.la \
libbongomdb.la \
libbongoxpl.la \
$(SQLITE_LIBS) \
$(PTHREAD_LIBS) \
$(ALL_LIBS)
src/agents/connmgr/cmmodules/rdns/all: libcmrdns.la
src/agents/connmgr/cmmodules/rdns/clean: clean
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
+360
View File
@@ -0,0 +1,360 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include <sqlite3.h>
#include "cmrdns.h"
/* Globals */
BOOL RDNSUnloadOk = TRUE;
RDNSGlobal RDNS;
static BOOL ReadConfiguration(void);
EXPORT int RDNSVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
XplDnsRecord *dns = NULL;
BOOL blocked = FALSE;
int rc = -1;
/* Check for a cached value */
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
sqlite3_bind_int(RDNS.sqlite.stmt.get, 1, command->address);
if ((rc = sqlite3_step(RDNS.sqlite.stmt.get)) == SQLITE_ROW) {
blocked = sqlite3_column_int(RDNS.sqlite.stmt.get, 0);
}
sqlite3_reset(RDNS.sqlite.stmt.get);
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
if (rc != SQLITE_ROW) {
unsigned char buffer[MAXEMAILNAMESIZE];
struct in_addr ip;
/* Perform the RDNS check */
ip.s_addr = command->address;
/* ip is in host byte order. Reverse DNS requires most significant first. (unless providing the .in-addr.arpa extension) */
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d",
ip.s_impno,
ip.s_lh,
ip.s_host,
ip.s_net);
rc = XplDnsResolve(buffer, &dns, XPL_RR_PTR);
if (dns) {
MemFree(dns);
}
if (rc != XPL_DNS_SUCCESS) {
/* We don't like the guy */
blocked = TRUE;
}
/* Store new value */
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
/*
Insert the new value into the table. The time for a negative result is a
full day. The time for a positive result is only 15 minutes however,
because a positive result simply means that the servers do not know anything
about the address.
*/
sqlite3_bind_int(RDNS.sqlite.stmt.add, 1, command->address);
sqlite3_bind_text(RDNS.sqlite.stmt.add, 2, blocked ? RDNS.config.blockTimeout : RDNS.config.allowTimeout, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(RDNS.sqlite.stmt.add, 3, blocked);
sqlite3_step(RDNS.sqlite.stmt.add);
sqlite3_reset(RDNS.sqlite.stmt.add);
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
}
if (blocked) {
/* He was blocked by RDNS */
strncpy(result->comment, CM_COMMENT, sizeof(result->comment));
}
result->detail.connect.requireAuth = blocked;
return(CM_MODULE_ACCEPT);
}
return(0);
}
static void
TransactionController(void *ignored)
{
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
if (sqlite3_exec(RDNS.sqlite.handle, SQL_BEGIN, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrdns: Failed to start transaction controller\n");
}
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
while (!RDNSUnloadOk) {
unsigned long i;
for (i = 0; i < 15 && !RDNSUnloadOk; i++) {
XplDelay(1000);
}
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
if (sqlite3_exec(RDNS.sqlite.handle, SQL_SAVE, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrdns: Failed to save cache data\n");
}
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
}
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
if (sqlite3_exec(RDNS.sqlite.handle, SQL_END, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrdns: Failed to end transaction controller\n");
}
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
}
EXPORT BOOL
CMRDNSInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (RDNSUnloadOk == TRUE) {
XplSafeWrite(RDNS.threadCount, 0);
RDNS.directoryHandle = (MDBHandle) MsgInit();
if (RDNS.directoryHandle) {
RDNSUnloadOk = FALSE;
RDNS.logHandle = LoggerOpen("cmrdns");
if (RDNS.logHandle == NULL) {
XplConsolePrintf("cmrdns: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 1; /* It is important that the rdns are early */
registration->Shutdown = RDNSShutdown;
registration->Verify = RDNSVerify;
registration->Notify = NULL;
XplSafeIncrement(RDNS.threadCount);
strcpy(RDNS.config.datadir, datadir);
XplOpenLocalSemaphore(RDNS.sqlite.semaphore, 1);
if (ReadConfiguration()) {
unsigned char buffer[XPL_MAX_PATH + 1];
int ccode;
XplThreadID id;
snprintf(buffer, sizeof(buffer), "%s/cache.db", datadir);
if (sqlite3_open(buffer, &RDNS.sqlite.handle) != SQLITE_OK) {
printf("cmrdns: Failed to open database: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
}
if (sqlite3_exec(RDNS.sqlite.handle, SQL_CREATE, NULL, NULL, NULL) != SQLITE_OK) {
#if 0
printf("bongogatekeeper: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
#endif
sqlite3_exec(RDNS.sqlite.handle, SQL_ROLLBACK, NULL, NULL, NULL);
}
if ((sqlite3_prepare(RDNS.sqlite.handle, SQL_ADD, -1, &RDNS.sqlite.stmt.add, 0) != SQLITE_OK) ||
(sqlite3_prepare(RDNS.sqlite.handle, SQL_GET, -1, &RDNS.sqlite.stmt.get, 0) != SQLITE_OK) ||
(sqlite3_prepare(RDNS.sqlite.handle, SQL_CLEAN, -1, &RDNS.sqlite.stmt.clean,0) != SQLITE_OK))
{
printf("cmrdns: Failed to prepare sql: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
}
/* Begin the transaction controller thread */
XplBeginThread(&id, TransactionController, (1024 * 32), NULL, ccode);
return(TRUE);
}
} else {
XplConsolePrintf("cmrdns: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
EXPORT BOOL
RDNSShutdown(void)
{
XplSafeDecrement(RDNS.threadCount);
if (RDNSUnloadOk == FALSE) {
RDNSUnloadOk = TRUE;
/*
Make sure the library rdns are gone before beginning to
shutdown.
*/
while (XplSafeRead(RDNS.threadCount)) {
XplDelay(33);
}
LoggerClose(RDNS.logHandle);
sqlite3_finalize(RDNS.sqlite.stmt.add);
sqlite3_finalize(RDNS.sqlite.stmt.get);
sqlite3_finalize(RDNS.sqlite.stmt.clean);
sqlite3_close(RDNS.sqlite.handle);
XplCloseLocalSemaphore(RDNS.sqlite.semaphore);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RDNS.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RDNS.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
config = MDBCreateValueStruct(RDNS.directoryHandle, MsgGetServerDN(NULL));
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
RDNSShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_CONFIG_CHANGED, config)) {
RDNS.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
RDNS.config.last = 0;
}
/*
Store the timeout strings. It is faster to do this once, instead of storing the long value
and creating the string each time, since it must be a string that is bound to the SQL statement.
*/
snprintf(RDNS.config.blockTimeout, sizeof(RDNS.config.blockTimeout), "%d minutes", (3 * 60)); /* Default to 3 hours */
snprintf(RDNS.config.allowTimeout, sizeof(RDNS.config.blockTimeout), "%d minutes", (3 * 60)); /* Default to 3 hours */
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_CONFIGURATION, config) > 0) {
unsigned long i;
for (i = 0; i < config->Used; i++) {
if (XplStrNCaseCmp(config->Value[i], BLOCK_TIMEOUT_PREFIX, sizeof(BLOCK_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RDNS.config.blockTimeout, sizeof(RDNS.config.blockTimeout), "%lu minutes", atol(config->Value[i] + sizeof(BLOCK_TIMEOUT_PREFIX) - 1));
} else if (XplStrNCaseCmp(config->Value[i], ALLOW_TIMEOUT_PREFIX, sizeof(ALLOW_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RDNS.config.allowTimeout, sizeof(RDNS.config.allowTimeout), "%lu minutes", atol(config->Value[i] + sizeof(ALLOW_TIMEOUT_PREFIX) - 1));
}
}
}
MDBDestroyValueStruct(config);
return(TRUE);
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
RDNSShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(RDNS.tgid);
if (RDNSUnloadOk == FALSE) {
RDNSUnloadOk = TRUE;
/*
Make sure the library rdns are gone before beginning to
shutdown.
*/
while (XplSafeRead(RDNS.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(RDNS.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RDNS.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RDNS.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (RDNSUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
RDNS.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper RDNS Module");
XplOpenLocalSemaphore(RDNS.shutdownSemaphore, 0);
XplSignalHandler(RDNSShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore);
XplSignalLocalSemaphore(RDNS.shutdownSemaphore);
return(0);
}
@@ -0,0 +1,99 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <sqlite3.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmrdns.nlm"
#define PRODUCT_NAME "Bongo Connection Manager Reverse DNS Module"
#define CM_COMMENT "Your computer does not have a hostname, access blocked"
typedef struct _RDNSGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
unsigned char datadir[XPL_MAX_PATH + 1];
unsigned char blockTimeout[256];
unsigned char allowTimeout[256];
} config;
struct {
sqlite3 *handle;
XplSemaphore semaphore;
struct {
sqlite3_stmt *add;
sqlite3_stmt *get;
sqlite3_stmt *clean;
} stmt;
} sqlite;
} RDNSGlobal;
extern RDNSGlobal RDNS;
/* cmrdns.c */
void RDNSShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMRDNSInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL RDNSShutdown(void);
EXPORT int RDNSVerify(ConnMgrCommand *command, ConnMgrResult *result);
/* Config Prefixes */
#define BLOCK_TIMEOUT_PREFIX "RDNSBlockTimeout:"
#define ALLOW_TIMEOUT_PREFIX "RDNSAllowTimeout:"
/* SQL */
#define SQL_CREATE "BEGIN TRANSACTION;" \
"CREATE TABLE cache (" \
"ip INTEGER PRIMARY KEY NOT NULL," \
"timeout DATETIME," \
"block BOOL" \
");" \
"CREATE INDEX timeout_idx ON cache (timeout);" \
"END TRANSACTION;"
#define SQL_ROLLBACK "ROLLBACK;"
#define SQL_ADD "INSERT OR REPLACE INTO cache (ip, timeout, block) VALUES (?, DATETIME('now', ?), ?);"
#define SQL_GET "SELECT block FROM cache WHERE ip=? AND julianday('now') < julianday(timeout);"
#define SQL_CLEAN "DELETE FROM cache WHERE julianday('now') >= julianday(timeout);"
#define SQL_BEGIN "BEGIN TRANSACTION;"
#define SQL_END "END TRANSACTION;"
#define SQL_SAVE SQL_CLEAN SQL_END SQL_BEGIN
@@ -0,0 +1,19 @@
# -*- Makefile -*-
cmmodule_LTLIBRARIES += libcmuser.la
libcmuser_la_SOURCES := \
src/agents/connmgr/cmmodules/user/cmuser.c \
src/agents/connmgr/cmmodules/user/cmuser.h
libcmuser_la_LDFLAGS := -module -avoid-version
libcmuser_la_LIBADD := \
libbongomsgapi.la \
libbongologger.la \
libbongomemmgr.la \
libbongomdb.la \
libbongoxpl.la \
$(PTHREAD_LIBS) \
$(ALL_LIBS)
src/agents/connmgr/cmmodules/user/cmuser/all: libcmuser.la
src/agents/connmgr/cmmodules/user/cmuser/clean: clean
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
+293
View File
@@ -0,0 +1,293 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include "cmuser.h"
/* Globals */
BOOL UserUnloadOk = TRUE;
UserGlobal User;
static BOOL ReadConfiguration(void);
static void Cleanup(void *param);
EXPORT BOOL UserNotify(ConnMgrCommand *command)
{
/*
CM_EVENT_AUTHENTICATED
When receieved, create a file in datadir where the name is the ip address
and the conntent is the username.
*/
if (XplStrCaseCmp(command->event, CM_EVENT_AUTHENTICATED) == 0) {
unsigned char buffer[XPL_MAX_PATH + 1];
FILE *addr;
snprintf(buffer, sizeof(buffer), "%s/%07lx", User.config.datadir, command->address);
addr = fopen(buffer, "w");
if (addr) {
fwrite(command->detail.authenticated.user, sizeof(unsigned char), strlen(command->detail.authenticated.user), addr);
fclose(addr);
}
}
return(TRUE);
}
EXPORT int UserVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
/*
CM_EVENT_RELAY
When received, look for a file in datadir with the ip address as the
name, and read the user from the content of the file. Check the time
of the file to see if it has expired.
*/
if (XplStrCaseCmp(command->event, CM_EVENT_RELAY) == 0) {
unsigned char buffer[XPL_MAX_PATH + 1];
struct stat sb;
snprintf(buffer, sizeof(buffer), "%s/%07lx", User.config.datadir, command->address);
if (stat(buffer, &sb) != -1) {
if (sb.st_mtime > time(NULL) - (User.config.timeout * 60)) {
FILE *addr = fopen(buffer, "r");
if (addr) {
int l = fread(result->detail.user, sizeof(unsigned char), MAXEMAILNAMESIZE, addr);
result->detail.user[l] = '\0';
fclose(addr);
return(CM_MODULE_ACCEPT);
}
} else {
unlink(buffer);
}
}
return(CM_MODULE_DENY);
}
return(0);
}
EXPORT BOOL
CMUSERInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (UserUnloadOk == TRUE) {
XplSafeWrite(User.threadCount, 0);
User.directoryHandle = (MDBHandle) MsgInit();
if (User.directoryHandle) {
UserUnloadOk = FALSE;
User.logHandle = LoggerOpen("cmuser");
if (User.logHandle == NULL) {
XplConsolePrintf("cmuser: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 5;
registration->Shutdown = UserShutdown;
registration->Verify = UserVerify;
registration->Notify = UserNotify;
XplSafeIncrement(User.threadCount);
strcpy(User.config.datadir, datadir);
if (ReadConfiguration()) {
XplThreadID id;
int ccode;
XplBeginThread(&id, Cleanup, (1024 * 32), NULL, ccode);
return(TRUE);
}
} else {
XplConsolePrintf("cmuser: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
EXPORT BOOL
UserShutdown(void)
{
XplSafeDecrement(User.threadCount);
if (UserUnloadOk == FALSE) {
UserUnloadOk = TRUE;
/*
Make sure the library users are gone before beginning to
shutdown.
*/
while (XplSafeRead(User.threadCount)) {
XplDelay(33);
}
LoggerClose(User.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(User.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(User.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(User.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
config = MDBCreateValueStruct(User.directoryHandle, MsgGetServerDN(NULL));
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
UserShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_CONFIG_CHANGED, config)) {
User.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
User.config.last = 0;
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_TIMEOUT, config)) {
User.config.timeout = atol(config->Value[0]);
} else {
User.config.timeout = 15;
}
MDBDestroyValueStruct(config);
return(TRUE);
}
static void
Cleanup(void *param)
{
while (!UserUnloadOk) {
int i;
XplDir *dir;
XplDir *dirent;
struct stat sb;
if ((dir = XplOpenDir(User.config.datadir)) != NULL) {
while ((dirent = XplReadDir(dir)) != NULL) {
unsigned char buffer[XPL_MAX_PATH +1 ];
snprintf(buffer, sizeof(buffer), "%s/%s", User.config.datadir, dirent->d_nameDOS);
if ((stat(buffer, &sb) != -1) && (sb.st_mtime < time(NULL) - (User.config.timeout * 60))) {
unlink(buffer);
}
}
XplCloseDir(dir);
}
for (i = 0; i < (User.config.timeout * 60) && !UserUnloadOk; i++) {
XplDelay(1000);
}
}
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
UserShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(User.tgid);
if (UserUnloadOk == FALSE) {
UserUnloadOk = TRUE;
/*
Make sure the library users are gone before beginning to
shutdown.
*/
while (XplSafeRead(User.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(User.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(User.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(User.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(User.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (UserUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
User.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper User Module");
XplOpenLocalSemaphore(User.shutdownSemaphore, 0);
XplSignalHandler(UserShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(User.shutdownSemaphore);
XplSignalLocalSemaphore(User.shutdownSemaphore);
return(0);
}
@@ -0,0 +1,61 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmuser.nlm"
#define PRODUCT_NAME "Bongo Connection Manager User Authentication Module"
typedef struct _UserGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
long timeout;
unsigned char datadir[XPL_MAX_PATH + 1];
} config;
} UserGlobal;
extern UserGlobal User;
/* cmuser.c */
void UserShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMUSERInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL UserShutdown(void);
EXPORT BOOL UserNotify(ConnMgrCommand *command);
EXPORT int UserVerify(ConnMgrCommand *command, ConnMgrResult *result);
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <connmgr.h>
#define CONNMGR_STACK_SPACE (1024 * 32)
#define CONNECTION_TIMEOUT (15 * 60)
/* modules.c */
typedef struct _ModuleStruct {
struct _CMModuleRegistrationStruct registration;
CMInitFunc Init;
XplPluginHandle handle;
struct _ModuleStruct *next;
unsigned char *name;
} ModuleStruct;
void ModulesVerify(ModuleStruct *first, ConnMgrCommand *command, ConnMgrResult *result);
void ModulesNotify(ModuleStruct *first, ConnMgrCommand *command);
ModuleStruct * LoadModules(unsigned char *directory, ModuleStruct *first);
void UnloadModules(ModuleStruct *first);
+212
View File
@@ -0,0 +1,212 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <bongoutil.h>
#include <msgapi.h>
#include "connmgrp.h"
void
ModulesVerify(ModuleStruct *first, ConnMgrCommand *command, ConnMgrResult *result)
{
ModuleStruct *module = first;
result->result = command->detail.policy.default_result;
while (module) {
if (module->registration.Verify) {
int rc = module->registration.Verify(command, result);
if (rc & CM_MODULE_DENY) {
if (rc & CM_MODULE_PERMANENT) {
result->result = CM_RESULT_DENY_PERMANENT;
} else {
result->result = CM_RESULT_DENY_TEMPORARY;
}
}
if (rc & CM_MODULE_FORCE) {
if (rc & CM_MODULE_ACCEPT) {
result->result = CM_RESULT_ALLOWED;
}
return;
}
}
module = module->next;
}
}
void
ModulesNotify(ModuleStruct *first, ConnMgrCommand *command)
{
ModuleStruct *module = first;
while (module) {
if (module->registration.Notify) {
module->registration.Notify(command);
}
module = module->next;
}
}
ModuleStruct *
LoadModules(unsigned char *directory, ModuleStruct *first)
{
XplDir *dir;
XplDir *dirent;
ModuleStruct *result = first;
XplMakeDir(XPL_DEFAULT_DBF_DIR "//connmgr");
if ((dir = XplOpenDir(directory)) != NULL) {
while ((dirent = XplReadDir(dir)) != NULL) {
unsigned char path[XPL_MAX_PATH +1 ];
unsigned char name[XPL_MAX_PATH + 1];
unsigned char *modulename = dirent->d_nameDOS;
ModuleStruct *new = MemMalloc(sizeof(ModuleStruct));
unsigned char datadir[XPL_MAX_PATH + 1];
memset(new, 0, sizeof(ModuleStruct));
if (strlen(modulename) > 3) {
snprintf(path, sizeof(path), "%s/lib%s", directory, modulename);
new->handle = XplLoadDLL(path);
if (!new->handle) {
snprintf(path, sizeof(path), "%s/%s", directory, modulename);
new->handle = XplLoadDLL(path);
}
if (new->handle) {
unsigned char *ptr;
/* Initialize the module */
if (XplStrNCaseCmp(modulename, "lib", 3) == 0) {
BongoStrNCpy(name, modulename + 3, sizeof(name) - strlen("Init"));
} else {
BongoStrNCpy(name, modulename, sizeof(name) - strlen("Init"));
}
ptr = strrchr(name, '.');
if (ptr) {
*ptr = '\0';
}
/* Setup the work directory for the module */
ptr = name;
while (*ptr) {
*ptr = tolower(*ptr);
ptr++;
}
sprintf(datadir, "%s/connmgr/%s", XPL_DEFAULT_DBF_DIR, name);
XplMakeDir(datadir);
ptr = name;
while (*ptr) {
*ptr = toupper(*ptr);
ptr++;
}
strcat(name, "Init");
new->Init = (CMInitFunc)XplGetDLLFunction(modulename, name, new->handle);
name[strlen(name) - 4] = '\0';
#if 0
} else {
/* dlerror() is much more useful when dlopen fails than errno is */
unsigned char *err = dlerror();
if (err) {
XplConsolePrintf("connmgr: XplLoadDLL failed: %s\n", err);
}
XplConsolePrintf("connmgr: could not load module %s/%s, errno: %d %s\n", directory, modulename, errno, strerror(errno));
#endif
}
}
if (new->Init && new->Init(&(new->registration), datadir)) {
new->name = MemStrdup(name);
#if VERBOSE
XplConsolePrintf("connmgr: loaded module: %s\n", new->name);
#endif
if (!result) {
result = new;
} else if (result->registration.priority > new->registration.priority) {
new->next = result;
result = new;
} else {
ModuleStruct *n = result;
/* Find a spot for it */
while (n && n->next) {
if (n->next->registration.priority > new->registration.priority) {
new->next = n->next;
n->next = new;
n = NULL;
}
if (n) {
n = n->next;
}
}
if (n) {
n->next = new;
}
}
} else {
MemFree(new);
}
}
XplCloseDir(dir);
}
return(result);
}
void
UnloadModules(ModuleStruct *first)
{
ModuleStruct *module = first;
while (module) {
ModuleStruct *next = module->next;
if (module->registration.Shutdown) {
module->registration.Shutdown();
}
if (module->handle && module->name) {
XplUnloadDLL(module->name, module->handle);
MemFree(module->name);
}
MemFree(module);
module = next;
}
}
+7 -21
View File
@@ -1272,16 +1272,9 @@ POP3CommandTop(void *param)
}
/* Read message header size */
ccode = NMAPSendCommandF(client->store, "PROPGET %llx nmap.mail.headersize\r\n", client->message[id].guid);
if (ccode != -1) {
ccode = NMAPReadResponse(client->store, client->buffer, CONN_BUFSIZE, TRUE);
if (ccode == 2001) {
ccode = NMAPReadDecimalPropertyResponse(client->store, "nmap.mail.headersize", &headerSize);
}
if (ccode != 2001) {
return(ConnWriteF(client->conn, "%s %d\r\n",MSGERRNMAP, ccode));
}
}
ccode = NMAPGetDecimalProperty(client->store, client->message[id].guid, "nmap.mail.headersize", &headerSize);
if (ccode == -1)
return (ConnWriteF(client->conn, "%s %d\r\n", MSGERRNMAP, ccode));
/* Read the message header */
ccode = NMAPSendCommandF(client->store, "READ %llx 0 %lu\r\n", client->message[id].guid, headerSize);
@@ -1293,31 +1286,24 @@ POP3CommandTop(void *param)
if (ccode != -1) {
ccode = ConnReadToConn(client->store, client->conn, count);
}
if (ccode != -1) {
ccode = NMAPReadAnswer(client->store, client->buffer, CONN_BUFSIZE, TRUE);
}
break;
}
case 4220: {
ccode = ConnWrite(client->conn, MSGERRNOMSG, sizeof(MSGERRNOMSG) - 1);
ccode = -1;
break;
}
default: {
ccode = ConnWriteF(client->conn, "%s %d\r\n",MSGERRNMAP, ccode);
ccode = -1;
break;
}
}
if (ccode != 2001) {
ccode = -1;
}
}
if (ccode != 1000) {
if (ccode == -1) {
return(ccode);
}
@@ -1376,7 +1362,7 @@ POP3CommandTop(void *param)
ConnWrite(client->conn, ".\r\n", 3);
}
return(ccode);
return(1000);
}
static int
+1 -1
View File
@@ -908,7 +908,7 @@ StartOver:
unsigned char buffer[1024]; /* FIXME: is this too big? */
unsigned char *addrptr;
unsigned char *flags = strchr(ptr2+1,' '); /* the original flags */
int cnt;
int cnt=0;
aliasing(cur+1, &cnt, buffer);
+8
View File
@@ -223,11 +223,19 @@ StoreCommandSEARCH(StoreClient *client, uint64_t guid, StoreSearchInfo *query)
goto finish;
case 1:
if (!STORE_IS_FOLDER(child.type)) {
FindPathToDocument(client, child.collection, child.guid, path, sizeof(path));
f = fopen(path, "rb");
if (!f) {
ccode = ConnWriteStr(client->conn, MSG4224CANTREAD);
goto finish;
}
ccode = SearchDocument(client, &child, query, f);
fclose(f);
}
break;
}
}
ccode = ConnWriteStr(client->conn, MSG1000OK);
finish:
if (stmt) DStoreStmtEnd(client->handle, stmt);
+51 -40
View File
@@ -180,7 +180,6 @@ InitializeDataArea(void)
if (unpriv_user != NULL)
XplLookupUser(unpriv_user, &uid, &gid);
XplConsolePrintf(_("Creating directory structure...\n"));
for (dir = MSGAPI_DIR_START; dir < MSGAPI_DIR_END; dir++) {
char path[XPL_MAX_PATH];
if (MsgGetDir(dir, path, XPL_MAX_PATH)) {
@@ -191,7 +190,6 @@ InitializeDataArea(void)
RunAsBongoUser();
XplConsolePrintf(_("Initializing user database...\n"));
if (MsgAuthInit() != 0) {
XplConsolePrintf(_("ERROR: Couldn't initialise auth subsystem\n"));
exit(1);
@@ -212,14 +210,12 @@ InitialStoreConfiguration(void) {
// attempt to initialise cal lib. This creates cached data, and can be time
// consuming: do it now, rather than in the store (for now, at least)
XplConsolePrintf(_("Initializing calendar data...\n"));
cal_success = BongoCalInit(XPL_DEFAULT_DBF_DIR);
if (! cal_success) {
XplConsolePrintf(_("ERROR: Couldn't initialise calendar library\n"));
exit(1);
}
XplConsolePrintf(_("Loading initial store configuration...\n"));
LoadDefaultStoreConfiguration();
}
@@ -268,8 +264,6 @@ LoadDefaultStoreConfiguration(void)
goto nmapcleanup;
}
XplConsolePrintf(_("Setting default agent configuration...\n"));
snprintf(path, XPL_MAX_PATH, "%s/conf/default.set", XPL_DEFAULT_DATA_DIR);
if (! ImportSystemBackupFile(client, path)) {
XplConsolePrintf(_("ERROR: Couldn't setup default configuration\n"));
@@ -333,15 +327,14 @@ GenerateCryptoData() {
// hack: we need to ensure the files below can be saved...
if (0 != mkdir(XPL_DEFAULT_DBF_DIR, 0755)) {
XplConsolePrintf(_("Couldn't create data directory!\n"));
// TODO: check that the directory doesn't already exist.
// XplConsolePrintf(_("Couldn't create data directory!\n"));
}
// save a random seed for faster Xpl startup in future.
XplConsolePrintf(_("Creating random seed...\n"));
XplSaveRandomSeed();
// various magic params
XplConsolePrintf(_("Creating DH parameters...\n"));
gnutls_dh_params_init(&dh_params);
gnutls_dh_params_generate2(dh_params, 1024);
dsize = CERTSIZE;
@@ -356,7 +349,6 @@ GenerateCryptoData() {
return FALSE;
}
XplConsolePrintf(_("Creating RSA parameters...\n"));
gnutls_rsa_params_init(&rsa_params);
gnutls_rsa_params_generate2(rsa_params, 512);
dsize = CERTSIZE;
@@ -372,7 +364,6 @@ GenerateCryptoData() {
}
// create private key
XplConsolePrintf(_("Creating private key...\n"));
ret = gnutls_x509_privkey_init(&key);
if (ret < 0) {
XplConsolePrintf(_("ERROR: %s\n"), gnutls_strerror (ret));
@@ -402,7 +393,6 @@ GenerateCryptoData() {
}
// create certificate
XplConsolePrintf(_("Creating SSL/TLS certificate...\n"));
ret = gnutls_x509_crt_init(&certificate);
if (ret < 0) {
XplConsolePrintf(_("ERROR: %s\n"), gnutls_strerror(ret));
@@ -484,17 +474,38 @@ CheckVersion() {
void
UserAdd(const char *username)
{
if (MsgAuthAddUser(username) == 0) {
XplConsolePrintf(_("Added user %s\n"), username);
} else {
XplConsolePrintf(_("Couldn't add user %s\n"), username);
}
int result = MsgAuthAddUser(username);
switch (result) {
case 0:
XplConsolePrintf(_("Added user %s\n"), username);
break;
case -1:
XplConsolePrintf(_("User %s already exists\n"), username);
break;
case -2:
XplConsolePrintf(_("Auth backend doesn't support adding user\n"));
break;
default:
XplConsolePrintf(_("Couldn't add user %s: internal error\n"), username);
break;
}
}
void
UserList(void)
{
// TODO
char **userlist;
int result;
result = MsgAuthUserList(&userlist);
if (result) {
int i;
for (i = 0; userlist[i] != 0; i++) {
XplConsolePrintf("%s\n", userlist[i]);
}
MsgAuthUserListFree(&userlist);
}
}
void
@@ -539,8 +550,8 @@ main(int argc, char *argv[]) {
BongoAgent configtool;
config.verbose = 0;
/* this just clears up a warning. we don't need this here */
GlobalConfig[0].type = BONGO_JSON_NULL;
/* this just clears up a warning. we don't need this here */
GlobalConfig[0].type = BONGO_JSON_NULL;
if (!MemoryManagerOpen("bongo-config")) {
XplConsolePrintf("ERROR: Failed to initialize memory manager\n");
@@ -633,20 +644,28 @@ main(int argc, char *argv[]) {
XplConsolePrintf(_("Couldn't initialise auth subsystem\n"));
return 3;
}
if ((next_arg + 1) >= argc) {
XplConsolePrintf(_("USAGE : user [add|password] <username>\n"));
if (next_arg >= argc) {
XplConsolePrintf(_("USAGE : user [add|password|list] [<username>]\n"));
} else {
char *command = argv[next_arg++];
char *username = argv[next_arg];
if (! strncmp(command, "add", 3)) {
UserAdd(username);
} else if (!strncmp(command, "password", 8)) {
UserPassword(username);
} else if (!strncmp(command, "list", 4)) {
if (!strncmp(command, "list", 4)) {
UserList();
} else {
XplConsolePrintf(_("ERROR: Unknown command '%s' on user\n"), command);
char *username;
if (next_arg >= argc) {
XplConsolePrintf(_("USAGE : user %s <username\n"), command);
break;
}
username = argv[next_arg];
if (! strncmp(command, "add", 3)) {
UserAdd(username);
} else if (!strncmp(command, "password", 8)) {
UserPassword(username);
} else {
XplConsolePrintf(_("ERROR: Unknown command '%s'\n"), command);
}
}
}
break;
@@ -654,17 +673,9 @@ main(int argc, char *argv[]) {
break;
}
if (config.ip) {
MemFree(config.ip);
}
if (config.dns) {
MemFree(config.dns);
}
if (config.domains) {
BongoJsonNodeFree(config.domains);
}
if (config.ip) MemFree(config.ip);
if (config.dns) MemFree(config.dns);
if (config.domains) BongoJsonNodeFree(config.domains);
MemoryManagerClose("bongo-config");
exit(0);
-1
View File
@@ -10,7 +10,6 @@
{ "name": "bongorules", "pri": 5, "enabled": false },
{ "name": "bongoimap", "pri": 10, "enabled": true },
{ "name": "bongopop3", "pri": 10, "enabled": true },
{ "name": "bongocalcmd", "pri": 7, "enabled": true },
{ "name": "bongo-standalone", "pri": 10, "enabled": true }
]
}
-30
View File
@@ -1,30 +0,0 @@
# -*- Makefile -*-
sbin_SCRIPTS += src/apps/setup/bongo-setup
schemadir = $(XPL_DEFAULT_CONF_DIR)
dist_schema_DATA = \
src/apps/setup/bongo-setup.xml \
src/apps/setup/base-schema.xml \
src/apps/setup/bongo-schema.xml
nodist_schema_DATA = \
src/apps/setup/bongo-setup.xml
dist_noinst_DATA += src/apps/setup/bongo-setup.xml.in
src/apps/setup/bongo-setup: $(top_builddir)/src/libs/python/bongo-python-wrapper
$(INSTALL) -m 755 $< $@
dist_pkglibexec_SCRIPTS += src/apps/setup/bongo-setup.py
CLEANFILES += \
src/apps/setup/bongo-setup \
src/apps/setup/*.pyc
src/apps/setup/all:
src/apps/setup/clean: clean
src/apps/setup/install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) \
sbin_SCRIPTS=src/apps/setup/bongo-setup \
dist_pkglibexec_SCRIPTS=src/apps/setup/bongo-setup.py \
install-dist_sbinSCRIPTS install-dist_schemaDATA
-68
View File
@@ -1,68 +0,0 @@
<schema>
<attribute name="Surname" syntax="CaseInsensitiveString" />
<attribute name="Given Name" syntax="CaseInsensitiveString" />
<attribute name="Title" syntax="CaseInsensitiveString" />
<attribute name="Telephone Number" syntax="CaseInsensitiveString" />
<attribute name="Facsimile Telephone Number" syntax="CaseInsensitiveString" />
<attribute name="SA" syntax="CaseInsensitiveString" />
<attribute name="Postal Office Box" syntax="CaseInsensitiveString" />
<attribute name="Postal Code" syntax="CaseInsensitiveString" />
<attribute name="Postal Address" syntax="CaseInsensitiveString" />
<attribute name="Physical Delivery Office Name" syntax="CaseInsensitiveString" />
<attribute name="Owner" syntax="CaseInsensitiveString" />
<attribute name="O" syntax="CaseInsensitiveString" />
<attribute name="OU" syntax="CaseInsensitiveString" />
<attribute name="Description" syntax="CaseInsensitiveString" />
<attribute name="See Also" syntax="DistinguishedName" />
<class name = "Top">
</class>
<class name="User" super-class="Top">
<required-attributes>
<attribute name="Surname" />
</required-attributes>
<allowed-attributes>
<attribute name="Given Name" />
<attribute name="Title" />
<attribute name="Telephone Number" />
<attribute name="Facsimile Telephone Number" />
<attribute name="SA" />
<attribute name="Postal Office Box" />
<attribute name="Postal Code" />
<attribute name="Postal Address" />
<attribute name="Physical Delivery Office Name" />
<attribute name="See Also" />
<attribute name="Description" />
</allowed-attributes>
</class>
<class name="Organization" super-class="Top">
<allowed-attributes>
<attribute name="Telephone Number" />
<attribute name="Facsimile Telephone Number" />
<attribute name="Postal Office Box" />
<attribute name="Postal Code" />
<attribute name="Postal Address" />
<attribute name="Physical Delivery Office Name" />
<attribute name="Description" />
</allowed-attributes>
</class>
<class name="OrganizationalUnit" super-class="Top">
<allowed-attributes>
<attribute name="Telephone Number" />
<attribute name="Facsimile Telephone Number" />
<attribute name="Postal Office Box" />
<attribute name="Postal Code" />
<attribute name="Postal Address" />
<attribute name="Physical Delivery Office Name" />
<attribute name="Description" />
</allowed-attributes>
</class>
<class name="GroupOfNames" super-class="Top">
<allowed-attributes>
<attribute name="See Also" />
<attribute name="Owner" />
<attribute name="OU" />
<attribute name="O" />
<attribute name="Description" />
</allowed-attributes>
</class>
</schema>
File diff suppressed because it is too large Load Diff
-692
View File
@@ -1,692 +0,0 @@
#!/usr/bin/env python
#############################################################################
#
# Copyright (c) 2006 Novell, Inc.
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail,
# you may find current contact information at www.novell.com
#
#############################################################################
import os, random, signal, socket, string, sys
from bongo import Xpl, BongoError, Privs
from bongo.admin import ManagedSlapd, Util
from libbongo.bootstrap import msgapi
from bongo.Console import wrap
import re, optparse
import logging
formatter = logging.Formatter("%(levelname)s: %(message)s")
console = logging.StreamHandler()
console.setFormatter(formatter)
logging.root.addHandler(console)
log = logging.getLogger("bongo-setup")
# the managed slapd configuration is global, so we can shut it down on
# failure
slapdConfig = None
def BongoSetupOptions():
parser = optparse.OptionParser()
parser.add_option("-n", "--noprompt", action="store_true", help="run non-interactively")
parser.add_option("-H", "--hostname", type="string", help="hostname of this Bongo server")
parser.add_option("-M", "--maildomain", type="string", help="domain we accept mail for")
parser.add_option("-f", "--file", type="string",
default=os.path.join(Xpl.DEFAULT_CONF_DIR, "bongo-setup.xml"),
help="import objects from XML file FILE")
group = optparse.OptionGroup(parser, "SSL options")
group.add_option("-r", "--cert", type="string", metavar="FILE", help="use certificate file FILE")
group.add_option("-k", "--key", type="string", metavar="FILE", help="use private key file FILE")
parser.add_option_group(group)
group = optparse.OptionGroup(parser, "LDAP options", description="options for --mdb-driver=ldap")
group.add_option("-u", "--authuser", type="string", help="user for directory authentication")
group.add_option("-p", "--authpass", type="string", help="password for directory authentication")
parser.add_option_group(group)
schemas = "ad edir mdb openldap".split()
parser.add_option("-S", "--gen-schema", choices=schemas, metavar="TARGET", help="generate schema for TARGET (" + ", ".join(schemas) + ")")
parser.add_option("-a", "--noacl", type="string", help="don't set up ACLs")
dirs = "file ldap managed-slapd".split()
parser.add_option("-m", "--mdb-driver", choices=dirs, default="managed-slapd", help="specify directory driver (" + ", ".join(dirs) + ") [default %default]")
parser.add_option("-b", "--base", type="string", default="\\Tree", help="base in directory for Bongo")
parser.add_option("", "--managed-slapd-path", type="string", metavar="PATH",
default=Xpl.DEFAULT_SLAPD_PATH,
help="path to your slapd binary [default %default]")
parser.add_option("", "--managed-slapd-port", type="int", metavar="PORT",
default=8983, help="port for managed slapd [default %default]")
admintool = os.path.join(Xpl.DEFAULT_BIN_DIR, "bongo-admin")
binpath = os.path.abspath(os.path.dirname(sys.argv[0]))
if not binpath.startswith(Xpl.DEFAULT_BIN_DIR):
adminpath = os.path.abspath(os.path.join(binpath, "..", "bongoadmin",
"bongo-admin"))
if os.path.exists(adminpath):
admintool = adminpath
parser.add_option("", "--bongo-admin", action="store_const", default=admintool, help=optparse.SUPPRESS_HELP)
parser.add_option("", "--debug", action="store_true", help=optparse.SUPPRESS_HELP)
return parser
def main():
parser = BongoSetupOptions()
(options, args) = parser.parse_args()
if options.debug:
logging.root.setLevel(logging.DEBUG)
log.debug("bongo-setup options: " + str(options))
if len(args) > 0:
log.error("Unexpected arguments after script flags")
sys.stderr.write(parser.get_usage())
sys.stderr.write("\n")
sys.exit(1)
if os.getegid() != 0:
log.error("%s must be run as root" % os.path.basename(sys.argv[0]))
sys.exit(1)
if not options.noprompt:
print wrap("""
Welcome to Bongo!
You will be guided through the setup of a new Bongo installation.
This tool makes use of %(bongo_admin)s, which you can also use to tweak the system later, or (for experts) to set up Bongo manually.
See \"%(bongo_setup)s --help\" for command-line options to further automate the setup process.
""" % {'bongo_admin' : options.bongo_admin, 'bongo_setup' : sys.argv[0]})
Input('Press Enter to continue', options=options)
# make sure our various directories are in good shape permissions-wise
for path in [Xpl.DEFAULT_CONF_DIR,
Xpl.DEFAULT_STATE_DIR,
Xpl.DEFAULT_CACHE_DIR,
Xpl.DEFAULT_DBF_DIR,
Xpl.DEFAULT_WORK_DIR]:
if not os.path.exists(path):
os.makedirs(path)
Privs.Chown(path)
pidfile = os.path.join(Xpl.DEFAULT_WORK_DIR, "bongomanager.pid")
if os.path.exists(pidfile):
fd = open(pidfile, "r")
pid = fd.readline().strip()
fd.close()
# see if the bongomanager pid is still running
try:
pid = long(pid)
r = os.kill(pid, 0)
raise BongoError("""A possibly stale bongomanager pid file has been found. Either kill process %d (if it is bongomanager) or remove %s""" % (pid, pidfile))
except OSError, e:
os.remove(pidfile)
mdbfile = os.path.join(Xpl.DEFAULT_CONF_DIR, "mdb.conf")
mdbconf = InspectMDB(mdbfile, options)
if mdbconf is None:
mdbconf = SetupMDB(mdbfile, options)
if mdbconf.get("driver") in ("file", "managed-slapd"):
if not UpdateSchema(mdbconf, options):
raise BongoError(wrap("""Updating the MDB schema has failed."""))
if ImportObjects(mdbconf, options):
raise BongoError("""Importing objects failed, possibly because the directory's schema needs to be updated. When you are done updating the schema in your directory, run %s again to complete Bongo's configuration.""" % sys.argv[0])
print 'Imported objects from \"%s\".' % options.file
SetupACL(mdbconf, options)
GeneratePasswords(options)
print 'Configuring final settings...'
from bongo import MDB
mdb = MDB.MDB(options.authuser, options.authpass)
context = mdb.baseDn
# include other directory options here once they're supported
if mdbconf.get("driver") == "ldap" and not mdbconf.has_key("slapdConfig"):
context = Input('Enter default directory context for Bongo users',
{}, mdb.baseDn, options)
while not mdb.IsObject(context):
print 'Context does not exist. Please enter a valid context.'
context = Input('Enter default directory context for Bongo users',
{}, mdb.baseDn, options)
confprops = {msgapi.DEFAULT_CONTEXT : context}
Util.ModifyConfProperties(confprops)
msgserver = msgapi.GetConfigProperty(msgapi.MESSAGING_SERVER)
mdb.SetAttribute(msgserver, msgapi.A_CONTEXT, [context])
#getting hostname for certificate
if options.hostname:
hostname = options.hostname
else:
hostname = Input('Enter the hostname for the mail server hosting Bongo',
{}, socket.getfqdn(), options)
try:
mdb.SetAttribute(msgserver, msgapi.A_OFFICIAL_NAME, [hostname])
except BongoError:
if not hostname in ['localhost', 'localhost.localdomain']:
raise
#getting domain name bongo will accept mail for
if options.maildomain:
maildomain = options.maildomain
else:
maildomain = Input('Enter domain name that Bongo will host',
{}, socket.getfqdn(), options)
try:
mdb.SetAttribute(msgserver, msgapi.A_OFFICIAL_NAME, [maildomain])
except BongoError:
if not maildomain in ['localhost', 'localhost.localdomain']:
raise
# Add hosted domain to the smtp agent
smtpserver = msgserver + '\\' + msgapi.AGENT_SMTP
if(mdb.IsObject(smtpserver)):
try:
mdb.AddAttribute(smtpserver, msgapi.A_DOMAIN, maildomain)
except:
print "Couldn't set attribute A_DOMAIN to " + maildomain
try:
default = socket.gethostbyname(maildomain)
except:
default = '127.0.0.1'
ip = Input('Enter IP address on which to run Bongo',
{}, default, options)
try:
mdb.SetAttribute(msgserver, msgapi.A_IP_ADDRESS, [ip])
except:
print "Couldn't set attribute A_IP_ADDRESS to " + ip
options.hostname = hostname
options.ip = ip
# now we have the hostname and ip, we can setup a sensible cert.
SetupCerts(options)
# shut down the temporary slapd
if mdbconf.has_key("slapdConfig"):
slapdConfig = mdbconf["slapdConfig"]
slapdConfig.killSlapd()
print
print 'Bongo setup is complete!'
print 'Now run "bongo-config install" to complete the installation'
return
def ReadMdbConf(mdbfile):
fd = open(mdbfile)
confstr = fd.readline().strip()
fd.close()
if not re.match("^Driver=", confstr):
return None
arr = confstr.split(" ", 2)
driver = arr[0].split("=", 2)
conf = {"driver" : driver[1].lower()}
if len(arr) > 1:
for key, val in re.findall("(.*?)=\"(.*?)\"(?:[ |,])?", arr[1]):
conf[key.lower()] = val
return conf
def WriteMdbConf(mdbfile, mdbconf):
mcfile = open(mdbfile, "w")
drivers = {"managed-slapd" : "ldap"}
driver = mdbconf.get("driver")
if drivers.has_key(driver):
driver = drivers[driver]
confstr = "Driver=MDB" + driver.upper()
opts = []
for optname in ["basedn", "binddn", "password", "port", "host", "tls"]:
if not mdbconf.has_key(optname):
continue
opts.append('%s="%s"' % (optname, mdbconf[optname]))
if len(opts) > 0:
confstr = confstr + " " + ",".join(opts)
mcfile.write(confstr)
mcfile.write("\n")
mcfile.close()
Privs.Chown(mdbfile)
def LdapToMdb(dn):
parts = re.findall("=([^,]+)", dn)
parts.reverse()
return '\\' + '\\'.join(parts)
def InspectMDB(mdbfile, options):
if not os.path.exists(mdbfile):
return None
log.debug("inspecting existing MDB install")
conf = ReadMdbConf(mdbfile)
if conf is None:
return None
olddriver = conf["driver"]
print 'Found an existing %s MDB configuration.' % olddriver
choices = {'keep': 'Use the existing \"%s\" configuration' % olddriver,
'change': 'Set up MDB differently'}
choice = 'keep'
if options.noprompt:
choice = 'change'
choice = Input('Enter your choice for MDB', choices, choice, options)
if choice == 'change':
return None
# at this point, the user wants to reuse the old mdb configuration
drivers = {'mdbfile': 'file', 'mdbldap': 'ldap'}
# if no driver has been specified on the command line, reuse
# the old driver
if options.mdb_driver is None:
conf["driver"] = drivers.get(conf["olddriver"], conf["olddriver"])
if options.authuser and options.authpass:
print 'Using command line credentials...'
elif olddriver == 'mdbfile':
print 'Using no credentials (for mdbfile)...'
else:
authuser = conf.get('binddn')
authpass = conf.get('password')
if not authuser and not authpass:
print 'Could not determine directory credentials from old MDB configuration.'
authuser = Input('Enter the directory admin dn')
authpass = Input('Enter the directory admin password')
if authuser and not options.authuser:
# turn the ldap user into an mdb user
options.authuser = LdapToMdb(authuser)
if authpass and not options.authpass:
options.authpass = authpass
return conf
def GetRandomPassword():
pw = ""
chars = string.ascii_letters + string.digits
for i in range(1, 20):
pw = pw + random.choice(chars)
return pw
def DiscoverMDBDriverCB(drivers, parent, children):
for child in children:
if os.path.isdir(os.path.join(parent, child)):
children.remove(child)
if (child[:6].lower() == 'libmdb') and (child[-3:].lower() == '.so'):
drivers[child[6:-3]] = child.lower()
def DiscoverMDBDrivers():
mdblibpath = "%s/bongomdb/" % Xpl.DEFAULT_LIB_DIR
if not os.path.exists(mdblibpath):
raise BongoError(wrap("""MDB Driver directory can not be found!"""))
drivers = {}
os.path.walk(mdblibpath, DiscoverMDBDriverCB, drivers)
return drivers
def SetupMDB(mdbfile, options):
drivers = DiscoverMDBDrivers()
mdbOptions = {}
if drivers.has_key('file'):
mdbOptions['file'] = 'use the filesystem as a directory (test systems only)'
if drivers.has_key('ldap'):
mdbOptions['managed-slapd'] = 'Bongo-managed standalone LDAP server'
mdbOptions['ldap'] = 'connect to any LDAP-speaking directory'
if drivers.has_key('edir'):
mdbOptions['edir'] = 'use native calls to speak to eDirectory'
if len(mdbOptions) == 0:
raise BongoError(wrap("""No MDB Driver has been found!"""))
print 'Which driver would you like to use for the directory?'
mdbSelection = Input('Enter your driver selection', mdbOptions, options.mdb_driver, options)
mdbconf = {}
mdbconf["driver"] = mdbSelection
confprops = {"ManagedSlapd" : 0}
if mdbSelection == 'file':
mdbpath = os.path.join(Xpl.DEFAULT_STATE_DIR, "mdb")
if not os.path.exists(mdbpath):
os.makedirs(mdbpath)
Privs.Chown(mdbpath)
options.authpass = "bongo"
elif mdbSelection == 'ldap':
host = ShellCmd('hostname --long')
if host:
default = 'dc=' + ',dc='.join(host.split('.'))
else:
default = 'dc=example,dc=com'
ldaphost = Input('Enter the hostname or the IP address of the ldap server', default='localhost',
options=options)
mdbconf["host"] = ldaphost
ldapport = Input('Enter the port of the ldap server', default='389',
options=options)
mdbconf["port"] = ldapport
basedn = Input('Enter LDAP base for Bongo', default=default,
options=options)
mdbconf["basedn"] = basedn
binddn = Input('Enter LDAP admin object', default='cn=admin,'+basedn,
options=options)
mdbconf["binddn"] = options.authuser = binddn
bindpw = Input('Enter LDAP admin password', default='bongo',
options=options)
mdbconf["password"] = options.authpass = bindpw
enableTLS = Input('Use TLS on LDAP connections', default='true',
options=options)
if enableTLS[0:1].lower() == 't':
mdbconf["tls"] = '1'
elif mdbSelection == 'managed-slapd':
ofile = os.path.join(Xpl.DEFAULT_CONF_DIR, "bongo.schema")
bongoRootpw = GetRandomPassword()
global slapdConfig
slapdConfig = \
ManagedSlapd.ConfigSlapd(ofile,
options.managed_slapd_path,
options.managed_slapd_port,
bongoRootpw)
mdbconf["port"] = options.managed_slapd_port
mdbconf["basedn"] = slapdConfig.suffix
mdbconf["binddn"] = slapdConfig.rootdn
mdbconf["password"] = slapdConfig.password
slapdConfigFile = os.path.join(Xpl.DEFAULT_CONF_DIR, "bongo-slapd.conf")
slapdConfig.writeSlapdConf(slapdConfigFile)
options.authuser = LdapToMdb(slapdConfig.rootdn)
options.authpass = slapdConfig.password
mdbconf["slapdConfig"] = slapdConfig
mdbconf["slapdConfigFile"] = slapdConfigFile
base = '\\com\\example'
confprops = {'BongoServices': '%s\\%s' % (base, msgapi.ROOT),
'MessagingServer': '%s\\%s\\%s' % (base,
msgapi.ROOT,
'Bongo Messaging Server'),
'ManagedSlapd': '1',
'ManagedSlapdPath': options.managed_slapd_path,
'ManagedSlapdPort': str(options.managed_slapd_port)}
elif mdbSelection == 'edir':
edirhost = Input('Enter the hostname or the IP address of the edirectory (ncp) server', default='localhost',
options=options)
mdbconf["host"] = edirhost
edirport = Input('Enter the port of the edirectory (ncp) server', default='524',
options=options)
mdbconf["port"] = edirport
else:
raise BongoError('Invalid driver selection: %s' % mdbSelection)
Util.WriteConfProperties(confprops)
print 'Configured MDB with \"%s\" option.' % mdbSelection
WriteMdbConf(mdbfile, mdbconf)
return mdbconf
def ImportObjects(mdbconf, options):
print 'Directory setup - importing objects...'
pid = None
if mdbconf.has_key("slapdConfig"):
slapdConfig = mdbconf["slapdConfig"]
log.debug("starting temporary managed slapd process")
pid = slapdConfig.startSlapd(mdbconf["slapdConfigFile"])
if pid is None:
raise BongoError('Error starting temporary slapd process. Check syslog for information about the failure.')
log.debug("initializing slapd with the base Bongo container")
slapdConfig.initSlapd()
options.file = Input('Enter file for importing objects',
default=options.file, options=options)
authops = GetAdminCmdAuth(options)
return AdminCmd(options, authops + ['import', '-f', options.file])
def UpdateSchema(mdbconf, options):
print 'Updating the directory\'s schema...'
authops = GetAdminCmdAuth(options)
dirnames = {"file" : "MDB File",
"edir" : "Novell eDirectory",
"openldap" : "OpenLDAP",
"managed-slapd" : "Managed Slapd"}
driver = mdbconf["driver"]
print 'Generating schema for %s...' % dirnames.get(driver)
if driver == 'file' or driver == 'edir':
if AdminCmd(options, authops + ['setup-mdb']):
return False
return True
elif driver == 'ldap':
dirtypes = {'openldap': 'OpenLDAP standalone server',
'edir': 'Novell eDirectory',
'ad': 'Microsoft Active Directory'}
dirtype = Input('Enter your directory selection', dirtypes,
'openldap', options)
if dirtype == 'openldap':
ofile = 'bongo.schema'
elif dirtype == 'edir':
ofile = 'bongo.sch'
elif dirtype == 'ad':
ofile = 'bongo.ldf'
else:
raise BongoError('Invalid directory type')
print 'A schema file will now be generated, which you will have to'
print 'import into your directory manually.'
ofile = Input('Enter filename for schema', {}, ofile, options)
if AdminCmd(options, authops + ["setup-genschema",
"-t", dirtype,
"-o", ofile]):
return False
return True
elif driver == 'managed-slapd':
ofile = os.path.join(Xpl.DEFAULT_CONF_DIR, 'bongo.schema')
if AdminCmd(options, authops + ["setup-genschema",
"-t", "openldap",
"-o", ofile]):
return False
return True
def GetAdminCmdAuth(options):
authops = []
if options.authuser:
authops.extend(["-U", options.authuser])
if options.authpass:
authops.extend(["-P", options.authpass])
return authops
def GetAdminCmdBase(options):
if not options.base:
return []
return ["--base", options.base]
def SetupACL(mdbconf, options):
noacl_drivers = ("managed-slapd")
if options.noacl or mdbconf["driver"] in noacl_drivers:
print 'Skipping access control setup.'
return
print 'Setting up access control...'
authops = GetAdminCmdAuth(options)
baseops = GetAdminCmdBase(options)
ret = AdminCmd(options, authops + ['setup-rights'] + baseops)
if ret != 0:
print 'Rights could not be automatically set in the directory.'
print 'You will manually have to grant privileges on the base'
print 'to the Bongo Messaging Server object.'
Input('Press Enter to continue')
else:
print 'Access control installed.'
def GeneratePasswords(options):
print 'Generating server credentials...'
authops = GetAdminCmdAuth(options)
if AdminCmd(options, authops + ['setup-system-credential']) != 0:
raise BongoError('Server credential generation failed.')
print 'Server credentials installed.'
#TODO: ask for files interactively
def SetupCerts(options):
authops = GetAdminCmdAuth(options)
certops = []
if options.cert and options.key:
print 'Installing provided certificate + key...'
certops.append('--cert=\"%s\"' % options.cert)
certops.append('--key=\"%s\"' % options.key)
if not certops:
print 'Generating certificate + key...'
certops.append('--ip=\"%s\"' % options.ip)
certops.append('--domain=\"%s\"' % options.hostname)
if AdminCmd(options, authops + ['setup-ssl'] + certops) != 0:
raise BongoError('Certificate + key installation failed.')
print 'Certificate + key installed.'
def AdminCmd(options, args):
if not args:
raise BongoError('No command specified')
if options.debug:
args = ["--debug"] + args
log.debug("running %s %s", options.bongo_admin, ' '.join(args))
ret = os.spawnv(os.P_WAIT, options.bongo_admin, [options.bongo_admin] + args)
if ret != 0:
log.debug("command failed")
return ret
def ShellCmd(cmd):
log.debug("running shell command: " + cmd)
return os.popen(cmd).read().strip()
def Input(prompt, choices={}, default=None, options=None):
if options and options.noprompt:
return default
nums = []
length = 0
for key, val in choices.iteritems():
nums.append(key)
nums.sort()
for key in choices.keys():
if length < len(key):
length = len(key)
entry = None
while entry is None:
i = 0
for val in nums:
i += 1
print ' %d: %s - %s' % (i, val.ljust(length), choices[val])
if default is None:
pstr = prompt + ': '
else:
pstr = '%s [%s]: ' % (prompt, default)
entry = raw_input(pstr)
if entry.lower().strip() in choices.keys():
entry = entry.lower().strip()
elif entry.strip().isdigit() and int(entry.strip()) <= len(nums):
entry = nums[int(entry.strip()) - 1]
elif not entry.strip():
entry = default
if default is None:
break
elif entry and not choices:
entry = entry
else:
entry = None
return entry
def Shutdown():
if slapdConfig is not None:
slapdConfig.killSlapd()
if __name__ == "__main__":
try:
main()
Shutdown()
except BongoError, e:
Shutdown()
print wrap("ERROR: " + str(e))
sys.exit(1)
except KeyboardInterrupt:
Shutdown()
print
sys.exit(1)
-150
View File
@@ -1,150 +0,0 @@
<setup>
<services name="Bongo Services">
<messaging-server name="Bongo Messaging Server">
<property name="bongo-postmaster">\</property>
<property name="context">\</property>
<property name="official-name">localhost.localdomain</property>
<!--<property name="ip-address">127.0.0.1</property>-->
<property name="ssl-tls">1</property>
<property name="ssl-allow-chained">0</property>
<property name="work-directory">@XPL_DEFAULT_WORK_DIR@</property>
<property name="dbf-directory">@XPL_DEFAULT_DBF_DIR@</property>
<property name="nls-directory">@XPL_DEFAULT_NLS_DIR@</property>
<property name="conn-mgr">Bongo Messaging Server\Connection Manager</property>
<agent name="Store Agent" type="store-agent">
<property name="module-name">BONGOSTORE.NLM</property>
<property name="module-version">1</property>
<property name="minimum-space">2048</property>
<property name="scms-user-threshold">5</property>
<property name="scms-size-threshold">5</property>
<property name="message-store">@XPL_DEFAULT_MAIL_DIR@</property>
<property name="scms-directory">@XPL_DEFAULT_SCMS_DIR@</property>
<property name="client">
<value>Address Book Agent</value>
</property>
</agent>
<agent name="Queue Agent" type="queue-agent">
<property name="module-name">BONGOQUEUE.NLM</property>
<property name="module-version">1</property>
<!-- Can't comment out when nested under 'property'. Weird.
These belong under <property name="client"> when the actual agents are
reintroduced to this file.
<value>Calendar Text Command Agent</value>
<value>Itip Agent</value>
-->
<property name="client">
<value>Proxy Agent</value>
<value>SMTP Agent</value>
<value>AntiSpam Agent</value>
</property>
<property name="quota-message">
The user to whom this message was addressed has exceeded the allowed mailbox quota. Please resend the message at a later time.
</property>
<property name="queue-interval">30</property>
<property name="queue-timeout">5</property>
<property name="minimum-space">2048</property>
<property name="bounce-return">1</property>
<property name="bounce-cc-postmaster">0</property>
<property name="spool-directory">@XPL_DEFAULT_SPOOL_DIR@</property>
</agent>
<agent name="Proxy Agent" type="proxy-agent">
<property name="module-name">BONGOMAILPROX.NLM</property>
<property name="module-version">1</property>
<property name="time-interval">3</property>
<property name="maximum-items">3</property>
<property name="monitored-queue">Queue Agent</property>
<property name="queue-server">Queue Agent</property>
<property name="store-server">Store Agent</property>
</agent>
<agent name="SMTP Agent" type="smtp-agent">
<property name="module-name">BONGOSMTP.NLM</property>
<property name="module-version">1</property>
<property name="port">25</property>
<property name="ssl-port">465</property>
<property name="monitored-queue">Queue Agent</property>
<property name="queue-server">Queue Agent</property>
<property name="domain">
<value>localhost.localdomain</value>
<value>localhost</value>
</property>
<property name="message-limit">0</property>
<property name="routing">0</property>
<property name="smtp-send-etrn">0</property>
<property name="smtp-accept-etrn">1</property>
<property name="ube-smtp-after-pop">1</property>
<property name="ube-remote-auth-only">1</property>
</agent>
<agent name="Connection Manager" type="conn-mgr-agent">
<property name="module-name">BONGOCONNMGR.NLM</property>
<property name="module-version">1</property>
<property name="timeout">15</property>
<module name="User Module" type="cm-user-module">
<property name="module-name">BONGOCMUSER.NLM</property>
<property name="module-version">1</property>
</module>
<module name="Lists Module" type="cm-lists-module">
<property name="module-name">BONGOCMLISTS.NLM</property>
<property name="module-version">1</property>
</module>
<module name="RBL Module" type="cm-rbl-module">
<property name="module-name">BONGOCMRBL.NLM</property>
<property name="module-version">1</property>
</module>
<module name="RDNS Module" type="cm-rdns-module">
<property name="module-name">BONGOCMRDNS.NLM</property>
<property name="module-version">1</property>
<property name="disabled">1</property>
</module>
</agent>
<agent name="Address Book Agent" type="addressbook-agent">
<property name="module-name">BONGOMSGLDAP.NLM</property>
<property name="module-version">1</property>
<property name="monitored-queue">Queue Agent</property>
<property name="port">389</property>
<property name="time-interval">1</property>
<property name="ldap-options">1</property>
</agent>
<agent name="AntiSpam Agent" type="antispam-agent">
<property name="module-name">BONGOANTISPAM.NLM</property>
<property name="module-version">1</property>
<property name="monitored-queue">Queue Agent</property>
</agent>
<!--
<agent name="Calendar Text Command Agent" type="calcmd-agent">
<property name="module-name">BONGOCALCMD.NLM</property>
<property name="module-version">1</property>
<property name="monitored-queue">Queue Agent</property>
</agent>
-->
<agent name="Collector Agent" type="collector-agent">
<property name="module-name">BONGOCALCMD.NLM</property>
<property name="module-version">1</property>
</agent>
<!--
<agent name="Itip Agent" type="itip-agent">
<property name="module-name">BONGOITIP.NLM</property>
<property name="module-version">1</property>
<property name="monitored-queue">Queue Agent</property>
</agent>
-->
<agent name="IMAP Agent" type="imap-agent">
<property name="module-name">BONGOIMAP.NLM</property>
<property name="module-version">1</property>
<property name="monitored-queue">Queue Agent</property>
<property name="port">143</property>
<property name="ssl-port">993</property>
</agent>
<agent name="POP Agent" type="pop-agent">
<property name="module-name">BONGOPOP3.NLM</property>
<property name="module-version">1</property>
<property name="monitored-queue">Queue Agent</property>
<property name="port">110</property>
<property name="ssl-port">995</property>
</agent>
</messaging-server>
</services>
</setup>
-7
View File
@@ -1,7 +0,0 @@
# THIS FILE SHOULD NOT BE INSTALLED!
# It exists only to merge the src/[...]/bongosetup/bongo and src/libs/python/bongo
# directories in the Bongo source tree together. In an installed
# system, they're going to be in the same place.
__path__.append(__path__[0] + "/../../../libs/python/bongo")
-110
View File
@@ -1,110 +0,0 @@
<schema>
<class name="User">
<allowed-attributes>
<attribute name="Novonyx:EMail Address" />
<attribute name="Novonyx:Finger Message" />
<attribute name="Novonyx:Reply Message" />
<attribute name="Bongo:SMSAuthorizedPhones" />
<attribute name="Bongo:CalCmdAddressSuffix" />
<attribute name="BongoCalendarSubscriptions" />
<attribute name="Novonyx:Forwarding Address" />
<attribute name="Novonyx:Forwarding Enabled" />
<attribute name="NIMS:WapMessageSize" />
<attribute name="Novonyx:Vacation Message Enabled" />
<attribute name="Novonyx:Reply Message" />
<attribute name="Novonyx:Messaging Disabled" />
<attribute name="Novonyx:Use Quota" />
<attribute name="Novonyx:Quota Value" />
<attribute name="Novonyx:Proxy List" />
<attribute name="Novonyx:Language" />
<attribute name="Novonyx:Color" />
<attribute name="Novonyx:Font" />
<attribute name="Novonyx:Preferences" />
<attribute name="Novonyx:Timeout" />
<attribute name="Novonyx:Privacy" />
<attribute name="Novonyx:Addressbook Config" />
<attribute name="Novonyx:Addressbook URL Public" />
<attribute name="Novonyx:Addressbook" />
<attribute name="Novonyx:Phrase" />
<attribute name="Novonyx:Accounting Data" />
<attribute name="Novonyx:Billing Data" />
<attribute name="NIMS:Signature" />
<attribute name="NIMS:Default Charset" />
<attribute name="NIMS:Rule" />
<attribute name="NIMS:FeatureSet" />
<attribute name="NIMS:ParentObject" />
<attribute name="NIMS:Template" />
<attribute name="NIMS:Timezone" />
<attribute name="NIMS:Locale" />
<attribute name="NIMS:PasswordConfig" />
<attribute name="NIMS:Title" />
<attribute name="NIMS:TOMManager" />
<attribute name="NIMS:TOMContexts" />
<attribute name="NIMS:TOMDomains" />
<attribute name="NIMS:TOMOptions" />
<attribute name="WebAdmin:DefaultTemplate" />
<attribute name="WebAdmin:DisallowedTemplates" />
<attribute name="NetMail:AvailableShares" />
<attribute name="NetMail:OwnedShares" />
<attribute name="NetMail:AvailableProxies" />
<attribute name="NetMail:OwnedProxies" />
<attribute name="NetMail:ManagedResources" />
</allowed-attributes>
</class>
<class name="Group">
<allowed-attributes>
<attribute name="Novonyx:Finger Message" />
<attribute name="Novonyx:Messaging Disabled" />
<attribute name="NIMS:Rule" />
<attribute name="NIMS:FeatureSet" />
<attribute name="NIMS:ParentObject" />
<attribute name="WebAdmin:DefaultTemplate" />
<attribute name="WebAdmin:DisallowedTemplates" />
</allowed-attributes>
</class>
<class name="Organizational Role">
<allowed-attributes>
<attribute name="Novonyx:Messaging Disabled" />
<attribute name="NIMS:ParentObject" />
<attribute name="WebAdmin:DefaultTemplate" />
<attribute name="WebAdmin:DisallowedTemplates" />
</allowed-attributes>
</class>
<class name="Organization">
<allowed-attributes>
<attribute name="Novonyx:Domain" />
<attribute name="Novonyx:Message Store" />
<attribute name="Bongo:Index Store" />
<attribute name="Novonyx:Messaging Disabled" />
<attribute name="NIMS:Default Charset" />
<attribute name="NIMS:Rule" />
<attribute name="NIMS:FeatureSet" />
<attribute name="NIMS:ParentObject" />
<attribute name="WebAdmin:DefaultTemplate" />
<attribute name="WebAdmin:DisallowedTemplates" />
</allowed-attributes>
</class>
<class name="Organizational Unit">
<allowed-attributes>
<attribute name="Novonyx:Domain" />
<attribute name="Novonyx:Message Store" />
<attribute name="Bongo:Index Store" />
<attribute name="Novonyx:Messaging Disabled" />
<attribute name="NIMS:Default Charset" />
<attribute name="NIMS:Rule" />
<attribute name="NIMS:FeatureSet" />
<attribute name="NIMS:ParentObject" />
<attribute name="WebAdmin:DefaultTemplate" />
<attribute name="WebAdmin:DisallowedTemplates" />
</allowed-attributes>
</class>
<class name="NCP Server">
<allowed-attributes>
<attribute name="Novonyx:Messaging Server" />
<attribute name="NIMS:PKeyFile" />
<attribute name="NIMS:CAFile" />
<attribute name="NetMail:MessagingServer" />
<attribute name="WebAdminConfigDN" />
</allowed-attributes>
</class>
</schema>
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
# -*- Makefile -*-
lib_LTLIBRARIES += libbongoconnmgr.la
#libbongonmap_la_LDFLAGS := -static
libbongoconnmgr_la_SOURCES := \
src/libs/connmgr/connmgr.c \
src/libs/connmgr/hashcred.c
src/libs/connmgr/all: libbongoconnmgr.la
src/libs/connmgr/clean: clean
+17
View File
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
+342
View File
@@ -0,0 +1,342 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <bongoutil.h>
#include <memmgr.h>
#include <cmlib.h>
#include <connmgr.h>
#include <msgapi.h>
struct {
unsigned char access[CM_HASH_SIZE];
unsigned char pass[XPLHASH_MD5_LENGTH];
MDBHandle directoryHandle;
BOOL debug;
unsigned long address;
XplRWLock lock;
unsigned char service[16 + 1];
} CMLibrary = {
{ '\0' },
{ '\0' },
NULL,
FALSE
};
BOOL
CMSendCommand(ConnMgrCommand *command, ConnMgrResult *result)
{
struct sockaddr_in fromSin;
struct sockaddr_in toSin;
int sock;
int tries = 0;
do {
result->result = CM_RESULT_UNKNOWN_ERROR;
XplRWReadLockAcquire(&CMLibrary.lock);
strcpy(command->pass, CMLibrary.pass);
XplRWReadLockRelease(&CMLibrary.lock);
memset(&fromSin, 0, sizeof(struct sockaddr_in));
memset(&toSin, 0, sizeof(struct sockaddr_in));
sock = IPsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock >= 0) {
toSin.sin_family = AF_INET;
toSin.sin_addr.s_addr = CMLibrary.address;
toSin.sin_port = htons(CM_PORT);
fromSin.sin_family = AF_INET;
fromSin.sin_addr.s_addr = 0;
fromSin.sin_port = 0;
if (IPbind(sock, (struct sockaddr *)&fromSin, sizeof(fromSin)) == 0) {
sendto(sock, (unsigned char *)command, sizeof(ConnMgrCommand), 0, (struct sockaddr*)&toSin, sizeof(toSin));
XplIPRead(XPL_INT_TO_PTR(sock), (unsigned char *)result, sizeof(ConnMgrResult), 19);
}
IPclose(sock);
}
if (result->result == CM_RESULT_MUST_AUTH) {
xpl_hash_context ctx;
// Ensure that we don't walk off the edge of the buffer if garbage was sent
result->detail.salt[sizeof(result->detail.salt) - 1] = '\0';
XplHashNew(&ctx, XPLHASH_MD5);
XplHashWrite(&ctx, result->detail.salt, strlen(result->detail.salt));
XplHashWrite(&ctx, CMLibrary.access, CM_HASH_SIZE);
XplHashFinal(&ctx, XPLHASH_LOWERCASE, command->pass, XPLHASH_MD5_LENGTH);
/* Store the password so we don't have to generate it every time */
XplRWWriteLockAcquire(&CMLibrary.lock);
strcpy(CMLibrary.pass, command->pass);
XplRWWriteLockRelease(&CMLibrary.lock);
} else {
return(TRUE);
}
} while (tries++ < 3);
return(FALSE);
}
int
CMVerifyConnect(unsigned long address, unsigned char *comment, BOOL *requireAuth)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_VERIFY;
strcpy(command.event, CM_EVENT_CONNECT);
command.address = address;
command.detail.policy.default_result = CM_RESULT_ALLOWED;
CMSendCommand(&command, &result);
if (result.comment[0] != '\0') {
strncpy(comment, result.comment, sizeof(result.comment));
} else {
comment[0] = '\0';
}
if (requireAuth) {
*requireAuth = result.detail.connect.requireAuth;
}
return(result.result);
}
int
CMVerifyRelay(unsigned long address, unsigned char *user)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_VERIFY;
strcpy(command.event, CM_EVENT_RELAY);
command.address = address;
command.detail.policy.default_result = CM_RESULT_MUST_AUTH;
CMSendCommand(&command, &result);
if (result.result == CM_RESULT_ALLOWED && user) {
strncpy(user, result.detail.user, MAXEMAILNAMESIZE);
} else {
user[0] = '\0';
}
return(result.result);
}
int
CMDisconnected(unsigned long address)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_DISCONNECTED);
command.address = address;
CMSendCommand(&command, &result);
return(result.result);
}
int
CMAuthenticated(unsigned long address, unsigned char *user)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_AUTHENTICATED);
command.address = address;
if (user) {
strncpy(command.detail.authenticated.user, user, MAXEMAILNAMESIZE);
} else {
command.detail.authenticated.user[0] = '\0';
}
CMSendCommand(&command, &result);
return(result.result);
}
int
CMDelivered(unsigned long address, unsigned long recipients)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_DELIVERED);
command.address = address;
command.detail.delivered.recipients = recipients;
CMSendCommand(&command, &result);
return(result.result);
}
int
CMReceived(unsigned long address, unsigned long local, unsigned long invalid, unsigned long remote)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_RECEIVED);
command.address = address;
command.detail.received.local = local;
command.detail.received.invalid = invalid;
command.detail.received.remote = remote;
CMSendCommand(&command, &result);
return(result.result);
}
int
CMFoundVirus(unsigned long address, unsigned long recipients, unsigned char *name)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_VIRUS_FOUND);
command.address = address;
command.detail.virus.recipients = recipients;
if (name) {
strncpy(command.detail.virus.name, name, 256);
} else {
command.detail.virus.name[0] = '\0';
}
CMSendCommand(&command, &result);
return(result.result);
}
int
CMSpamFound(unsigned long address, unsigned long recipients)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_SPAM_FOUND);
command.address = address;
command.detail.spam.recipients = recipients;
CMSendCommand(&command, &result);
return(result.result);
}
int
CMDOSDetected(unsigned long address, unsigned char *description)
{
ConnMgrCommand command;
ConnMgrResult result;
memset(&command, 0, sizeof(command));
memset(&result, 0, sizeof(result));
command.command = CM_COMMAND_NOTIFY;
strcpy(command.event, CM_EVENT_DOS_DETECTED);
command.address = address;
if (description) {
strncpy(command.detail.dos.description, description, 256);
} else {
command.detail.dos.description[0] = '\0';
}
CMSendCommand(&command, &result);
return(result.result);
}
BOOL
CMInitialize(MDBHandle directoryHandle, unsigned char *service)
{
BOOL result = FALSE;
if (directoryHandle) {
MDBValueStruct *v;
CMLibrary.directoryHandle = directoryHandle;
v = MDBCreateValueStruct(CMLibrary.directoryHandle, NULL);
if (v) {
MDBRead(MSGSRV_ROOT, MSGSRV_A_ACL, v);
if (v->Used) {
result = HashCredential(MsgGetServerDN(NULL), v->Value[0], CMLibrary.access);
}
MDBFreeValues(v);
if (MsgReadIP((unsigned char *) MsgGetServerDN(NULL), MSGSRV_A_CONNMGR, v)) {
CMLibrary.address = inet_addr(v->Value[0]);
}
MDBDestroyValueStruct(v);
}
XplRWLockInit(&CMLibrary.lock);
}
if (service) {
strncpy(CMLibrary.service, service, 16);
CMLibrary.service[16] = '\0';
} else {
CMLibrary.service[0] = '\0';
}
return(result);
}
+137
View File
@@ -0,0 +1,137 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#if 0
#include <config.h>
#include <xpl.h>
#include <msgapi.h>
#include <gatekeeper.h>
#include <gklib.h>
#define ORGANIZATION_BUFFER_SIZE 100
#define GK_CRED_STORE_SIZE 4096
#define GK_CRED_DIGEST_SIZE 16
#define GK_CRED_CHUNK_SIZE (GK_CRED_STORE_SIZE * GK_CRED_DIGEST_SIZE) / GK_HASH_SIZE
static BOOL
GetOrgName(unsigned char *Organization)
{
unsigned long len;
unsigned char *ptr;
unsigned char *buffer;
/* get the treename */
buffer = MemStrdup(MsgGetServerDN(NULL));
if (buffer) {
if (buffer[0] == '\\') {
ptr = strchr(buffer + 1, '\\');
if (ptr) {
len = ptr - (buffer + 1);
if (len > 0) {
if (len < ORGANIZATION_BUFFER_SIZE) {
*ptr = '\0';
strcpy(Organization, buffer + 1);
*ptr = '\\';
} else {
memcpy(Organization, buffer + 1, ORGANIZATION_BUFFER_SIZE);
Organization[ORGANIZATION_BUFFER_SIZE] = '\0';
}
MemFree(buffer);
return(TRUE);
}
}
}
MemFree(buffer);
}
return(FALSE);
}
BOOL
HashCredential(unsigned char *Credential, unsigned char *Hash)
{
unsigned char organization[ORGANIZATION_BUFFER_SIZE + 1];
unsigned char *ptr;
unsigned long organizationLen;
unsigned long len;
if (Hash && Credential) {
len = strlen(Credential);
if (GetOrgName(organization)) {
organizationLen = strlen(organization);
if (len >= GK_CRED_STORE_SIZE) {
unsigned long i;
MD5_CTX mdContext;
unsigned char digest[GK_CRED_DIGEST_SIZE];
unsigned char *srcPtr;
unsigned char *dstPtr;
unsigned char *dstEnd;
srcPtr = Credential;
dstPtr = Hash;
dstEnd = Hash + GK_HASH_SIZE;
MD5_Init(&mdContext);
MD5_Update(&mdContext, srcPtr, GK_CRED_CHUNK_SIZE);
MD5_Update(&mdContext, organization, organizationLen);
MD5_Final(digest, &mdContext);
srcPtr += GK_CRED_CHUNK_SIZE;
for (i = 0; i < GK_CRED_DIGEST_SIZE; i++) {
if (dstPtr < dstEnd) {
*dstPtr = digest[i];
dstPtr++;
}
}
do {
MD5_Init(&mdContext);
MD5_Update(&mdContext, srcPtr, GK_CRED_CHUNK_SIZE);
MD5_Update(&mdContext, Hash, dstPtr - Hash);
MD5_Final(digest, &mdContext);
srcPtr += GK_CRED_CHUNK_SIZE;
for (i = 0; i < GK_CRED_DIGEST_SIZE; i++) {
if (dstPtr < dstEnd) {
*dstPtr = digest[i];
dstPtr++;
}
}
} while (dstPtr < dstEnd);
/* Hash now contains a non-terminated 128 byte octet string */
return(TRUE);
}
XplConsolePrintf("\rGate Keeper credentials are not properly configured!\r\n");
return(FALSE);
}
XplConsolePrintf("\Bongo can not determine what organization it is running on.\r\n");
return(FALSE);
}
return(FALSE);
}
#endif
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE log4c SYSTEM "">
<log4c version="0.1.0">
<log4c version="0.3.1">
<config>
<bufsize>0</bufsize>
+19
View File
@@ -0,0 +1,19 @@
# -*- Makefile -*-
mdb_LTLIBRARIES += libmdbfile.la
libmdbfile_la_SOURCES := \
src/libs/mdb-file/mdbfile.c \
src/libs/mdb-file/mdbfilep.h
libmdbfile_la_CPPFLAGS := $(AM_CPPFLAGS) \
-DLOCALSTATEDIR=\""$(localstatedir)"\" \
-DMDB_INTERNAL
libmdbfile_la_LDFLAGS := -module -avoid-version
libmdbfile_la_LIBADD := \
libbongoutil.la \
libbongomemmgr.la \
libbongoxpl.la
src/libs/mdb-file/all: libmdbfile.la
src/libs/mdb-file/clean: clean
+17
View File
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
File diff suppressed because it is too large Load Diff
+366
View File
@@ -0,0 +1,366 @@
/*
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
*/
#ifndef MDBP_H
#define MDBP_H
/* Little helpers */
#define MDB_CONTEXT_IS_VALID(ValueStruct) (ValueStruct->Flags & MDB_FLAGS_CONTEXT_VALID)
/* Bit definitions */
#define MDB_FLAGS_ALLOCATED_HANDLE (unsigned long)(1<<0) /* The Init function has allocated the handle */
#define MDB_FLAGS_CONTEXT_VALID (unsigned long)(1<<1) /* The Context handle is valid */
#define MDB_FLAGS_CONTEXT_DUPLICATE (unsigned long)(1<<2) /* The context handle is duplicated, do not free it */
#define MDB_FLAGS_BASEDN_CHANGED (unsigned long)(1<<3) /* Caching uses this, if the DN of a context is changed, this is set */
#define VALUE_ALLOC_SIZE 20
#define VALUE_BUFFER_SIZE (10 * 1024)
#define ERR_NO_SUCH_ENTRY 0xFFFFFDA7
#define ERR_NO_SUCH_VALUE 0xFFFFFDA6
#define ERR_NO_SUCH_ATTRIBUTE 0xFFFFFDA5
#define ERR_NO_SUCH_CLASS 0xFFFFFDA4
#define ERR_NO_SUCH_PARTITION 0xFFFFFDA3
#define ERR_ENTRY_ALREADY_EXISTS 0xFFFFFDA2
#define ERR_NOT_EFFECTIVE_CLASS 0xFFFFFDA1
#define ERR_ILLEGAL_ATTRIBUTE 0xFFFFFDA0
#define ERR_MISSING_MANDATORY 0xFFFFFD9F
#define ERR_ILLEGAL_DS_NAME 0xFFFFFD9E
#define ERR_ILLEGAL_CONTAINMENT 0xFFFFFD9D
#define ERR_CANT_HAVE_MULTIPLE_VALUES 0xFFFFFD9C
#define ERR_SYNTAX_VIOLATION 0xFFFFFD9B
#define ERR_DUPLICATE_VALUE 0xFFFFFD9A
#define ERR_ATTRIBUTE_ALREADY_EXISTS 0xFFFFFD99
#define ERR_MAXIMUM_ENTRIES_EXIST 0xFFFFFD98
#define ERR_DATABASE_FORMAT 0xFFFFFD97
#define ERR_INCONSISTENT_DATABASE 0xFFFFFD96
#define ERR_INVALID_COMPARISON 0xFFFFFD95
#define ERR_COMPARISON_FAILED 0xFFFFFD94
#define ERR_TRANSACTIONS_DISABLED 0xFFFFFD93
#define ERR_INVALID_TRANSPORT 0xFFFFFD92
#define ERR_SYNTAX_INVALID_IN_NAME 0xFFFFFD91
#define ERR_TRANSPORT_FAILURE 0xFFFFFD8F
#define ERR_ALL_REFERRALS_FAILED 0xFFFFFD8E
#define ERR_CANT_REMOVE_NAMING_VALUE 0xFFFFFD8D
#define ERR_OBJECT_CLASS_VIOLATION 0xFFFFFD8C
#define ERR_ENTRY_IS_NOT_LEAF 0xFFFFFD8B
#define ERR_DIFFERENT_TREE 0xFFFFFD8A
#define ERR_SYSTEM_FAILURE 0xFFFFFD88
#define ERR_INVALID_ENTRY_FOR_ROOT 0xFFFFFD87
#define ERR_NO_REFERRALS 0xFFFFFD86
#define ERR_REMOTE_FAILURE 0xFFFFFD85
#define ERR_UNREACHABLE_SERVER 0XFFFFFD84
#define ERR_NO_CHARACTER_MAPPING 0XFFFFFD82
#define ERR_INCOMPLETE_AUTHENTICATION 0XFFFFFD81
#define ERR_INVALID_CERTIFICATE 0xFFFFFD80
#define ERR_INVALID_REQUEST 0xFFFFFD7F
#define ERR_INVALID_ITERATION 0xFFFFFD7E
#define ERR_SCHEMA_IS_NONREMOVABLE 0xFFFFFD7D
#define ERR_SCHEMA_IS_IN_USE 0xFFFFFD7C
#define ERR_CLASS_ALREADY_EXISTS 0xFFFFFD7B
#define ERR_BAD_NAMING_ATTRIBUTES 0xFFFFFD7A
#define ERR_INSUFFICIENT_STACK 0xFFFFFD78
#define ERR_INSUFFICIENT_BUFFER 0xFFFFFD77
#define ERR_AMBIGUOUS_CONTAINMENT 0xFFFFFD76
#define ERR_AMBIGUOUS_NAMING 0xFFFFFD75
#define ERR_DUPLICATE_MANDATORY 0xFFFFFD74
#define ERR_DUPLICATE_OPTIONAL 0xFFFFFD73
#define ERR_RECORD_IN_USE 0xFFFFFD6C
#define ERR_ENTRY_NOT_CONTAINER 0xFFFFFD64
#define ERR_FAILED_AUTHENTICATION 0xFFFFFD63
#define ERR_INVALID_CONTEXT 0xFFFFFD62
#define ERR_NO_SUCH_PARENT 0xFFFFFD61
#define ERR_NO_ACCESS 0xFFFFFD60
#define ERR_INVALID_NAME_SERVICE 0xFFFFFD5E
#define ERR_INVALID_TASK 0xFFFFFD5D
#define ERR_INVALID_CONN_HANDLE 0xFFFFFD5C
#define ERR_INVALID_IDENTITY 0xFFFFFD5B
#define ERR_DUPLICATE_ACL 0xFFFFFD5A
#define ERR_ALIAS_OF_AN_ALIAS 0xFFFFFD57
#define ERR_INVALID_RDN 0xFFFFFD4E
#define ERR_INCORRECT_BASE_CLASS 0xFFFFFD4C
#define ERR_MISSING_REFERENCE 0xFFFFFD4B
#define ERR_LOST_ENTRY 0xFFFFFD4A
#define ERR_FATAL 0xFFFFFD45
typedef struct {
/* Semi-public; known to the main MDB library */
unsigned char Description[128];
struct _MDBInterfaceStruct *Interface;
/* Private */
unsigned char Dirname[XPL_MAX_PATH + 1];
BOOL ReadOnly;
} MDBFILEContextStruct;
typedef MDBFILEContextStruct *MDBHandle;
typedef struct {
/* Public part, exposed to allow simpler code */
unsigned char **Value;
unsigned long Used;
unsigned long ErrNo;
struct _MDBInterfaceStruct *Interface;
/* Private part, not exposed in public header */
unsigned long Flags;
unsigned long Allocated;
unsigned char *BaseDN;
unsigned char Buffer[VALUE_BUFFER_SIZE];
unsigned char Path[XPL_MAX_PATH + 1];
unsigned char Filename[(XPL_MAX_PATH * 4) + 1];
MDBFILEContextStruct *Handle;
} MDBValueStruct;
typedef struct {
BOOL Initialized;
unsigned int EntriesLeft;
FILE *File;
MDBValueStruct *V;
unsigned char Buffer[VALUE_BUFFER_SIZE];
unsigned char Filename[(XPL_MAX_PATH * 4) + 1];
unsigned long Offset;
} MDBEnumStruct;
typedef struct _MDBFILEBaseSchemaAttributes {
unsigned char *name;
unsigned long flags;
unsigned long type;
unsigned char *asn1;
} MDBFILEBaseSchemaAttributes;
typedef struct _MDBFILEBaseSchemaClasses {
unsigned char *name;
unsigned long flags;
unsigned char *asn1;
unsigned char *superClass;
unsigned char *containedBy;
unsigned char *namedBy;
unsigned char *mandatory;
unsigned char *optional;
} MDBFILEBaseSchemaClasses;
MDBFILEBaseSchemaAttributes MDBFILEBaseSchemaAttributesList[] = {
{ "ACL",64,17,"2.16.840.1.113719.1.1.4.1.2" },
{ "Aliased Object Name",69,1,"2.5.4.1" },
{ "Back Link",268,23,"2.16.840.1.113719.1.1.4.1.6" },
{ "Bindery Property",12,32,"2.16.840.1.113719.1.1.4.1.8" },
{ "Bindery Object Restriction",13,8,"2.16.840.1.113719.1.1.4.1.7" },
{ "Bindery Type",45,5,"2.16.840.1.113719.1.1.4.1.9" },
{ "CA Private Key",93,32,"2.16.840.1.113719.1.1.4.1.11" },
{ "CA Public Key",205,32,"2.16.840.1.113719.1.1.4.1.12" },
{ "Cartridge",100,3,"2.16.840.1.113719.1.1.4.1.10" },
{ "CN",102,3,"2.5.4.3" },
{ "Printer Configuration",69,32,"2.16.840.1.113719.1.1.4.1.78" },
{ "Convergence",71,8,"2.16.840.1.113719.1.1.4.1.15" },
{ "C",103,3,"2.5.4.6" },
{ "Default Queue",325,1,"2.16.840.1.113719.1.1.4.1.18" },
{ "Description",102,3,"2.5.4.13" },
{ "Partition Creation Time",205,19,"2.16.840.1.113719.1.1.4.1.64" },
{ "Facsimile Telephone Number",68,11,"2.5.4.23" },
{ "High Convergence Sync Interval",69,27,"2.16.840.1.113719.1.1.4.1.117" },
{ "Group Membership",580,1,"2.16.840.1.113719.1.1.4.1.25" },
{ "Home Directory",71,15,"2.16.840.1.113719.1.1.4.1.26" },
{ "Host Device",69,1,"2.16.840.1.113719.1.1.4.1.27" },
{ "Host Resource Name",101,3,"2.16.840.1.113719.1.1.4.1.28" },
{ "Host Server",69,1,"2.16.840.1.113719.1.1.4.1.29" },
{ "Inherited ACL",76,17,"2.16.840.1.113719.1.1.4.1.30" },
{ "L",102,3,"2.5.4.7" },
{ "Login Allowed Time Map",71,32,"2.16.840.1.113719.1.1.4.1.39" },
{ "Login Disabled",69,7,"2.16.840.1.113719.1.1.4.1.40" },
{ "Login Expiration Time",69,24,"2.16.840.1.113719.1.1.4.1.41" },
{ "Login Grace Limit",69,8,"2.16.840.1.113719.1.1.4.1.42" },
{ "Login Grace Remaining",69,22,"2.16.840.1.113719.1.1.4.1.43" },
{ "Login Intruder Address",69,12,"2.16.840.1.113719.1.1.4.1.44" },
{ "Login Intruder Attempts",69,22,"2.16.840.1.113719.1.1.4.1.45" },
{ "Login Intruder Limit",69,8,"2.16.840.1.113719.1.1.4.1.46" },
{ "Intruder Attempt Reset Interval",69,27,"2.16.840.1.113719.1.1.4.1.31" },
{ "Login Intruder Reset Time",69,24,"2.16.840.1.113719.1.1.4.1.47" },
{ "Login Maximum Simultaneous",69,8,"2.16.840.1.113719.1.1.4.1.48" },
{ "Login Script",69,21,"2.16.840.1.113719.1.1.4.1.49" },
{ "Login Time",5,24,"2.16.840.1.113719.1.1.4.1.50" },
{ "Member",68,1,"2.5.4.31" },
{ "Memory",69,8,"2.16.840.1.113719.1.1.4.1.52" },
{ "EMail Address",228,14,"0.9.2342.19200300.100.1.3" },
{ "Network Address",68,12,"2.16.840.1.113719.1.1.4.1.55" },
{ "Network Address Restriction",68,12,"2.16.840.1.113719.1.1.4.1.56" },
{ "Notify",68,25,"2.16.840.1.113719.1.1.4.1.57" },
{ "Obituary",76,32,"2.16.840.1.113719.1.1.4.1.114" },
{ "Object Class",196,20,"2.5.4.0" },
{ "Operator",324,1,"2.16.840.1.113719.1.1.4.1.59" },
{ "OU",102,3,"2.5.4.11" },
{ "O",102,3,"2.5.4.10" },
{ "Owner",68,1,"2.5.4.32" },
{ "Page Description Language",102,4,"2.16.840.1.113719.1.1.4.1.63" },
{ "Passwords Used",86,32,"2.16.840.1.113719.1.1.4.1.65" },
{ "Password Allow Change",69,7,"2.16.840.1.113719.1.1.4.1.66" },
{ "Password Expiration Interval",69,27,"2.16.840.1.113719.1.1.4.1.67" },
{ "Password Expiration Time",69,24,"2.16.840.1.113719.1.1.4.1.68" },
{ "Password Minimum Length",69,8,"2.16.840.1.113719.1.1.4.1.69" },
{ "Password Required",69,7,"2.16.840.1.113719.1.1.4.1.70" },
{ "Password Unique Required",69,7,"2.16.840.1.113719.1.1.4.1.71" },
{ "Path",68,15,"2.16.840.1.113719.1.1.4.1.72" },
{ "Physical Delivery Office Name",102,3,"2.5.4.19" },
{ "Postal Address",68,18,"2.5.4.16" },
{ "Postal Code",102,3,"2.5.4.17" },
{ "Postal Office Box",102,3,"2.5.4.18" },
{ "Print Job Configuration",69,21,"2.16.840.1.113719.1.1.4.1.80" },
{ "Printer Control",69,21,"2.16.840.1.113719.1.1.4.1.79" },
{ "Private Key",93,32,"2.16.840.1.113719.1.1.4.1.82" },
{ "Profile",69,1,"2.16.840.1.113719.1.1.4.1.83" },
{ "Public Key",205,32,"2.16.840.1.113719.1.1.4.1.84" },
{ "Queue",68,25,"2.16.840.1.113719.1.1.4.1.85" },
{ "Queue Directory",359,3,"2.16.840.1.113719.1.1.4.1.86" },
{ "Reference",1052,1,"2.16.840.1.113719.1.1.4.1.115" },
{ "Replica",204,16,"2.16.840.1.113719.1.1.4.1.88" },
{ "Resource",68,1,"2.16.840.1.113719.1.1.4.1.89" },
{ "Role Occupant",68,1,"2.5.4.33" },
{ "Higher Privileges",836,1,"2.16.840.1.113719.1.1.4.1.116" },
{ "Security Equals",836,1,"2.16.840.1.113719.1.1.4.1.92" },
{ "See Also",68,1,"2.5.4.34" },
{ "Serial Number",102,4,"2.16.840.1.113719.1.1.4.1.94" },
{ "Server",324,1,"2.16.840.1.113719.1.1.4.1.95" },
{ "S",102,3,"2.5.4.8" },
{ "Status",197,8,"2.16.840.1.113719.1.1.4.1.98" },
{ "SA",102,3,"2.5.4.9" },
{ "Supported Typefaces",102,3,"2.16.840.1.113719.1.1.4.1.102" },
{ "Supported Services",102,3,"2.16.840.1.113719.1.1.4.1.101" },
{ "Surname",230,3,"2.5.4.4" },
{ "Telephone Number",100,10,"2.5.4.20" },
{ "Title",102,3,"2.5.4.12" },
{ "Unknown",4,0,"2.16.840.1.113719.1.1.4.1.109" },
{ "User",324,1,"2.16.840.1.113719.1.1.4.1.111" },
{ "Version",231,3,"2.16.840.1.113719.1.1.4.1.112" },
{ "Account Balance",69,22,"2.16.840.1.113719.1.1.4.1.1" },
{ "Allow Unlimited Credit",69,7,"2.16.840.1.113719.1.1.4.1.4" },
{ "Low Convergence Reset Time",69,24,"2.16.840.1.113719.1.1.4.1.118" },
{ "Minimum Account Balance",69,8,"2.16.840.1.113719.1.1.4.1.54" },
{ "Low Convergence Sync Interval",69,27,"2.16.840.1.113719.1.1.4.1.104" },
{ "Device",68,1,"2.16.840.1.113719.1.1.4.1.21" },
{ "Message Server",69,1,"2.16.840.1.113719.1.1.4.1.53" },
{ "Language",69,6,"2.16.840.1.113719.1.1.4.1.34" },
{ "Supported Connections",69,8,"2.16.840.1.113719.1.1.4.1.100" },
{ "Type Creator Map",69,21,"2.16.840.1.113719.1.1.4.1.107" },
{ "UID",69,8,"2.16.840.1.113719.1.1.4.1.108" },
{ "GID",69,8,"2.16.840.1.113719.1.1.4.1.24" },
{ "Unknown Base Class",39,3,"2.16.840.1.113719.1.1.4.1.110" },
{ "Received Up To",204,19,"2.16.840.1.113719.1.1.4.1.87" },
{ "Synchronized Up To",1164,19,"2.16.840.1.113719.1.1.4.1.33" },
{ "Authority Revocation",77,32,"2.16.840.1.113719.1.1.4.1.5" },
{ "Certificate Revocation",77,32,"2.16.840.1.113719.1.1.4.1.13" },
{ "Cross Certificate Pair",68,32,"2.16.840.1.113719.1.1.4.1.17" },
{ "Locked By Intruder",69,7,"2.16.840.1.113719.1.1.4.1.37" },
{ "Printer",68,25,"2.16.840.1.113719.1.1.4.1.77" },
{ "Detect Intruder",69,7,"2.16.840.1.113719.1.1.4.1.20" },
{ "Lockout After Detection",69,7,"2.16.840.1.113719.1.1.4.1.38" },
{ "Intruder Lockout Reset Interval",69,27,"2.16.840.1.113719.1.1.4.1.32" },
{ "Server Holds",68,26,"2.16.840.1.113719.1.1.4.1.96" },
{ "SAP Name",103,3,"2.16.840.1.113719.1.1.4.1.91" },
{ "Volume",69,1,"2.16.840.1.113719.1.1.4.1.113" },
{ "Last Login Time",13,24,"2.16.840.1.113719.1.1.4.1.35" },
{ "Print Server",69,25,"2.16.840.1.113719.1.1.4.1.81" },
{ "NNS Domain",102,3,"2.16.840.1.113719.1.1.4.1.119" },
{ "Full Name",102,3,"2.16.840.1.113719.1.1.4.1.120" },
{ "Partition Control",204,25,"2.16.840.1.113719.1.1.4.1.121" },
{ "Revision",2189,22,"2.16.840.1.113719.1.1.4.1.122" },
{ "Certificate Validity Interval",71,27,"2.16.840.1.113719.1.1.4.1.123" },
{ "External Synchronizer",68,32,"2.16.840.1.113719.1.1.4.1.124" },
{ "Messaging Database Location",69,15,"2.16.840.1.113719.1.1.4.1.125" },
{ "Message Routing Group",68,1,"2.16.840.1.113719.1.1.4.1.126" },
{ "Messaging Server",68,1,"2.16.840.1.113719.1.1.4.1.127" },
{ "Postmaster",68,1,"2.16.840.1.113719.1.1.4.1.128" },
{ "Mailbox Location",197,1,"2.16.840.1.113719.1.1.4.1.162" },
{ "Mailbox ID",231,3,"2.16.840.1.113719.1.1.4.1.163" },
{ "External Name",69,32,"2.16.840.1.113719.1.1.4.1.164" },
{ "Security Flags",69,8,"2.16.840.1.113719.1.1.4.1.165" },
{ "Messaging Server Type",103,3,"2.16.840.1.113719.1.1.4.1.166" },
{ "Last Referenced Time",1029,19,"2.16.840.1.113719.1.1.4.1.167" },
{ "Given Name",230,3,"2.5.4.42" },
{ "Initials",230,3,"2.5.4.43" },
{ "Generational Qualifier",231,3,"2.16.840.1.113719.1.1.4.1.170" },
{ "Profile Membership",580,1,"2.16.840.1.113719.1.1.4.1.171" },
{ "DS Revision",197,8,"2.16.840.1.113719.1.1.4.1.172" },
{ "Supported Gateway",102,3,"2.16.840.1.113719.1.1.4.1.173" },
{ "Equivalent To Me",324,1,"2.16.840.1.113719.1.1.4.1.174" },
{ "Replica Up To",1164,32,"2.16.840.1.113719.1.1.4.1.175" },
{ "Partition Status",1164,32,"2.16.840.1.113719.1.1.4.1.176" },
{ "Permanent Config Parms",196,32,"2.16.840.1.113719.1.1.4.1.177" },
{ "Timezone",133,32,"2.16.840.1.113719.1.1.4.1.178" },
{ "Bindery Restriction Level",5,8,"2.16.840.1.113719.1.1.4.1.179" },
{ "Transitive Vector",2252,32,"2.16.840.1.113719.1.1.4.1.180" },
{ "T",102,3,"2.16.840.1.113719.1.1.4.1.181" },
{ "Purge Vector",3212,19,"2.16.840.1.113719.1.1.4.1.183" },
{ "Synchronization Tolerance",196,19,"2.16.840.1.113719.1.1.4.1.184" },
{ "Password Management",69,0,"2.16.840.1.113719.1.1.4.1.185" },
{ "Used By",332,15,"2.16.840.1.113719.1.1.4.1.186" },
{ "Uses",332,15,"2.16.840.1.113719.1.1.4.1.187" },
{ "Obituary Notify",76,32,"2.16.840.1.113719.1.1.4.1.500" },
{ "GUID",207,32,"2.16.840.1.113719.1.1.4.1.501" },
{ "Other GUID",198,32,"2.16.840.1.113719.1.1.4.1.502" },
{ NULL,0,0,NULL },
};
MDBFILEBaseSchemaClasses MDBFILEBaseSchemaClassesList[] = {
{ "[Nothing]",3,NULL,NULL,NULL,NULL,NULL,NULL },
{ "Top",3,"2.5.6.0",NULL,NULL,"T","Object Class,T","CA Public Key,Private Key,Certificate Validity Interval,Authority Revocation,Last Referenced Time,Equivalent To Me,ACL,Back Link,Bindery Property,Obituary,Reference,Revision,Cross Certificate Pair,Certificate Revocation,Used By,GUID,Other GUID" },
{ "Tree Root",3,"2.16.840.1.113719.1.1.6.1.32","Top","[Nothing]",NULL,NULL,NULL },
{ "Alias",2,"2.5.6.1","Top",NULL,NULL,"Aliased Object Name",NULL },
{ "Country",3,"2.5.6.2","Top","Top,Tree Root,[Nothing]","C","C","Description" },
{ "Locality",3,"2.5.6.3","Top","Locality,Country,Organizational Unit,Organization","L,S",NULL,"Description,L,See Also,S,SA" },
{ "Organization",3,"2.5.6.4",NULL,"Top,Tree Root,Country,Locality,[Nothing]","O","O","Description,Facsimile Telephone Number,L,Login Script,EMail Address,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,Print Job Configuration,Printer Control,See Also,S,SA,Telephone Number,Login Intruder Limit,Intruder Attempt Reset Interval,Detect Intruder,Lockout After Detection,Intruder Lockout Reset Interval" },
{ "Organizational Unit",3,"2.5.6.5",NULL,"Locality,Organization,Organizational Unit","OU","OU","Description,Facsimile Telephone Number,L,Login Script,EMail Address,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,Print Job Configuration,Printer Control,See Also,S,SA,Telephone Number,Login Intruder Limit,Intruder Attempt Reset Interval,Detect Intruder,Lockout After Detection,Intruder Lockout Reset Interval" },
{ "Organizational Role",2,"2.5.6.8","Top","Organization,Organizational Unit","CN","CN","Description,Facsimile Telephone Number,L,EMail Address,OU,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,Role Occupant,See Also,S,SA,Telephone Number,Mailbox Location,Mailbox ID" },
{ "Group",2,"2.5.6.17","Top","Organization,Organizational Unit","CN","CN","Description,L,Member,OU,O,Owner,See Also,GID,Full Name,EMail Address,Mailbox Location,Mailbox ID,Profile,Profile Membership,Login Script" },
{ "Person",2,"2.5.6.6",NULL,"Organization,Organizational Unit","CN","CN","Description,See Also,Telephone Number,Full Name,Given Name,Initials,Generational Qualifier" },
{ "Organizational Person",2,"2.5.6.7","Person","Organization,Organizational Unit","CN,OU",NULL,"Facsimile Telephone Number,L,EMail Address,OU,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,S,SA,Title,Mailbox Location,Mailbox ID" },
{ "User",2,"2.5.6.10","Organizational Person",NULL,NULL,NULL,"Group Membership,Home Directory,Login Allowed Time Map,Login Disabled,Login Expiration Time,Login Grace Limit,Login Grace Remaining,Login Intruder Address,Login Intruder Attempts,Login Intruder Reset Time,Login Maximum Simultaneous,Login Script,Login Time,Network Address Restriction,Network Address,Passwords Used,Password Allow Change,Password Expiration Interval,Password Expiration Time,Password Minimum Length,Password Required,Password Unique Required,Print Job Configuration,Private Key,Profile,Public Key,Security Equals,Account Balance,Allow Unlimited Credit,Minimum Account Balance,Message Server,Language,UID,Locked By Intruder,Server Holds,Last Login Time,Type Creator Map,Higher Privileges,Printer Control,Security Flags,Profile Membership,Timezone" },
{ "Device",2,"2.16.840.1.113719.1.1.6.1.6","Top","Organization,Organizational Unit","CN","CN","Description,L,Network Address,OU,O,Owner,See Also,Serial Number" },
{ "Computer",2,"2.16.840.1.113719.1.1.6.1.4","Device",NULL,NULL,NULL,"Operator,Server,Status" },
{ "Printer",2,"2.16.840.1.113719.1.1.6.1.17","Device",NULL,NULL,NULL,"Cartridge,Printer Configuration,Default Queue,Host Device,Print Server,Memory,Network Address Restriction,Notify,Operator,Page Description Language,Queue,Status,Supported Typefaces" },
{ "Resource",0,"2.16.840.1.113719.1.1.6.1.21","TOp","Organization,Organizational Unit","CN","CN","Description,Host Resource Name,L,OU,O,See Also,Uses" },
{ "Queue",2,"2.16.840.1.113719.1.1.6.1.20","Resource",NULL,NULL,"Queue Directory","Device,Operator,Server,User,Network Address,Volume,Host Server" },
{ "Bindery Queue",2,"2.16.840.1.113719.1.1.6.1.3","Queue",NULL,"CN","Bindery Type",NULL },
{ "Volume",2,"2.16.840.1.113719.1.1.6.1.26","Resource",NULL,NULL,"Host Server","Status" },
{ "Directory Map",2,"2.16.840.1.113719.1.1.6.1.7","Resource",NULL,NULL,"Host Server","Path" },
{ "Profile",2,"2.16.840.1.113719.1.1.6.1.19","Top","Organization,Organizational Unit","CN","CN,Login Script","Description,L,OU,O,See Also,Full Name" },
{ "Server",0,"2.16.840.1.113719.1.1.6.1.22","Top","Organization,Organizational Unit","CN","CN","Description,Host Device,L,OU,O,Private Key,Public Key,Resource,See Also,Status,User,Version,Network Address,Account Balance,Allow Unlimited Credit,Minimum Account Balance,Full Name,Security Equals,Security Flags,Timezone" },
{ "NCP Server",2,"2.16.840.1.113719.1.1.6.1.10","Server",NULL,NULL,NULL,"Operator,Supported Services,Messaging Server,DS Revision,Permanent Config Parms" },
{ "Print Server",2,"2.16.840.1.113719.1.1.6.1.18","Server",NULL,NULL,NULL,"Operator,Printer,SAP Name" },
{ "CommExec",2,"2.16.840.1.113719.1.1.6.1.31","Server",NULL,NULL,NULL,"Network Address Restriction" },
{ "Bindery Object",2,"2.16.840.1.113719.1.1.6.1.2","Top","Organization,Organizational Unit","CN,Bindery Type","Bindery Object Restriction,Bindery Type,CN",NULL },
{ "Unknown",3,"2.16.840.1.113719.1.1.6.1.24","Top",NULL,NULL,NULL,NULL },
{ "Partition",0,"2.16.840.1.113719.1.1.6.1.15",NULL,NULL,NULL,NULL,"Convergence,Partition Creation Time,Replica,Inherited ACL,Low Convergence Sync Interval,Received Up To,Synchronized Up To,Authority Revocation,Certificate Revocation,CA Private Key,CA Public Key,Cross Certificate Pair,Low Convergence Reset Time,High Convergence Sync Interval,Partition Control,Replica Up To,Partition Status,Transitive Vector,Purge Vector,Synchronization Tolerance,Obituary Notify,Local Received Up To" },
{ "AFP Server",2,"2.16.840.1.113719.1.1.6.1.0","Server",NULL,NULL,NULL,"Serial Number,Supported Connections" },
{ "Messaging Server",2,"2.16.840.1.113719.1.1.6.1.27","Server",NULL,NULL,NULL,"Messaging Database Location,Message Routing Group,Postmaster,Supported Services,Messaging Server Type,Supported Gateway" },
{ "Message Routing Group",2,"2.16.840.1.113719.1.1.6.1.28","Group",NULL,NULL,NULL,NULL },
{ "External Entity",2,"2.16.840.1.113719.1.1.6.1.29","Top","Organization,Organizational Unit","CN,OU","CN","Description,See Also,Facsimile Telephone Number,L,EMail Address,OU,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,S,SA,Title,External Name,Mailbox Location,Mailbox ID" },
{ "List",2,"2.16.840.1.113719.1.1.6.1.30","Top","Organization,Organizational Unit","CN","CN","Description,L,Member,OU,O,EMail Address,Mailbox Location,Mailbox ID,Owner,See Also,Full Name" },
{ NULL,0,NULL,NULL,NULL,NULL,NULL,NULL }
};
#endif /* MDBP_H */
+33
View File
@@ -0,0 +1,33 @@
# -*- Makefile -*-
if HAVE_LDAP
mdb_LTLIBRARIES += libmdbldap.la
endif
libmdbldap_la_SOURCES := \
src/libs/mdb-xldap/valarray.c \
src/libs/mdb-xldap/schema.c \
src/libs/mdb-xldap/mdbldap.c \
src/libs/mdb-xldap/mdbldapp.h
libmdbldap_la_CPPFLAGS := $(AM_CPPFLAGS) \
-DLOCALSTATEDIR=\""$(localstatedir)"\" \
-DMDB_INTERNAL
libmdbldap_la_LDFLAGS = -module -avoid-version
libmdbldap_la_LIBADD := \
$(LDAP_LIBS) \
libbongoutil.la \
libbongoxpl.la \
libbongomemmgr.la \
libbongostreamio.la \
$(top_builddir)/import/log4c/log4c/libbongolog4c.la
if HAVE_LDAP
src/libs/mdb-xldap/all: libmdbldap.la
src/libs/mdb-xldap/install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) mdb_LTLIBRARIES=libmdbldap.la install-mdbLTLIBRARIES
else
src/libs/mdb-xldap/all:
src/libs/mdb-xldap/install:
endif
src/libs/mdb-xldap/clean: clean
+17
View File
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
File diff suppressed because it is too large Load Diff
+146
View File
@@ -0,0 +1,146 @@
#define LDAP_DEPRECATED 1
#include <ldap.h>
#include <config.h>
#include <xpl.h>
/* compatibility with different client libraries */
#ifndef LDAP_CONST
#define LDAP_CONST const
#endif
#ifndef LDAP_OPT_SUCCESS
#define LDAP_OPT_SUCCESS 0
#endif
#ifndef LDAP_EXOP_MODIFY_PASSWD
#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
#endif
#ifndef LDAP_TAG_EXOP_MODIFY_PASSWD_ID
#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
#endif
#ifndef LDAP_TAG_EXOP_MODIFY_PASSWD_OLD
#define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U)
#endif
#ifndef LDAP_TAG_EXOP_MODIFY_PASSWD_NEW
#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
#endif
#ifndef LBER_USE_DER
#define LBER_USE_DER 0x01
#endif
#define MDBLDAP_FLAGS_ALLOCATED_HANDLE (unsigned long)(1 << 0)
#define MDBLDAP_FLAGS_CONTEXT_VALID (unsigned long)(1 << 1)
#define MDBLDAP_FLAGS_CONTEXT_DUPLICATE (unsigned long)(1 << 2)
#define MDBLDAP_FLAGS_BASEDB_CHANGED (unsigned long)(1 << 3)
#define MDBLDAP_MIN_CONNECTIONS 4
#define MDBLDAP_MAX_CONNECTIONS 8
#define MDBLDAP_DEFAULT_CACHE_SIZE 512
#define VALUE_ALLOC_SIZE 20
typedef struct {
unsigned char Description[128];
struct _MDBInterfaceStruct *Interface;
char *binddn;
char *passwd;
struct {
int next;
int min;
int max;
XplMutex mutex;
LDAP **list;
} conn;
} MDBLDAPContextStruct;
typedef MDBLDAPContextStruct *MDBHandle;
typedef struct {
unsigned char **Value;
unsigned long Used;
unsigned long ErrNo;
struct _MDBInterfaceStruct *Interface;
MDBLDAPContextStruct *context;
LDAP *ldap;
unsigned char *base;
unsigned char *lastDn;
unsigned long allocated;
BOOL duplicate;
} MDBValueStruct;
typedef struct {
char **vals;
int next;
int count;
} MDBEnumStruct;
#ifndef MDB_INTERNAL
#define MDB_INTERNAL
#endif
#include <mdb.h>
/* schema.c */
typedef struct {
char *val;
char *oid;
char **names;
int namecnt;
char *desc;
char *equality;
char *syntax;
char *sup;
BOOL singleval;
int refcnt;
BOOL visited;
} MDBLDAPSchemaAttr;
typedef enum {
TYPE_ABSTRACT,
TYPE_AUXILIARY,
TYPE_STRUCTURAL
} ClassTypeEnum;
typedef struct {
char *val;
char *oid;
char **names;
char *desc;
char **sup;
char **must;
char **may;
char *naming;
ClassTypeEnum type;
int refcnt;
BOOL visited;
} MDBLDAPSchemaClass;
#define MDBLDAP_SYNTAX_DN(syntax) \
!strncmp((syntax), "1.3.6.1.4.1.1466.115.121.1.12", 29)
#define MDBLDAP_SYNTAX_STRING(syntax) \
!strncmp((syntax), "1.3.6.1.4.1.1466.115.121.1.15", 29)
BOOL ParseAttributeTypeDescription(char *ptr, MDBLDAPSchemaAttr *attr);
BOOL ParseObjectClassDescription(char *ptr, MDBLDAPSchemaClass *class);
/* valarray.c */
typedef char * (* TranslateFunction) (const char *val, const char *opt);
inline char **NewValArray(int size);
inline void FreeValArray(char **vals);
inline int CountValArray(char **vals);
inline char **CopyValArray(char **vals);
inline BOOL ExpandValArray(char ***vals, int size);
inline unsigned int ValueStructToValArray(MDBValueStruct *v, char **vals);
inline int ValArrayToValueStruct(char **vals, MDBValueStruct *v);
inline char **TranslateValArray(char **in, TranslateFunction transfunc, char *opt);
inline unsigned int TranslateValueStructToValArray(MDBValueStruct *v, char **vals, TranslateFunction transfunc, char *opt);
inline int TranslateValArrayToValueStruct(char **vals, MDBValueStruct *v, TranslateFunction transfunc, char *opt);
BOOL MDBLDAPAddValue(const unsigned char *Value, MDBValueStruct *V);
BOOL MDBLDAPFreeValues(MDBValueStruct * V);
EXPORT BOOL MDBLDAPInit(MDBDriverInitStruct *Init);
EXPORT void MDBLDAPShutdown(void);
+286
View File
@@ -0,0 +1,286 @@
#include <string.h>
#include "mdbldapp.h"
#define CHARS_WHITESPACE " \t\n\f\r"
#define CHARS_DIGIT "0123456789"
#define CHARS_ALPHA_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define CHARS_ALPHA_LOWER "abcdefghijklmnopqrstuvwxyz"
#define CHARS_ALPHA CHARS_ALPHA_UPPER CHARS_ALPHA_LOWER
#define CHARS_ALPHANUM CHARS_DIGIT CHARS_ALPHA
#define CHARS_WORD "_" CHARS_ALPHANUM
#define CHARS_WHSP CHARS_WHITESPACE
#define CHARS_OID "-." CHARS_WORD
/**
* Find the first character not among the characters in 'except'.
*/
static char *strnot(const char *string, const char *except) {
char *s = (char *) string;
char *e = (char *) except;
while (*s != '\0') {
while (*e != '\0') {
if (*s == *e) {
s++;
break;
}
e++;
}
if (*e == '\0') {
break;
}
e = (char *) except;
}
return s;
}
/**
* Return true if c is among the characters in 'accept'.
*/
static int charin(int c, const char *accept) {
char *a = (char *) accept;
while (*a != '\0') {
if (c == *a) {
return 1;
}
a++;
}
return 0;
}
static char *ParseOid(char *ptr, char **oid) {
if (!charin(*ptr, CHARS_OID)) {
return NULL;
}
*oid = ptr;
if (!(ptr = strchr(ptr, ' '))) {
return NULL;
}
*ptr++ = '\0';
return ptr;
}
static char *ParseQdescr(char *ptr, char **qdescr) {
if (*ptr != '\'') {
return NULL;
}
*qdescr = ++ptr;
if (!(ptr = strchr(ptr, '\''))) {
return NULL;
}
*ptr++ = '\0';
return ptr;
}
static char *ParseNoidlen(char *ptr, char **noidlen) {
/* Active Directory sometimes (incorrectly) uses quotes here */
if (*ptr == '\'') {
return ParseQdescr(ptr, noidlen);
}
if (!charin(*ptr, CHARS_OID)) {
return NULL;
}
*noidlen = ptr;
if (!(ptr = strchr(ptr, ' '))) {
}
*ptr++ = '\0';
return ptr;
}
static char *ParseOids(char *ptr, char ***oids) {
int inc = 4;
int idx = 0;
*oids = NewValArray(inc);
if (!*oids) {
return NULL;
}
if (*ptr == '(') {
ptr = strnot(ptr + 1, CHARS_WHSP);
while (ptr && *ptr != ')') {
if (!(idx % inc)) {
if (!ExpandValArray(oids, idx + inc)) {
FreeValArray(*oids);
free(*oids);
return NULL;
}
}
if (!(ptr = ParseOid(ptr, &((*oids)[idx++]))) ||
!(ptr = strnot(ptr, "$" CHARS_WHSP))) {
break;
}
}
if (!ptr || *ptr != ')') {
FreeValArray(*oids);
free(*oids);
return NULL;
}
} else if (charin(*ptr, CHARS_OID)) {
ptr = ParseOid(ptr, &((*oids)[idx++]));
} else {
FreeValArray(*oids);
free(*oids);
return NULL;
}
return ptr;
}
static char *ParseQdescrs(char *ptr, char ***qdescrs) {
int inc = 4;
int idx = 0;
*qdescrs = NewValArray(inc);
if (!*qdescrs) {
return NULL;
}
if (*ptr == '(') {
ptr = strnot(ptr + 1, CHARS_WHSP);
while (ptr && *ptr != ')') {
if (!(idx % inc)) {
if (!ExpandValArray(qdescrs, idx + inc)) {
FreeValArray(*qdescrs);
free(*qdescrs);
return NULL;
}
}
if (!(ptr = ParseQdescr(ptr, &((*qdescrs)[idx++]))) ||
!(ptr = strnot(ptr, CHARS_WHSP))) {
break;
}
}
if (!ptr || *ptr != ')') {
FreeValArray(*qdescrs);
free(*qdescrs);
return NULL;
}
} else if (*ptr == '\'') {
if (!(ptr = ParseQdescr(ptr, &((*qdescrs)[idx++])))) {
FreeValArray(*qdescrs);
free(*qdescrs);
return NULL;
}
} else {
FreeValArray(*qdescrs);
free(*qdescrs);
return NULL;
}
return ptr;
}
BOOL ParseAttributeTypeDescription(char *ptr, MDBLDAPSchemaAttr *attr) {
char *tmp;
ptr = strnot(ptr, CHARS_WHSP);
if (*ptr != '(') {
return FALSE;
}
if (!(ptr = strnot(ptr + 1, CHARS_WHSP)) ||
!(ptr = ParseOid(ptr, &attr->oid))) {
return FALSE;
}
if ((tmp = strstr(ptr, "NAME"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 4, CHARS_WHSP)) ||
!(ptr = ParseQdescrs(ptr, &attr->names))) {
return FALSE;
}
}
if ((tmp = strstr(ptr, "SUP"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 3, CHARS_WHSP)) ||
!(ptr = ParseOid(ptr, &attr->sup))) {
return FALSE;
}
}
if ((tmp = strstr(ptr, "EQUALITY"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 8, CHARS_WHSP)) ||
!(ptr = ParseOid(ptr, &attr->equality))) {
return FALSE;
}
}
if ((tmp = strstr(ptr, "SYNTAX"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 6, CHARS_WHSP)) ||
!(ptr = ParseNoidlen(ptr, &attr->syntax))) {
return FALSE;
}
}
if (!(ptr = strnot(ptr, CHARS_WHSP)) &&
!strncmp(ptr, "SINGLE-VALUE", 12)) {
attr->singleval = TRUE;
}
return TRUE;
}
BOOL ParseObjectClassDescription(char *ptr, MDBLDAPSchemaClass *class) {
char *tmp;
ptr = strnot(ptr, CHARS_WHSP);
if (*ptr != '(') {
return FALSE;
}
if (!(ptr = strnot(ptr + 1, CHARS_WHSP)) ||
!(ptr = ParseOid(ptr, &class->oid))) {
return FALSE;
}
if ((tmp = strstr(ptr, "NAME"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 4, CHARS_WHSP)) ||
!(ptr = ParseQdescrs(ptr, &class->names))) {
return FALSE;
}
}
if ((tmp = strstr(ptr, "SUP"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 3, CHARS_WHSP)) ||
!(ptr = ParseOids(ptr, &class->sup))) {
return FALSE;
}
}
/*
ptr = strnot(ptr, CHARS_WHSP);
if (!strncmp(ptr, "ABSTRACT", 8) ||
!strncmp(ptr, "STRUCTURAL", 10) ||
!strncmp(ptr, "AUXILIARY", 9)) {
type = ptr;
if (!(ptr = strchr(ptr, ' '))) {
return FALSE;
}
*ptr++ = '\0';
}
*/
if ((tmp = strstr(ptr, "MUST"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 4, CHARS_WHSP)) ||
!(ptr = ParseOids(ptr, &class->must))) {
return FALSE;
}
}
if ((tmp = strstr(ptr, "MAY"))) {
ptr = tmp;
if (!(ptr = strnot(ptr + 3, CHARS_WHSP)) ||
!(ptr = ParseOids(ptr, &class->may))) {
return FALSE;
}
}
return TRUE;
}
+213
View File
@@ -0,0 +1,213 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2006 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include "mdbldapp.h"
/**
* Functions for handling char ** arrays.
*/
inline char **
NewValArray(int size)
{
char **vals;
vals = malloc(sizeof(char *) * (size + 1));
if (vals) {
memset(vals, 0, sizeof(char *) * (size + 1));
}
return vals;
}
inline void
FreeValArray(char **vals)
{
int i;
for (i = 0; vals[i]; i++) {
free(vals[i]);
vals[i] = NULL;
}
/*free(vals);*/
}
inline int
CountValArray(char **vals)
{
int i;
for (i = 0; vals[i]; i++);
return i;
}
inline char **
CopyValArray(char **vals)
{
char **dup;
int count;
int i;
count = CountValArray(vals);
dup = NewValArray(count);
if (dup) {
for (i = 0; vals[i]; i++) {
dup[i] = strdup(vals[i]);
if (!dup[i]) {
break;
}
}
if (i < count) {
FreeValArray(dup);
free(dup);
dup = NULL;
}
}
return dup;
}
inline BOOL
ExpandValArray(char ***vals, int size)
{
char **tmps;
char **ptr;
int count;
int ext;
count = CountValArray(*vals);
ext = size - count;
if (ext > 0) {
tmps = realloc(*vals, (sizeof(char *) * (size + 1)));
if (tmps) {
ptr = tmps + count + 1;
memset(ptr, 0, (sizeof(char *) * ext));
*vals = tmps;
return TRUE;
}
}
return FALSE;
}
inline unsigned int
ValueStructToValArray(MDBValueStruct *v, char **vals)
{
unsigned int i;
for (i = 0; i < v->Used; i++) {
vals[i] = strdup((char *)(v->Value[i]));
if (!vals[i]) {
break;
}
}
if (i < v->Used) {
FreeValArray(vals);
return 0;
}
return i;
}
inline int
ValArrayToValueStruct(char **vals, MDBValueStruct *v)
{
int i;
int count;
count = CountValArray(vals);
for (i = 0; vals[i]; i++) {
if (!MDBLDAPAddValue((unsigned char *)(vals[i]), v)) {
break;
}
}
if (i < count) {
return 0;
}
return i;
}
inline char **
TranslateValArray(char **in, TranslateFunction transfunc, char *opt)
{
char **out;
int count;
int i;
count = CountValArray(in);
out = NewValArray(count);
if (out) {
for (i = 0; in[i]; i++) {
out[i] = transfunc(in[i], opt);
if (!out[i]) {
break;
}
}
if (i < count) {
FreeValArray(out);
free(out);
out = NULL;
}
}
return out;
}
inline unsigned int
TranslateValueStructToValArray(MDBValueStruct *v, char **vals,
TranslateFunction transfunc, char *opt)
{
unsigned int i;
for (i = 0; i < v->Used; i++) {
vals[i] = transfunc((char *)(v->Value[i]), opt);
if (!vals[i]) {
break;
}
}
if (i < v->Used) {
FreeValArray(vals);
return 0;
}
return i;
}
inline int
TranslateValArrayToValueStruct(char **vals, MDBValueStruct *v,
TranslateFunction transfunc, char *opt)
{
char *val;
int count;
int i;
count = CountValArray(vals);
for (i = 0; vals[i]; i++) {
val = transfunc(vals[i], opt);
if (val) {
if (!MDBLDAPAddValue((unsigned char *)val, v)) {
break;
}
free(val);
} else {
break;
}
}
if (i < count) {
return 0;
}
return i;
}
+21
View File
@@ -0,0 +1,21 @@
# -*- Makefile -*-
mdbdir = $(libdir)/bongomdb
mdb_LTLIBRARIES :=
lib_LTLIBRARIES += libbongomdb.la
libbongomdb_la_SOURCES := \
src/libs/mdb/mdb.c \
src/libs/mdb/mdbp.h
libbongomdb_la_CPPFLAGS := $(AM_CPPFLAGS) \
-DDRIVER_EXTENSION=\"$(SHARED_POSTFIX)\" \
-DSYSCONF_DIR=\""$(sysconfdir)"\" \
-DDRIVER_DIR=\""$(libdir)/bongomdb"\"
libbongomdb_la_LIBADD := \
libbongoxpl.la \
$(DL_LIBS)
src/libs/mdb/all: libbongomdb.la
src/libs/mdb/clean: clean
+17
View File
@@ -0,0 +1,17 @@
# -*- Makefile -*-
#
# Do not edit!
#
# (unless this is Makefile.am.subdir)
#
# This file is a copy of the toplevel Makefile.am.subdir. If changes
# need to be made, edit that file, and make update-makefiles, and
# check the new files in.
#
# This is a skeletal automake file. The real automake fules for
# building the targets for this directory can be found in the
# Bongo.rules file. This file is simply here so that 'make all' can
# work in each subdirectory.
all clean install:
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
+887
View File
@@ -0,0 +1,887 @@
/*
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
*/
/* We use bongo-specific keys/dirs here rather than mdb, so that we don't conflict before
* we merge */
#include <config.h>
#include <xpl.h>
#include <errno.h>
#include <signal.h>
/* Local modification, bongo's xpl no longer defines these */
#include <mdb.h>
#include "mdbp.h"
/* Globals */
LONG Tid;
LONG TGid;
XplSemaphore ShutdownSemaphore;
BOOL MDBInitialized = FALSE;
BOOL MDBLoading = FALSE;
BOOL MDBFailed = FALSE;
#define ChopNL(String) { unsigned char *pTr; pTr=strchr((String), 0x0a); if (pTr) *pTr='\0'; pTr=strrchr((String), 0x0d); if (pTr) *pTr='\0'; }
#if defined(NETWARE)
#define MDB_CONFIG_INIT
#define MDB_CONFIG_FILE "sys:/etc/mdb.cfg"
unsigned char DriverDir[XPL_MAX_PATH+1] = "sys:\\system";
#elif defined(WIN32)
#define MDB_CONFIG_INIT { \
HKEY HKey; \
GetWindowsDirectory(MDB_CONFIG_FILE, sizeof(MDB_CONFIG_FILE)); \
strcat(MDB_CONFIG_FILE, "/mdb.cfg"); \
\
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Bongo\\MDB", 0, KEY_READ, &HKey)==ERROR_SUCCESS) { \
DWORD BufSize=XPL_MAX_PATH; \
RegQueryValueEx(HKey, "DriverDir", NULL, NULL, DriverDir, &BufSize); \
RegCloseKey(HKey); \
} \
}
unsigned char MDB_CONFIG_FILE[256+1];
unsigned char DriverDir[XPL_MAX_PATH+1] = "C:\\program files\\Bongo\\MDB";
#elif defined(SUSE) || defined(LINUX) || defined(S390RH) || defined(REDHAT) || defined(SOLARIS) || defined(MACOSX)
#define MDB_CONFIG_INIT
#define MDB_CONFIG_FILE XPL_DEFAULT_CONF_DIR "/mdb.conf"
unsigned char DriverDir[XPL_MAX_PATH+1] = DRIVER_DIR;
#endif
typedef struct _MDBDriverStruct {
unsigned char Driver[256];
BOOL Primary;
MDBDriverInitFunc Init;
MDBDriverShutdownFunc Shutdown;
MDBInterfaceStruct Interface;
XplPluginHandle Handle;
void *Data;
} MDBDriverStruct;
typedef struct {
unsigned char Module[XPL_MAX_PATH];
unsigned char Driver[XPL_MAX_PATH];
unsigned char Arguments[512];
} MDBModuleStruct;
unsigned long MDBDriverCount = 0;
MDBDriverStruct *MDBDrivers = NULL;
unsigned long MDBModuleCount = 0;
unsigned long MDBModuleAlloc = 0;
MDBModuleStruct *MDBModules = NULL;
unsigned long MDBDefaultDriver = 0;
static unsigned long
MDBFindDriver(const unsigned char *Driver)
{
unsigned long i;
for (i=0; i<MDBDriverCount; i++) {
if (XplStrCaseCmp(MDBDrivers[i].Driver, Driver)==0) {
return(i);
}
}
return(-1);
}
static XplPluginHandle
MDBGetDriverHandle(const unsigned char *Driver)
{
unsigned long i;
for (i=0; i<MDBDriverCount; i++) {
if (XplStrCaseCmp(MDBDrivers[i].Driver, Driver)==0) {
return(MDBDrivers[i].Handle);
}
}
return(NULL);
}
static unsigned long
MDBInitDriver (MDBDriverStruct *Driver,
const unsigned char *Arguments,
unsigned char *Error)
{
unsigned char FuncName[XPL_MAX_PATH+sizeof ("Shutdown")];
MDBDriverInitStruct Init;
strcpy (FuncName, Driver->Driver);
strcat (FuncName, "Init");
/* FIXME: what do we do about DriverName here */
Driver->Init=(MDBDriverInitFunc)XplGetDLLFunction(DriverName, FuncName, Driver->Handle);
if (!Driver->Init) {
if (Error) sprintf(Error, "Driver %s, missing Init function", Driver->Driver);
if (Driver->Primary) {
XplUnloadDLL(Driver->Driver, Driver->Handle);
}
return(-1);
}
/* Grab the shutdown function */
strcpy(FuncName, Driver->Driver);
strcat(FuncName, "Shutdown");
Driver->Shutdown=(MDBDriverShutdownFunc)XplGetDLLFunction(DriverName, FuncName, Driver->Handle);
if (!Driver->Shutdown) {
if (Error) sprintf(Error, "Driver %s, missing Shutdown function", Driver->Driver);
if (Driver->Primary) {
XplUnloadDLL(Driver->Driver, Driver->Handle);
}
return(-1);
}
memset(&Init, 0, sizeof(Init));
Init.Arguments=Arguments;
if (!Driver->Init(&Init)) {
if (Error) sprintf(Error, "Driver %s, Init failed with: %s", Driver->Driver, Init.Error);
Driver->Shutdown();
/* Can't unload for now; dclient creates a bunch of threads and they go to hell if we unload this dll */
//XplUnloadDLL(Driver->Driver, Driver->Handle);
return(-1);
}
memcpy(&Driver->Interface, &Init.Interface, sizeof(MDBInterfaceStruct));
return 0;
}
static unsigned long
MDBLoadDriver(const unsigned char *DriverNameIn, const unsigned char *Arguments, unsigned char *Error)
{
unsigned char DriverName[XPL_MAX_PATH+1];
unsigned char Name[XPL_MAX_PATH+1];
unsigned char *ptr;
MDBDriverStruct *Driver;
/* First, make sure there's enough space in our list */
MDBDrivers=realloc(MDBDrivers, sizeof(MDBDriverStruct)*(MDBDriverCount+1));
if (!MDBDrivers) {
return(-1);
}
Driver=&MDBDrivers[MDBDriverCount];
memset(Driver, 0, sizeof(MDBDriverStruct));
strcpy(DriverName, DriverNameIn);
ptr=DriverName;
while (*ptr) {
*ptr=tolower(*ptr);
ptr++;
}
TryAgain:
if ((strchr(DriverNameIn, '/')==NULL) && (strchr(DriverNameIn, '\\')==NULL)) {
if ((strlen(DriverName)<5) || (XplStrNCaseCmp(DriverName+strlen(DriverName)-strlen(DRIVER_EXTENSION), DRIVER_EXTENSION, strlen(DRIVER_EXTENSION))!=0)) {
ptr=strrchr(DriverName, '.');
if (ptr && XplStrNCaseCmp(ptr,".NLM", 4)==0) {
strcpy(ptr, DRIVER_EXTENSION);
goto TryAgain;
} else {
/* No period means possibly no extension, let's add our default extension */
strcat(DriverName, DRIVER_EXTENSION);
goto TryAgain;
}
if (Error) strcpy(Error, "Bad driver extension");
return(-1);
}
} else {
unsigned char *ptr;
if ((ptr=strrchr(DriverNameIn, '/'))==NULL) {
ptr=strrchr(DriverNameIn, '\\');
}
ptr++;
strcpy(DriverName, ptr);
}
strcpy(Name, DriverName);
Name[strlen(Name)-strlen(DRIVER_EXTENSION)]='\0';
ptr=Name;
while (*ptr) {
*ptr=toupper(*ptr);
ptr++;
}
Driver->Handle=MDBGetDriverHandle(DriverName);
if (!Driver->Handle) {
if (!(strchr(DriverNameIn, '/')==NULL) && (strchr(DriverNameIn, '\\')==NULL)) {
/* Use the absolute path if it was passed */
Driver->Handle=XplLoadDLL(DriverNameIn);
} else {
/* Otherwise try <name> then lib<name> */
unsigned char Path[XPL_MAX_PATH + 1];
sprintf(Path, "%s%c%s", DriverDir, XPL_DIR_SEPARATOR, DriverName);
Driver->Handle=XplLoadDLL(Path);
if (!Driver->Handle) {
sprintf(Path, "%s%clib%s", DriverDir, XPL_DIR_SEPARATOR, DriverName);
Driver->Handle=XplLoadDLL(Path);
}
}
Driver->Primary=TRUE;
}
if (!Driver->Handle) {
if (Error) sprintf(Error, "Could not load driver, error %d", errno);
return(-1);
}
/* Give the module a chance to initialize */
strcpy(Driver->Driver, Name);
if (MDBInitDriver (Driver, Arguments, Error) == 0) {
//XplConsolePrintf("MDBDriver '%s', successfully loaded\n", DriverName);
return(MDBDriverCount++);
} else {
return(-1);
}
}
EXPORT int
MDBGetAPIVersion(BOOL WantCompatibleVersion, unsigned char *Description, MDBHandle Context)
{
if (Description) {
if (Context) {
strncpy(Description, ((MDBContextCacheStruct *)Context)->Description, MDB_MAX_API_DESCRIPTION_CHARS-1);
} else {
strcpy(Description, "<undefined>");
}
}
if (WantCompatibleVersion) {
return(MDB_COMPATIBLE_TO_API);
} else {
return(MDB_CURRENT_API_VERSION);
}
}
EXPORT BOOL
MDBGetServerInfo(unsigned char *HostDN, unsigned char *HostTree, MDBValueStruct *V)
{
if (!V) {
return(MDBDrivers[MDBDefaultDriver].Interface.MDBGetServerInfo(HostDN, HostTree, V));
} else {
return(V->Interface->MDBGetServerInfo(HostDN, HostTree, V));
}
}
EXPORT char *
MDBGetBaseDN(MDBValueStruct *V)
{
if (!V) {
return(MDBDrivers[MDBDefaultDriver].Interface.MDBGetBaseDN(V));
} else {
return(V->Interface->MDBGetBaseDN(V));
}
}
/* Authentication */
EXPORT MDBHandle
MDBAuthenticate(const unsigned char *Module, const unsigned char *Object, const unsigned char *Password)
{
unsigned int i;
unsigned long Driver=MDBDefaultDriver;
MDBHandle Handle;
unsigned char *Arguments=NULL;
for (i=0; i<MDBModuleCount; i++) {
if (XplStrCaseCmp(Module, MDBModules[i].Module)==0) {
Driver=MDBFindDriver(MDBModules[i].Driver);
if (Driver!=(unsigned long)-1) {
Arguments=MDBModules[Driver].Arguments;
} else {
Driver=MDBDefaultDriver;
}
}
}
Handle=MDBDrivers[Driver].Interface.MDBAuthenticate(Object, Password, Arguments);
if (Handle) {
((MDBContextCacheStruct *)Handle)->Interface=&MDBDrivers[Driver].Interface;
}
return(Handle);
}
EXPORT BOOL
MDBRelease(MDBHandle Handle)
{
if (Handle) {
return(((MDBContextCacheStruct *)Handle)->Interface->MDBRelease(Handle));
} else {
return(FALSE);
}
}
EXPORT MDBValueStruct
*MDBCreateValueStruct(MDBHandle Handle, const unsigned char *Context)
{
MDBValueStruct *V;
V=((MDBContextCacheStruct *)Handle)->Interface->MDBCreateValueStruct(Handle, Context);
if (V) {
V->Interface=((MDBContextCacheStruct *)Handle)->Interface;
}
return(V);
}
EXPORT BOOL
MDBDestroyValueStruct(MDBValueStruct *V)
{
return(V->Interface->MDBDestroyValueStruct(V));
}
EXPORT MDBValueStruct
*MDBShareContext(MDBValueStruct *VOld)
{
MDBValueStruct *VNew;
VNew=VOld->Interface->MDBShareContext(VOld);
if (VNew) {
VNew->Interface=VOld->Interface;
}
return(VNew);
}
EXPORT BOOL
MDBSetValueStructContext(const unsigned char *Context, MDBValueStruct *V)
{
return(V->Interface->MDBSetValueStructContext(Context, V));
}
EXPORT MDBEnumStruct
*MDBCreateEnumStruct(MDBValueStruct *V)
{
return(V->Interface->MDBCreateEnumStruct(V));
}
EXPORT BOOL
MDBDestroyEnumStruct(MDBEnumStruct *E, MDBValueStruct *V)
{
return(V->Interface->MDBDestroyEnumStruct(E, V));
}
EXPORT BOOL
MDBAddValue(const unsigned char *Value, MDBValueStruct *V)
{
return(V->Interface->MDBAddValue(Value, V));
}
EXPORT BOOL
MDBFreeValue(unsigned long Index, MDBValueStruct *V)
{
return(V->Interface->MDBFreeValue(Index, V));
}
EXPORT BOOL
MDBFreeValues(MDBValueStruct *V)
{
return(V->Interface->MDBFreeValues(V));
}
EXPORT long
MDBRead(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
{
return(V->Interface->MDBRead(Object, Attribute, V));
}
EXPORT const unsigned char
*MDBReadEx(const unsigned char *Object, const unsigned char *Attribute, MDBEnumStruct *E, MDBValueStruct *V)
{
return(V->Interface->MDBReadEx(Object, Attribute, E, V));
}
EXPORT long
MDBReadDN(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
{
return(V->Interface->MDBReadDN(Object, Attribute, V));
}
EXPORT BOOL
MDBWriteTyped(const unsigned char *Object, const unsigned char *Attribute, const int AttrType, MDBValueStruct *V)
{
return(V->Interface->MDBWriteTyped(Object, Attribute, AttrType, V));
}
EXPORT BOOL
MDBWrite(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
{
return(V->Interface->MDBWrite(Object, Attribute, V));
}
EXPORT BOOL
MDBWriteDN(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
{
return(V->Interface->MDBWriteDN(Object, Attribute, V));
}
EXPORT BOOL
MDBClear(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
{
return(V->Interface->MDBClear(Object, Attribute, V));
}
EXPORT BOOL
MDBAdd(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
{
return(V->Interface->MDBAdd(Object, Attribute, Value, V));
}
EXPORT BOOL
MDBAddDN(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
{
return(V->Interface->MDBAddDN(Object, Attribute, Value, V));
}
EXPORT BOOL
MDBRemove(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
{
return(V->Interface->MDBRemove(Object, Attribute, Value, V));
}
EXPORT BOOL
MDBRemoveDN(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
{
return(V->Interface->MDBRemoveDN(Object, Attribute, Value, V));
}
EXPORT BOOL
MDBIsObject(const unsigned char *Object, MDBValueStruct *V)
{
return(V->Interface->MDBIsObject(Object, V));
}
EXPORT BOOL
MDBGetObjectDetails(const unsigned char *Object, unsigned char *Type, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V)
{
return(V->Interface->MDBGetObjectDetails(Object, Type, RDN, DN, V));
}
EXPORT BOOL
MDBGetObjectDetailsEx(const unsigned char *Object, MDBValueStruct *Types, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V)
{
return(V->Interface->MDBGetObjectDetailsEx(Object, Types, RDN, DN, V));
}
EXPORT BOOL
MDBVerifyPassword(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V)
{
return(V->Interface->MDBVerifyPassword(Object, Password, V));
}
EXPORT BOOL
MDBVerifyPasswordEx(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V)
{
return(V->Interface->MDBVerifyPasswordEx(Object, Password, V));
}
EXPORT BOOL
MDBChangePassword(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V)
{
return(V->Interface->MDBChangePassword(Object, OldPassword, NewPassword, V));
}
EXPORT BOOL
MDBChangePasswordEx(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V)
{
return(V->Interface->MDBChangePasswordEx(Object, OldPassword, NewPassword, V));
}
EXPORT long
MDBEnumerateObjects(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, MDBValueStruct *V)
{
return(V->Interface->MDBEnumerateObjects(Container, Type, Pattern, V));
}
EXPORT const unsigned char
*MDBEnumerateObjectsEx(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, unsigned long Flags, MDBEnumStruct *E, MDBValueStruct *V)
{
return(V->Interface->MDBEnumerateObjectsEx(Container, Type, Pattern, Flags, E, V));
}
EXPORT const unsigned char
*MDBEnumerateAttributesEx(const unsigned char *Object, MDBEnumStruct *E, MDBValueStruct *V)
{
return(V->Interface->MDBEnumerateAttributesEx(Object, E, V));
}
EXPORT BOOL
MDBCreateAlias(const unsigned char *Alias, const unsigned char *AliasedObjectDn, MDBValueStruct *V)
{
return(V->Interface->MDBCreateAlias(Alias, AliasedObjectDn, V));
}
EXPORT BOOL
MDBCreateObject(const unsigned char *Object, const unsigned char *Class, MDBValueStruct *Attribute, MDBValueStruct *Data, MDBValueStruct *V)
{
return(V->Interface->MDBCreateObject(Object, Class, Attribute, Data, V));
}
EXPORT BOOL
MDBDeleteObject(const unsigned char *Object, BOOL Recursive, MDBValueStruct *V)
{
return(V->Interface->MDBDeleteObject(Object, Recursive, V));
}
EXPORT BOOL
MDBRenameObject(const unsigned char *ObjectOld, const unsigned char *ObjectNew, MDBValueStruct *V)
{
return(V->Interface->MDBRenameObject(ObjectOld, ObjectNew, V));
}
EXPORT BOOL
MDBDefineAttribute(const unsigned char *Attribute, const unsigned char *ASN1, unsigned long Type, BOOL SingleValue, BOOL ImmediateSync, BOOL Public, MDBValueStruct *V)
{
return(V->Interface->MDBDefineAttribute(Attribute, ASN1, Type, SingleValue, ImmediateSync, Public, V));
}
EXPORT BOOL
MDBUndefineAttribute(const unsigned char *Attribute, MDBValueStruct *V)
{
return(V->Interface->MDBUndefineAttribute(Attribute, V));
}
EXPORT BOOL
MDBDefineClass(const unsigned char *Class, const unsigned char *ASN1, BOOL Container, MDBValueStruct *Superclass, MDBValueStruct *Containment, MDBValueStruct *Naming, MDBValueStruct *Mandatory, MDBValueStruct *Optional, MDBValueStruct *V)
{
return(V->Interface->MDBDefineClass(Class, ASN1, Container, Superclass, Containment, Naming, Mandatory, Optional, V));
}
EXPORT BOOL
MDBAddAttribute(const unsigned char *Attribute, const unsigned char *Class, MDBValueStruct *V)
{
return(V->Interface->MDBAddAttribute(Attribute, Class, V));
}
EXPORT BOOL
MDBUndefineClass(const unsigned char *Class, MDBValueStruct *V)
{
return(V->Interface->MDBUndefineClass(Class, V));
}
EXPORT BOOL
MDBListContainableClasses(const unsigned char *Container, MDBValueStruct *V)
{
return(V->Interface->MDBListContainableClasses(Container, V));
}
EXPORT const unsigned char
*MDBListContainableClassesEx(const unsigned char *Container, MDBEnumStruct *E, MDBValueStruct *V)
{
return(V->Interface->MDBListContainableClassesEx(Container, E, V));
}
EXPORT BOOL
MDBGrantObjectRights(const unsigned char *Object, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Delete, BOOL Rename, BOOL Admin, MDBValueStruct *V)
{
return(V->Interface->MDBGrantObjectRights(Object, TrusteeDN, Read, Write, Delete, Rename, Admin, V));
}
EXPORT BOOL
MDBGrantAttributeRights(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Admin, MDBValueStruct *V)
{
return(V->Interface->MDBGrantAttributeRights(Object, Attribute, TrusteeDN, Read, Write, Admin, V));
}
EXPORT BOOL
MDBFindObjects(const unsigned char *Container,
MDBValueStruct *Types,
const unsigned char *Pattern,
MDBValueStruct *Attributes,
int depth,
int max,
MDBValueStruct *V)
{
if (V->Interface->MDBFindObjects) {
return(V->Interface->MDBFindObjects(Container, Types, Pattern, Attributes, depth, max, V));
} else {
return FALSE;
}
}
EXPORT BOOL
MDBDumpValueStruct(MDBValueStruct *V)
{
unsigned long i;
if (!V->Used) {
XplConsolePrintf("No data in structure\n");
}
XplConsolePrintf("ValueStruct: Used:%lu\n", V->Used);
for (i=0; i<V->Used; i++) {
XplConsolePrintf("Value[%02lu] %-25s", i, V->Value[i]);
if (((i+1) % 2)==0) {
XplConsolePrintf("\n");
} else {
XplConsolePrintf(" | ");
}
}
XplConsolePrintf("\r\n");
return(TRUE);
}
/*
Config format:
DriverDir=<Directory>
Default=<Drivername>
Driver=<Drivername> [DriverArguments]
Module <Modulename>=<Drivername> [DriverArguments]
*/
static BOOL
MDBReadConfiguration(void)
{
FILE *Handle;
unsigned char Buffer[1024];
unsigned char Error[XPL_MAX_PATH*2];
unsigned char DefaultDriverName[XPL_MAX_PATH+1] = "";
MDB_CONFIG_INIT;
Handle=fopen(MDB_CONFIG_FILE, "rb");
if (!Handle) {
return(FALSE);
}
while (!ferror(Handle) && !feof(Handle)) {
if (fgets(Buffer, sizeof(Buffer), Handle)!=NULL) {
ChopNL(Buffer);
if (XplStrNCaseCmp(Buffer, "DriverDir=", 10)==0) {
strcpy(DriverDir, Buffer+10);
} else if (XplStrNCaseCmp(Buffer, "Module ", 7)==0) {
unsigned char *Module;
unsigned char *Driver;
unsigned char *Arguments;
if ((MDBModuleCount+1)>MDBModuleAlloc) {
MDBModules=realloc(MDBModules, sizeof(MDBModuleStruct)*(MDBModuleAlloc+10));
if (!MDBModules) {
fclose(Handle);
return(FALSE);
}
MDBModuleAlloc+=10;
}
Module=Buffer+7;
Driver=strchr(Module, '=');
if (Driver) {
*Driver='\0';
Driver++;
if ((Arguments=strchr(Driver, ' '))!=NULL) {
*Arguments='\0';
Arguments++;
}
strcpy(MDBModules[MDBModuleCount].Module, Module);
strcpy(MDBModules[MDBModuleCount].Driver, Driver);
if (Arguments) {
strcpy(MDBModules[MDBModuleCount].Arguments, Arguments);
} else {
MDBModules[MDBModuleCount].Arguments[0]='\0';
}
MDBModuleCount++;
}
} else if (XplStrNCaseCmp(Buffer, "Driver=", 7)==0) {
unsigned char *Arguments;
if ((Arguments=strchr(Buffer+7, ' '))!=NULL) {
*Arguments='\0';
Arguments++;
}
if (MDBLoadDriver(Buffer+7, Arguments, Error)==(unsigned long)-1) {
XplConsolePrintf("\rDriver %s failed to load:%s\n", Buffer+7, Error);
fclose(Handle);
return(FALSE);
}
} else if (XplStrNCaseCmp(Buffer, "Default=", 8)==0) {
strcpy(DefaultDriverName, Buffer+8);
}
}
}
fclose(Handle);
if (DefaultDriverName[0]!='\0') {
MDBDefaultDriver=MDBFindDriver(DefaultDriverName);
}
return(TRUE);
}
EXPORT BOOL
MDBInit(void)
{
if (MDBFailed) {
return FALSE;
}
if (!MDBInitialized && !MDBLoading) {
MDBLoading=TRUE;
/* Read configuration */
if (!MDBReadConfiguration()) {
unsigned char Error[XPL_MAX_PATH*2];
if ((MDBLoadDriver("MDBDS", NULL, Error)==(unsigned long)-1) && (MDBLoadDriver("MDBREG", NULL, Error)==(unsigned long)-1) && (MDBLoadDriver("MDBFILE", NULL, Error)==(unsigned long)-1)) {
MDBLoading = FALSE;
MDBFailed = TRUE;
XplConsolePrintf("Failed to load any MDB driver\n");
/* INSERT "fake" MDB driver here */
return(FALSE);
}
}
MDBInitialized=TRUE;
}
while (!MDBInitialized) {
XplDelay(100);
}
return(MDBInitialized);
}
EXPORT BOOL
MDBShutdown(void)
{
return(TRUE);
}
#if defined(NETWARE)
void
MDBSigHandler(int Signal)
{
int OldTGid;
unsigned long i;
OldTGid=XplSetThreadGroupID(TGid);
XplSignalLocalSemaphore(ShutdownSemaphore);
XplWaitOnLocalSemaphore(ShutdownSemaphore);
/* Do any required cleanup */
for (i=0; i<MDBDriverCount; i++) {
MDBDrivers[i].Shutdown();
XplUnloadDLL(MDBDrivers[i].Driver, MDBDrivers[i].Handle);
}
if (MDBDrivers) {
free(MDBDrivers);
}
if (MDBModules) {
free(MDBModules);
}
XplCloseLocalSemaphore(ShutdownSemaphore);
XplSetThreadGroupID(OldTGid);
}
int
main(int argc, char *argv[])
{
Tid=XplGetThreadID();
TGid=XplGetThreadGroupID();
signal(SIGTERM, MDBSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
MDBInit();
XplOpenLocalSemaphore(ShutdownSemaphore, 0);
XplWaitOnLocalSemaphore(ShutdownSemaphore);
XplSignalLocalSemaphore(ShutdownSemaphore);
return(0);
}
#endif
#if defined(WIN32)
BOOL WINAPI
DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
{
if (Reason==DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hInst);
}
return(TRUE);
}
#endif
+33
View File
@@ -0,0 +1,33 @@
/*
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
*/
#ifndef MDBP_H
#define MDBP_H
typedef struct {
unsigned char Description[128];
struct _MDBInterfaceStruct *Interface;
} MDBContextCacheStruct;
#endif /* MDBP_H */
+52 -20
View File
@@ -18,6 +18,7 @@ typedef struct {
MsgSQLStatement find_user;
MsgSQLStatement auth_user;
MsgSQLStatement add_user;
MsgSQLStatement list_user;
MsgSQLStatement set_password;
} MsgAuthStatements;
@@ -26,7 +27,7 @@ MsgAuthStatements msgauth_stmts;
int
AuthODBC_Init(void)
{
return 0;
return 0;
}
int
@@ -74,7 +75,7 @@ AuthSqlite_Install(void)
dcode = sqlite3_exec (handle->db,
"PRAGMA user_version=0;"
"CREATE TABLE users (username TEXT DEFAULT NULL,"
"CREATE TABLE users (username TEXT DEFAULT NULL UNIQUE,"
" password TEXT DEFAULT NULL"
");"
"INSERT INTO users (username, password)"
@@ -200,7 +201,7 @@ AuthSqlite_AddUser(const char *user)
handle = MsgSQLOpen(path, NULL, 1000);
if (NULL == handle) {
Log(LOG_ERROR, "Cannot open user db '%s'", path);
return -1;
return -10;
}
stmt = MsgSQLPrepare (handle,
@@ -209,12 +210,12 @@ AuthSqlite_AddUser(const char *user)
if (NULL == stmt) {
Log(LOG_ERROR, "Unable to prepare SQL statement in AddUser");
return 1;
return -11;
}
if (MsgSQLBindString(stmt, 1, user, TRUE)) return -2;
if (MsgSQLExecute(handle, stmt)) return -3;
if (MsgSQLBindString(stmt, 1, user, TRUE)) return -12;
if (MsgSQLExecute(handle, stmt)) return -13;
MsgSQLFinalize(stmt);
MsgSQLClose(handle);
@@ -230,12 +231,12 @@ AuthSqlite_SetPassword(const char *user, const char *password)
MsgSQLHandle *handle;
if (AuthSqlite_GenerateHash(user, password, hash, XPLHASH_SHA1_LENGTH + 1) != 0)
return -1;
return -10;
AuthSqlite_GetDbPath(path, XPL_MAX_PATH);
handle = MsgSQLOpen(path, NULL, 1000);
if (NULL == handle) {
Log(LOG_ERROR, "Cannot open user db '%s'", path);
return -2;
return -11;
}
stmt = MsgSQLPrepare (handle,
@@ -243,12 +244,12 @@ AuthSqlite_SetPassword(const char *user, const char *password)
&msgauth_stmts.set_password);
if (NULL == stmt) {
Log(LOG_ERROR, "Unable to prepare SQL in SetPassword()");
return 1;
return -12;
}
if (MsgSQLBindString(stmt, 1, hash, TRUE)) return -3;
if (MsgSQLBindString(stmt, 2, user, TRUE)) return -3;
if (MsgSQLExecute(handle, stmt)) return -3;
if (MsgSQLBindString(stmt, 1, hash, TRUE)) return -13;
if (MsgSQLBindString(stmt, 2, user, TRUE)) return -13;
if (MsgSQLExecute(handle, stmt)) return -14;
MsgSQLFinalize(stmt);
MsgSQLClose(handle);
@@ -267,18 +268,49 @@ AuthSqlite_GetUserStore(const char *user, struct sockaddr_in *store)
}
int
AuthSqlite_UserList(BongoArray **list)
AuthSqlite_UserList(char **list[])
{
/* TODO
BongoArray *userlist;
char **userlist;
MsgSQLStatement *stmt;
char path[XPL_MAX_PATH + 1];
MsgSQLHandle *handle;
int users = 0;
int alloc = 10;
userlist = BongoArrayNew(sizeof (char *), 0);
AuthSqlite_GetDbPath(path, XPL_MAX_PATH);
handle = MsgSQLOpen(path, NULL, 1000);
char *admin = strdup("admin");
BongoArrayAppendValue(userlist, admin);
if (NULL == handle) {
Log(LOG_ERROR, "Cannot open user db '%s'", path);
return 1;
}
stmt = MsgSQLPrepare (handle, "SELECT username FROM users;",
&msgauth_stmts.list_user);
if (NULL == stmt) {
Log(LOG_ERROR, "Unable to prepare SQL statement in ListUser");
return 1;
}
userlist = MemMalloc(sizeof(char *) * alloc);
{
int result;
while (1 == (result = MsgSQLStatementStep(handle, stmt))) {
userlist[users] = strdup((char *) sqlite3_column_text(stmt->stmt, 0));
users++;
if (users == alloc) {
alloc += 10;
userlist = MemRealloc(userlist, sizeof(char *) * alloc);
}
}
}
MsgSQLFinalize(stmt);
MsgSQLClose(handle);
userlist[users] = 0;
*list = userlist;
*/
return TRUE;
}
+1 -1
View File
@@ -7,6 +7,6 @@ int AuthSqlite_VerifyPassword(const char *user, const char *password);
int AuthSqlite_AddUser(const char *user);
int AuthSqlite_SetPassword(const char *user, const char *password);
int AuthSqlite_GetUserStore(const char *user, struct sockaddr_in *store);
int AuthSqlite_UserList(BongoArray **list);
int AuthSqlite_UserList(char **list[]);
int AuthSqlite_InterfaceVersion(void);
int AuthODBC_Init(void);
+29 -4
View File
@@ -153,7 +153,7 @@ MsgAuthVerifyPassword(const char *user, const char *password)
f = (AuthPlugin_VerifyPassword *)&function->func;
result = (*f)(user, password);
return result;
return result;
}
/* "Write" functions below */
@@ -169,9 +169,14 @@ MsgAuthAddUser(const char *user)
MsgAuthAPIFunction *function;
AuthPlugin_AddUser *f;
int result;
result = MsgAuthFindUser(user);
if (result == 0) {
return -1;
}
function = &pluginapi[Func_AddUser];
if (! function->available) return FALSE;
if (! function->available) return -2;
f = (AuthPlugin_AddUser *)&function->func;
result = (*f)(user);
@@ -259,8 +264,28 @@ MsgAuthGetUserStore(const char *user, struct sockaddr_in *store)
* \return Whether this was successful
*/
int
MsgAuthUserList(BongoArray **list)
MsgAuthUserList(char **list[])
{
return -1;
MsgAuthAPIFunction *function;
AuthPlugin_UserList *f;
int result;
function = &pluginapi[Func_UserList];
if (! function->available) return FALSE;
f = (AuthPlugin_UserList *)&function->func;
result = (*f)(list);
return result;
}
void
MsgAuthUserListFree(char **list[])
{
char **users = *list;
int i;
for (i = 0; users[i] != 0x0; i++) {
MemFree(users[i]);
}
MemFree(users);
}
+7 -8
View File
@@ -654,18 +654,17 @@ MsgCollectUser(const char *user)
void
MsgCollectAllUsers(void)
{
BongoArray *users;
int i;
char **userlist;
int result, i;
if (MsgAuthUserList(&users) < 0)
return;
result = MsgAuthUserList(&userlist);
if (! result) return;
for(i = 0; i < BongoArrayCount(users); i++) {
char *user = BongoArrayIndex(users, char *, i);
MsgCollectUser(user);
for (i = 0; userlist[i] != 0; i++) {
MsgCollectUser(userlist[i]);
}
BongoArrayFree(users, TRUE);
MsgAuthUserListFree(&userlist);
}
size_t
+2 -1
View File
@@ -13,6 +13,7 @@ typedef int (* AuthPlugin_VerifyPassword)(const char *user, const char *password
typedef int (* AuthPlugin_AddUser)(const char *user);
typedef int (* AuthPlugin_ChangePassword)(const char *user, const char *oldpassword, const char *newpassword);
typedef int (* AuthPlugin_SetPassword)(const char *user, const char *password);
typedef int (* AuthPlugin_UserList)(char **list[]);
typedef int (* AuthPlugin_GetUserStore)(const char *user, struct sockaddr_in *store);
typedef int (* AuthPlugin_Install)(void);
typedef int (* AuthPlugin_Init)(void);
@@ -27,7 +28,7 @@ enum {
Func_SetPassword = 6,
Func_GetUserStore = 7,
Func_Install = 8,
Func_Init = 9
Func_Init = 9
};
static MsgAuthAPIFunction pluginapi[] = {
+24
View File
@@ -269,6 +269,30 @@ MsgSQLExecute(MsgSQLHandle *handle, MsgSQLStatement *_stmt)
}
}
int
MsgSQLStatementStep(MsgSQLHandle *handle, MsgSQLStatement *_stmt)
{
sqlite3_stmt *stmt = _stmt->stmt;
int count = 1 + handle->lockTimeoutMs / MSGSQL_STMT_SLEEP_MS;
int dbg;
while (count--) {
switch ((dbg = sqlite3_step(stmt))) {
case SQLITE_ROW:
return 1;
case SQLITE_DONE:
return 0;
case SQLITE_BUSY:
XplDelay(MSGSQL_STMT_SLEEP_MS);
continue;
default:
XplConsolePrintf("Sql: %s", sqlite3_errmsg(handle->db));
return -1;
}
}
return -1;
}
int
MsgSQLResults(MsgSQLHandle *handle, MsgSQLStatement *_stmt)
{
+4 -8
View File
@@ -157,14 +157,14 @@ class AgentHandler(HawkeyeHandler):
# It's a hostlist, and arraytype is the default port
# Check if value has port and/or weighting
defaultweight = 1
defultport = arraytype
defaultport = arraytype
if dobj.count(':') == 1:
# Port and hostname
dobj = dobj + ":" + defaultweight
elif dobj.count(':') == 0:
# Only hostname
dobj = dobj + ":" + defaultport + ":" + defaultweight
dobj = dobj + ":" + str(defaultport) + ":" + str(defaultweight)
# Otherwise, type was string (default).
@@ -215,11 +215,7 @@ class AgentHandler(HawkeyeHandler):
nkey["revertbox"] = key + "-normal"
nkey["revertjs"] = "$('" + nkey["revertbox"] + "').hide(); $('" + nkey["selectorid"] + "').show();"
strthingy = ""
for value in config[key]:
strthingy += value + ","
nkey["strvalue"] = strthingy
nkey["strvalue"] = ','.join(config[key])
rkeys.append(nkey)
+17
View File
@@ -95,6 +95,20 @@ class AliasHandler(HawkeyeHandler):
else:
self.SetVariable("domainwide", None)
# handle the email->username mapping config
mapping_value = 0
if data.has_key("username-mapping"):
mapping_value = int(data["username-mapping"])
if mapping_value < 0 or mapping_value > 2:
mapping_value = 0
self.SetVariable("username-mapping", mapping_value)
for i in [0, 1, 2]:
select = "username-mapping-%d" % i
if i == mapping_value:
self.SetVariable(select, "selected")
else:
self.SetVariable(select, None)
self.SetVariable("useraliasestxt", aliases_txt)
self.SetVariable("useraliases", tpl_aliases)
self.SetVariable("domainalias", domainalias)
@@ -134,6 +148,9 @@ class AliasHandler(HawkeyeHandler):
elif key == "domainalias":
# Actual domain alias val
config["domainalias"] = value
elif key == "username-mapping":
# Mapping scheme wanted
config["username-mapping"] = int(value)
elif key == "useralias":
# User aliases
# Split this, and set array as value.
+8 -2
View File
@@ -52,7 +52,10 @@ class SundialPath(object):
self.sundialpath = '/'.join(pathparts)
if len(splituri) != 3:
if splituri[-1] == '':
splituri.pop()
if len(splituri) < 2:
raise HttpError(404)
# The user the calendar belongs to.
@@ -62,7 +65,10 @@ class SundialPath(object):
self.calendar = urllib.unquote(splituri[1])
# The file name.
self.filename = splituri[2]
try:
self.filename = splituri[2]
except IndexError:
self.filename = ''
if self.filename != '':
# This shop only serves up iCalendar.
+10
View File
@@ -47,6 +47,16 @@
</script>
</td>
</tr>
<tr>
<td style="padding-right: 16px;">Default address to username mapping</td>
<td>
<select name="username-mapping">
<option value="0" tal:attributes="selected username-mapping-0">Local part (before @) is the username</option>
<option value="1" tal:attributes="selected username-mapping-1">Full e-mail address is the username</option>
<option value="2" tal:attributes="selected username-mapping-2">Domain part (after @) is the username</option>
</select>
</td>
</tr>
</table>
<br />
<br />
+4 -3
View File
@@ -974,9 +974,10 @@ Dragonfly.start = function ()
// Don't use showElement - not nice to non-divs
$('admin-link').style.display = 'inline';
}
$('makeDumpLink-a').href = 'javascript:void(console.sendLog("user/' + d.userName + '/sendlog/all", true));';
if ($('makeDumpLink-a')) {
$('makeDumpLink-a').href = 'javascript:void(console.sendLog("user/' + d.userName + '/sendlog/all", true));';
}
removeElementClass (document.body, 'login');
d._handleResize();
+1 -1
View File
@@ -220,7 +220,7 @@ MochiKit.Async.Deferred.prototype = {
if (!(err instanceof Error)) {
err = new MochiKit.Async.GenericError(err);
}
logError ('Error firing Deferred: ', err.message);
console.error ('Error firing Deferred: ', err.message);
res = err;
}
}