Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
cyrus-imapd
user_deny_db-once.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File user_deny_db-once.patch of Package cyrus-imapd
From 1d6f0eedfb3a31695053ef0babe26e92b5fbbb2a Mon Sep 17 00:00:00 2001 From: murch <murch> Date: Thu, 22 Apr 2010 17:29:53 +0000 Subject: Modified user_deny.db code to open database once at service startup time. 8 files changed, 325 insertions(+), 127 deletions(-) Index: cyrus-imapd-2.3.17/imap/Makefile.in =================================================================== --- cyrus-imapd-2.3.17.orig/imap/Makefile.in +++ cyrus-imapd-2.3.17/imap/Makefile.in @@ -103,7 +103,7 @@ LOBJS= append.o mailbox.o mboxlist.o mup annotate.o search_engines.o squat.o squat_internal.o mbdump.o \ imapparse.o telemetry.o user.o notify.o idle.o quota_db.o \ sync_log.o autosieve.o $(SEEN) mboxkey.o backend.o tls.o message_guid.o \ - statuscache_db.o + statuscache_db.o userdeny_db.o IMAPDOBJS=pushstats.o imapd.o proxy.o imap_proxy.o index.o version.o Index: cyrus-imapd-2.3.17/imap/global.c =================================================================== --- cyrus-imapd-2.3.17.orig/imap/global.c +++ cyrus-imapd-2.3.17/imap/global.c @@ -72,8 +72,8 @@ #include "mupdate_err.h" #include "mutex.h" #include "prot.h" /* for PROT_BUFSIZE */ +#include "userdeny.h" #include "util.h" -#include "wildmat.h" #include "xmalloc.h" #include "xstrlcpy.h" #include "xstrlcat.h" @@ -531,124 +531,6 @@ static int acl_ok(const char *user, stru return r; } -#define DENYDB config_userdeny_db -#define FNAME_USERDENYDB "/user_deny.db" -#define USERDENY_VERSION 2 - -/* - * access_ok() checks to see if 'user' is allowed access to 'service' - * Returns 1 if so, 0 if not. - */ -int access_ok(const char *user, const char *service, char *msgbuf, int size) -{ - static char *fname = NULL; - struct db *db = NULL; - int r, ret = 1; /* access always granted by default */ - - if (!fname) { - /* create path to database */ - fname = xmalloc(strlen(config_dir) + sizeof(FNAME_USERDENYDB) + 1); - strcpy(fname, config_dir); - strcat(fname, FNAME_USERDENYDB); - } - - /* try to open database */ - r = DENYDB->open(fname, 0, &db); - if (r) { - /* ignore non-existent DB, report all other errors */ - if (errno != ENOENT) { - syslog(LOG_WARNING, "DENYDB_ERROR: error opening '%s': %s", - fname, cyrusdb_strerror(r)); - } - - } else { - /* fetch entry for user */ - const char *data = NULL; - int datalen; - - syslog(LOG_DEBUG, "fetching user_deny.db entry for '%s'", user); - do { - r = DENYDB->fetch(db, user, strlen(user), &data, &datalen, NULL); - } while (r == CYRUSDB_AGAIN); - - if (r || !data || !datalen) { - /* ignore non-existent/empty entry, report all other errors */ - if (r != CYRUSDB_NOTFOUND) { - syslog(LOG_WARNING, - "DENYDB_ERROR: error reading entry '%s': %s", - user, cyrusdb_strerror(r)); - } - } else { - /* parse the data */ - char *buf, *wild; - unsigned long version; - - buf = xstrndup(data, datalen); /* use a working copy */ - - /* check version */ - if (((version = strtoul(buf, &wild, 10)) < 1) || - (version > USERDENY_VERSION)) { - syslog(LOG_WARNING, - "DENYDB_ERROR: invalid version for entry '%s': %lu", - user, version); - } else if (*wild++ != '\t') { - syslog(LOG_WARNING, - "DENYDB_ERROR: missing wildmat for entry '%s'", user); - } else { - char *pat, *msg = "Access to this service has been blocked"; - int not; - - /* check if we have a deny message */ - switch (version) { - case USERDENY_VERSION: - if ((msg = strchr(wild, '\t'))) *msg++ = '\0'; - break; - } - - /* scan wildmat right to left for a match against our service */ - syslog(LOG_DEBUG, "wild: '%s' service: '%s'", wild, service); - do { - /* isolate next pattern */ - if ((pat = strrchr(wild, ','))) { - *pat++ = '\0'; - } else { - pat = wild; - } - - /* XXX trim leading & trailing whitespace? */ - - /* is it a negated pattern? */ - not = (*pat == '!'); - if (not) ++pat; - - syslog(LOG_DEBUG, "pat %d:'%s'", not, pat); - - /* see if pattern matches our service */ - if (wildmat(service, pat)) { - /* match ==> we're done */ - ret = not; - if (msgbuf) strlcpy(msgbuf, msg, size); - break; - } - - /* continue until we reach head of wildmat */ - } while (pat != wild); - } - - free(buf); - } - - - r = DENYDB->close(db); - if (r) { - syslog(LOG_WARNING, "DENYDB_ERROR: error closing: %s", - cyrusdb_strerror(r)); - } - } - - return ret; -} - /* should we allow users to proxy? return SASL_OK if yes, SASL_BADAUTH otherwise */ int mysasl_proxy_policy(sasl_conn_t *conn, @@ -704,7 +586,7 @@ int mysasl_proxy_policy(sasl_conn_t *con } /* is requested_user denied access? authenticated admins are exempt */ - if (!userisadmin && !access_ok(requested_user, config_ident, NULL, 0)) { + if (!userisadmin && userdeny(requested_user, config_ident, NULL, 0)) { syslog(LOG_ERR, "user '%s' denied access to service '%s'", requested_user, config_ident); sasl_seterror(conn, SASL_NOLOG, Index: cyrus-imapd-2.3.17/imap/global.h =================================================================== --- cyrus-imapd-2.3.17.orig/imap/global.h +++ cyrus-imapd-2.3.17/imap/global.h @@ -160,5 +160,6 @@ extern struct cyrusdb_backend *config_du extern struct cyrusdb_backend *config_tlscache_db; extern struct cyrusdb_backend *config_ptscache_db; extern struct cyrusdb_backend *config_statuscache_db; +extern struct cyrusdb_backend *config_userdeny_db; #endif /* INCLUDED_GLOBAL_H */ Index: cyrus-imapd-2.3.17/imap/imapd.c =================================================================== --- cyrus-imapd-2.3.17.orig/imap/imapd.c +++ cyrus-imapd-2.3.17/imap/imapd.c @@ -101,6 +101,7 @@ #include "telemetry.h" #include "tls.h" #include "user.h" +#include "userdeny.h" #include "util.h" #include "version.h" #include "xmalloc.h" @@ -679,6 +680,10 @@ int service_init(int argc, char **argv, quotadb_init(0); quotadb_open(NULL); + /* open the user deny db */ + denydb_init(0); + denydb_open(NULL); + /* setup for sending IMAP IDLE notifications */ idle_enabled(); @@ -932,6 +937,9 @@ void shut_down(int code) quotadb_close(); quotadb_done(); + denydb_close(); + denydb_done(); + annotatemore_close(); annotatemore_done(); @@ -1104,7 +1112,7 @@ void cmdloop() /* Check for shutdown file */ if ( !imapd_userisadmin && imapd_userid && (shutdown_file(shut, sizeof(shut)) || - !access_ok(imapd_userid, config_ident, shut, sizeof(shut)))) { + userdeny(imapd_userid, config_ident, shut, sizeof(shut)))) { for (p = shut; *p == '['; p++); /* can't have [ be first char */ prot_printf(imapd_out, "* BYE [ALERT] %s\r\n", p); shut_down(0); @@ -2741,7 +2749,7 @@ void cmd_idle(char *tag) if (!imapd_userisadmin && (shutdown_file(buf, sizeof(buf)) || (imapd_userid && - !access_ok(imapd_userid, config_ident, buf, sizeof(buf))))) { + userdeny(imapd_userid, config_ident, buf, sizeof(buf))))) { shutdown = done = 1; goto done; } @@ -2802,7 +2810,7 @@ void idle_update(idle_flags_t flags) if (! imapd_userisadmin && (shutdown_file(shut, sizeof(shut)) || (imapd_userid && - !access_ok(imapd_userid, config_ident, shut, sizeof(shut))))) { + userdeny(imapd_userid, config_ident, shut, sizeof(shut))))) { char *p; for (p = shut; *p == '['; p++); /* can't have [ be first char */ prot_printf(imapd_out, "* BYE [ALERT] %s\r\n", p); Index: cyrus-imapd-2.3.17/imap/nntpd.c =================================================================== --- cyrus-imapd-2.3.17.orig/imap/nntpd.c +++ cyrus-imapd-2.3.17/imap/nntpd.c @@ -103,6 +103,7 @@ #include "sync_log.h" #include "telemetry.h" #include "tls.h" +#include "userdeny.h" #include "util.h" #include "version.h" #include "wildmat.h" @@ -494,6 +495,10 @@ int service_init(int argc __attribute__( quotadb_init(0); quotadb_open(NULL); + /* open the user deny db */ + denydb_init(0); + denydb_open(NULL); + /* setup for sending IMAP IDLE notifications */ idle_enabled(); @@ -704,6 +709,9 @@ void shut_down(int code) quotadb_close(); quotadb_done(); + denydb_close(); + denydb_done(); + annotatemore_close(); annotatemore_done(); @@ -815,7 +823,7 @@ static void cmdloop(void) /* Check for shutdown file */ if (shutdown_file(buf, sizeof(buf)) || (nntp_userid && - !access_ok(nntp_userid, config_ident, buf, sizeof(buf)))) { + userdeny(nntp_userid, config_ident, buf, sizeof(buf)))) { prot_printf(nntp_out, "400 %s\r\n", buf); shut_down(0); } Index: cyrus-imapd-2.3.17/imap/pop3d.c =================================================================== --- cyrus-imapd-2.3.17.orig/imap/pop3d.c +++ cyrus-imapd-2.3.17/imap/pop3d.c @@ -88,6 +88,7 @@ #include "backend.h" #include "proxy.h" #include "seen.h" +#include "userdeny.h" #include "sync_log.h" #include "statuscache.h" @@ -434,6 +435,10 @@ int service_init(int argc __attribute__( quotadb_init(0); quotadb_open(NULL); + /* open the user deny db */ + denydb_init(0); + denydb_open(NULL); + if (config_getswitch(IMAPOPT_STATUSCACHE)) { /* open statuscache db to optimize handling an empty maildrop */ statuscache_open(NULL); @@ -643,6 +648,9 @@ void shut_down(int code) quotadb_close(); quotadb_done(); + denydb_close(); + denydb_done(); + if (popd_in) { prot_NONBLOCK(popd_in); prot_fill(popd_in); @@ -804,7 +812,7 @@ static void cmdloop(void) /* check for shutdown file */ if (shutdown_file(inputbuf, sizeof(inputbuf)) || (popd_userid && - !access_ok(popd_userid, config_ident, inputbuf, sizeof(inputbuf)))) { + userdeny(popd_userid, config_ident, inputbuf, sizeof(inputbuf)))) { for (p = inputbuf; *p == '['; p++); /* can't have [ be first char */ prot_printf(popd_out, "-ERR [SYS/TEMP] %s\r\n", p); shut_down(0); @@ -2027,7 +2035,7 @@ static void bitpipe(void) /* check for shutdown file */ if (shutdown_file(buf, sizeof(buf)) || - !access_ok(popd_userid, config_ident, buf, sizeof(buf))) { + userdeny(popd_userid, config_ident, buf, sizeof(buf))) { shutdown = 1; goto done; } Index: cyrus-imapd-2.3.17/imap/userdeny.h =================================================================== --- /dev/null +++ cyrus-imapd-2.3.17/imap/userdeny.h @@ -0,0 +1,72 @@ +/* userdeny.h -- User deny definitions + * + * Copyright (c) 1994-2010 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id$ + */ + +#ifndef INCLUDED_USERDENY_H +#define INCLUDED_USERDENY_H + +#include "cyrusdb.h" +#include <config.h> + +#define FNAME_USERDENYDB "/user_deny.db" +#define USERDENY_VERSION 2 + +extern struct db *denydb; + +extern int userdeny(const char *user, const char *service, + char *msgbuf, size_t bufsiz); + +/* open the user deny db */ +void denydb_open(char *name); + +/* close the database */ +void denydb_close(void); + +/* initialize database structures */ +#define DENYDB_SYNC 0x02 +void denydb_init(int flags); + +/* done with database stuff */ +void denydb_done(void); + +#endif /* INCLUDED_USERDENY_H */ Index: cyrus-imapd-2.3.17/imap/userdeny_db.c =================================================================== --- /dev/null +++ cyrus-imapd-2.3.17/imap/userdeny_db.c @@ -0,0 +1,219 @@ +/* userdeny_db.c -- User deny manipulation routines + * + * Copyright (c) 1994-2010 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * innovation@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id$ + */ + +#include <config.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <syslog.h> + +#include "cyrusdb.h" +#include "global.h" +#include "userdeny.h" +#include "wildmat.h" +#include "xmalloc.h" +#include "xstrlcpy.h" +#include "xstrlcat.h" + +#define DENYDB config_userdeny_db + +struct db *denydb; + +static int deny_dbopen = 0; + + +/* + * userdeny() checks to see if 'user' is denied access to 'service' + * Returns 1 if a matching deny entry exists in DB, otherwise returns 0. + */ +int userdeny(const char *user, const char *service, char *msgbuf, size_t bufsiz) +{ + int r, ret = 0; /* allow access by default */ + const char *data = NULL; + int datalen; + + if (!deny_dbopen) return 0; + + /* fetch entry for user */ + syslog(LOG_DEBUG, "fetching user_deny.db entry for '%s'", user); + do { + r = DENYDB->fetch(denydb, user, strlen(user), &data, &datalen, NULL); + } while (r == CYRUSDB_AGAIN); + + /* XXX Should we try to reopen the DB if we get IOERROR? + This might be necessary when using SQL backend + and we lose the connection. + */ + + if (r || !data || !datalen) { + /* ignore non-existent/empty entry, report all other errors */ + if (r != CYRUSDB_NOTFOUND) { + syslog(LOG_WARNING, + "DENYDB_ERROR: error reading entry '%s': %s", + user, cyrusdb_strerror(r)); + } + } else { + /* parse the data */ + char *buf, *wild; + unsigned long version; + + buf = xstrndup(data, datalen); /* use a working copy */ + + /* check version */ + if (((version = strtoul(buf, &wild, 10)) < 1) || + (version > USERDENY_VERSION)) { + syslog(LOG_WARNING, + "DENYDB_ERROR: invalid version for entry '%s': %lu", + user, version); + } else if (*wild++ != '\t') { + syslog(LOG_WARNING, + "DENYDB_ERROR: missing wildmat for entry '%s'", user); + } else { + char *pat, *msg = "Access to this service has been blocked"; + int not; + + /* check if we have a deny message */ + switch (version) { + case USERDENY_VERSION: + if ((msg = strchr(wild, '\t'))) *msg++ = '\0'; + break; + } + + /* scan wildmat right to left for a match against our service */ + syslog(LOG_DEBUG, "wild: '%s' service: '%s'", wild, service); + do { + /* isolate next pattern */ + if ((pat = strrchr(wild, ','))) { + *pat++ = '\0'; + } else { + pat = wild; + } + + /* XXX trim leading & trailing whitespace? */ + + /* is it a negated pattern? */ + not = (*pat == '!'); + if (not) ++pat; + + syslog(LOG_DEBUG, "pat %d:'%s'", not, pat); + + /* see if pattern matches our service */ + if (wildmat(service, pat)) { + /* match ==> we're done */ + ret = !not; + if (msgbuf) strlcpy(msgbuf, msg, bufsiz); + break; + } + + /* continue until we reach head of wildmat */ + } while (pat != wild); + } + + free(buf); + } + + return ret; +} + +/* must be called after cyrus_init */ +void denydb_init(int myflags) +{ + int r; + + if (myflags & DENYDB_SYNC) { + r = DENYDB->sync(); + } +} + +void denydb_open(char *fname) +{ + int ret; + char *tofree = NULL; + + /* create db file name */ + if (!fname) { + size_t fname_len = strlen(config_dir)+strlen(FNAME_USERDENYDB)+1; + + fname = xmalloc(fname_len); + tofree = fname; + + strlcpy(fname, config_dir, fname_len); + strlcat(fname, FNAME_USERDENYDB, fname_len); + } + + ret = (DENYDB->open)(fname, 0, &denydb); + if (ret == CYRUSDB_OK) { + deny_dbopen = 1; + } else if (errno != ENOENT) { + /* ignore non-existent DB, report all other errors */ + syslog(LOG_WARNING, "DENYDB_ERROR: opening %s: %s", fname, + cyrusdb_strerror(ret)); + } + + if (tofree) free(tofree); +} + +void denydb_close(void) +{ + int r; + + if (deny_dbopen) { + r = (DENYDB->close)(denydb); + if (r) { + syslog(LOG_ERR, "DENYDB_ERROR: error closing: %s", + cyrusdb_strerror(r)); + } + deny_dbopen = 0; + } +} + +void denydb_done(void) +{ + /* DB->done() handled by cyrus_done() */ +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor