summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaul <paul@7b491191-dbf0-0310-aff6-d879d4d69008>2005-02-07 12:15:55 +0000
committerpaul <paul@7b491191-dbf0-0310-aff6-d879d4d69008>2005-02-07 12:15:55 +0000
commit2f2151ed6c55e042c39a9bb39683a4b8bf0d35b6 (patch)
tree60814d82abbc3dc9f08e8fa3a407dad3d398c76b
parente0cbe72e5c09c0dda71a15c056bc110c4afaf59c (diff)
authldap and delivery fixes
git-svn-id: https://svn.ic-s.nl/svn/dbmail/trunk/dbmail@1589 7b491191-dbf0-0310-aff6-d879d4d69008
-rw-r--r--ChangeLog14
-rw-r--r--Makefile.am5
-rw-r--r--auth.h22
-rw-r--r--auth/authldap.c1393
-rw-r--r--auth/authsql.c182
-rw-r--r--check_dbmail.h4
-rw-r--r--check_dbmail_deliver.c155
-rw-r--r--check_dbmail_imapd.c2
-rw-r--r--check_dbmail_message.c10
-rw-r--r--db.c116
-rw-r--r--db.h30
-rw-r--r--dbmail-message.c139
-rw-r--r--dbmail-message.h15
-rw-r--r--dbmail.h1
-rwxr-xr-xdebian/rules5
-rw-r--r--imaputil.c50
-rw-r--r--imaputil.h4
-rw-r--r--list.c13
-rw-r--r--list.h2
-rw-r--r--main.c2
-rw-r--r--misc.c51
-rw-r--r--misc.h6
-rw-r--r--pipe.c18
-rw-r--r--user.c256
24 files changed, 1072 insertions, 1423 deletions
diff --git a/ChangeLog b/ChangeLog
index b92f2a47..8fb81734 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-02-07 Paul Stevens <paul@nfg.nl>
+
+ * auth.h, auth/authsql.c, auth/authldap.c: first wave of authldap
+ fixes.
+ * check_dbmail_deliver.c: implement testcases for auth.h api. The rest
+ of the tests for the delivery chain is still todo.
+ * user.c: change output from dbmail-users -l to make it machine
+ parseable and emulate unix getent standard.
+ * db.c, dbmail-message.c: move db_insert_message functionality to dbmail-message.c
+ * misc.c, imaputil.c: move some generic utilities to misc.c.
+ * list.c (g_list_copy_list): added shallow copy of old-style list to
+ glist.
+ * pipe.c, dbmail-message.c: cleanup dbmail_message_store_temp.
+
2005-01-26 Paul Stevens <paul@nfg.nl>
* imaputil.c, imapcommands.c (_ic_search): introduce sort_search which
diff --git a/Makefile.am b/Makefile.am
index f3e237d8..02083167 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,7 +29,12 @@ SERVER = server.c serverchild.c pool.c
DELIVER = pipe.c forward.c dsn.c
# CFLAGS
+if LDAP
+AM_CFLAGS = -fomit-frame-pointer -DAUTHLDAP
+else
AM_CFLAGS = -fomit-frame-pointer
+endif
+
INCLUDES = -I$(top_srcdir)
dbmail_smtp_SOURCES = main.c
diff --git a/auth.h b/auth.h
index a23b3567..ff9a2d6d 100644
--- a/auth.h
+++ b/auth.h
@@ -117,15 +117,19 @@ char *auth_getencryption(u64_t user_idnr);
/**
* \brief find all deliver_to addresses for a username (?, code is not exactly
- * clear to me at the moment, IB 21-08-03)
+ * clear to me at the moment, IB 21-08-03)
+ *
+ * Unused so I removed it, PS 30-01-05
+ *
* \param username
* \param userids list of user ids (empty on call)
* \param checks nr of checks. Used internally in recursive calls. It \b should
* be set to -1 when called!
* \return number of deliver_to addresses found
*/
-int auth_check_user(const char *username, struct list *userids,
- int checks);
+//int auth_check_user(const char *username, struct list *userids,
+// int checks);
+
/**
* \brief as auth_check_user() but adds the numeric ID of the user found to
* userids or the forward to the fwds list
@@ -268,10 +272,8 @@ char *auth_get_deliver_from_alias(const char *alias);
* - -2 on memory failure
* - -1 on database failure
* - 0 on success
- * \attention aliases list needs to be empty. Method calls list_init()
- * which sets list->start to NULL.
*/
-int auth_get_user_aliases(u64_t user_idnr, struct list *aliases);
+GList * auth_get_user_aliases(u64_t user_idnr);
/**
* \brief add an alias for a user
* \param user_idnr user's id
@@ -315,5 +317,13 @@ int auth_removealias(u64_t user_idnr, const char *alias);
*/
int auth_removealias_ext(const char *alias, const char *deliver_to);
+#ifdef AUTHLDAP
+
+char *dm_ldap_get_filter(const gchar boolean, const gchar *attribute, GList *values);
+u64_t dm_ldap_get_freeid(const gchar *attribute);
+GList * dm_ldap_entlist_get_values(GList *entlist);
+
+#endif
+
#endif
diff --git a/auth/authldap.c b/auth/authldap.c
index 3e2467bf..f8894a15 100644
--- a/auth/authldap.c
+++ b/auth/authldap.c
@@ -39,6 +39,7 @@
#include <string.h>
//#include <crypt.h>
#include <time.h>
+#include <glib.h>
#define AUTH_QUERY_SIZE 1024
#define LDAP_RES_SIZE 1024
@@ -57,18 +58,13 @@ char **_ldap_attrs = NULL;
char _ldap_query[AUTH_QUERY_SIZE];
typedef struct _ldap_cfg {
- field_t bind_dn,
- bind_pw, base_dn, port, scope, hostname, objectclass;
- field_t field_uid,
- field_cid,
- field_nid,
- field_mail,
- field_mailalt,
- mailaltprefix,
- field_maxmail,
- field_passwd,
- field_fwd,
- field_fwdsave, field_fwdtarget, fwdtargetprefix, field_members;
+ field_t bind_dn, bind_pw, base_dn, port, scope, hostname, objectclass;
+ field_t cn_string;
+ field_t field_uid, field_cid, min_cid, max_cid, field_nid, min_nid, max_nid;
+ field_t field_mail, field_mailalt, mailaltprefix;
+ field_t field_maxmail, field_passwd;
+ field_t field_fwd, field_fwdsave, field_fwdtarget, fwdtargetprefix;
+ field_t field_members;
int scope_int, port_int;
} _ldap_cfg_t;
@@ -88,31 +84,33 @@ _ldap_cfg_t _ldap_cfg;
static void __auth_get_config(void);
-static void __auth_get_config()
+static GList * __auth_get_every_match(const char *q, char **retfields);
+
+
+void __auth_get_config(void)
{
config_read(configFile);
SetTraceLevel("LDAP");
- GETCONFIGVALUE("BIND_DN", "LDAP", _ldap_cfg.bind_dn);
- GETCONFIGVALUE("BIND_PW", "LDAP", _ldap_cfg.bind_pw);
- GETCONFIGVALUE("BASE_DN", "LDAP", _ldap_cfg.base_dn);
- GETCONFIGVALUE("PORT", "LDAP", _ldap_cfg.port);
- GETCONFIGVALUE("HOSTNAME", "LDAP", _ldap_cfg.hostname);
- GETCONFIGVALUE("OBJECTCLASS", "LDAP", _ldap_cfg.objectclass);
- GETCONFIGVALUE("FIELD_UID", "LDAP", _ldap_cfg.field_uid);
- GETCONFIGVALUE("FIELD_CID", "LDAP", _ldap_cfg.field_cid);
- GETCONFIGVALUE("FIELD_NID", "LDAP", _ldap_cfg.field_nid);
- GETCONFIGVALUE("FIELD_MAIL", "LDAP", _ldap_cfg.field_mail);
- GETCONFIGVALUE("FIELD_MAILALT", "LDAP", _ldap_cfg.field_mailalt);
- GETCONFIGVALUE("MAILALTPREFIX", "LDAP", _ldap_cfg.mailaltprefix);
- GETCONFIGVALUE("FIELD_QUOTA", "LDAP", _ldap_cfg.field_maxmail);
- GETCONFIGVALUE("FIELD_PASSWD", "LDAP", _ldap_cfg.field_passwd);
- GETCONFIGVALUE("FIELD_FORWARD", "LDAP", _ldap_cfg.field_fwd);
- GETCONFIGVALUE("FIELD_FWDSAVE", "LDAP", _ldap_cfg.field_fwdsave);
- GETCONFIGVALUE("FIELD_FWDTARGET", "LDAP", _ldap_cfg.field_fwdtarget);
- GETCONFIGVALUE("FWDTARGETPREFIX", "LDAP", _ldap_cfg.fwdtargetprefix);
- GETCONFIGVALUE("FIELD_MEMBERS", "LDAP", _ldap_cfg.field_members);
- GETCONFIGVALUE("SCOPE", "LDAP", _ldap_cfg.scope);
+ GETCONFIGVALUE("BIND_DN", "LDAP", _ldap_cfg.bind_dn);
+ GETCONFIGVALUE("BIND_PW", "LDAP", _ldap_cfg.bind_pw);
+ GETCONFIGVALUE("BASE_DN", "LDAP", _ldap_cfg.base_dn);
+ GETCONFIGVALUE("PORT", "LDAP", _ldap_cfg.port);
+ GETCONFIGVALUE("HOSTNAME", "LDAP", _ldap_cfg.hostname);
+ GETCONFIGVALUE("OBJECTCLASS", "LDAP", _ldap_cfg.objectclass);
+ GETCONFIGVALUE("CN_STRING", "LDAP", _ldap_cfg.cn_string);
+ GETCONFIGVALUE("FIELD_UID", "LDAP", _ldap_cfg.field_uid);
+ GETCONFIGVALUE("FIELD_CID", "LDAP", _ldap_cfg.field_cid);
+ GETCONFIGVALUE("MIN_CID", "LDAP", _ldap_cfg.min_cid);
+ GETCONFIGVALUE("MAX_CID", "LDAP", _ldap_cfg.max_cid);
+ GETCONFIGVALUE("FIELD_NID", "LDAP", _ldap_cfg.field_nid);
+ GETCONFIGVALUE("MIN_NID", "LDAP", _ldap_cfg.min_nid);
+ GETCONFIGVALUE("MAX_NID", "LDAP", _ldap_cfg.max_nid);
+ GETCONFIGVALUE("FIELD_MAIL", "LDAP", _ldap_cfg.field_mail);
+ GETCONFIGVALUE("FIELD_QUOTA", "LDAP", _ldap_cfg.field_maxmail);
+ GETCONFIGVALUE("FIELD_PASSWD", "LDAP", _ldap_cfg.field_passwd);
+ GETCONFIGVALUE("FIELD_FWDTARGET", "LDAP", _ldap_cfg.field_fwdtarget);
+ GETCONFIGVALUE("SCOPE", "LDAP", _ldap_cfg.scope);
/* Store the port as an integer for later use. */
_ldap_cfg.port_int = atoi(_ldap_cfg.port);
@@ -120,9 +118,7 @@ static void __auth_get_config()
/* Compare the input string with the possible options,
* making sure not to exceeed the length of the given string */
{
- int len =
- (strlen(_ldap_cfg.scope) <
- 3 ? strlen(_ldap_cfg.scope) : 3);
+ int len = (strlen(_ldap_cfg.scope) < 3 ? strlen(_ldap_cfg.scope) : 3);
if (strncasecmp(_ldap_cfg.scope, "one", len) == 0)
_ldap_cfg.scope_int = LDAP_SCOPE_ONELEVEL;
@@ -155,12 +151,10 @@ int auth_disconnect(void)
{
/* Destroy the connection */
if (_ldap_conn != NULL) {
- trace(TRACE_DEBUG,
- "%s,%s: disconnecting from ldap server",__FILE__,__func__);
+ trace(TRACE_DEBUG, "%s,%s: disconnecting from ldap server",__FILE__,__func__);
ldap_unbind(_ldap_conn);
} else {
- trace(TRACE_DEBUG,
- "%s,%s: was already disconnected from ldap server",__FILE__,__func__);
+ trace(TRACE_DEBUG, "%s,%s: was already disconnected from ldap server",__FILE__,__func__);
}
return 0;
}
@@ -185,51 +179,158 @@ int auth_reconnect(void)
{
auth_disconnect();
/* ...and make anew! */
- trace(TRACE_DEBUG,
- "%s,%s: connecting to ldap server on [%s] : [%d]",__FILE__,__func__,
- _ldap_cfg.hostname, _ldap_cfg.port_int);
- _ldap_conn = ldap_init(_ldap_cfg.hostname, _ldap_cfg.port_int);
- trace(TRACE_DEBUG,
- "%s,%s: binding to ldap server as [%s] / [%s]",__FILE__,__func__,
- _ldap_cfg.bind_dn, _ldap_cfg.bind_pw);
- _ldap_err =
- ldap_bind_s(_ldap_conn, _ldap_cfg.bind_dn, _ldap_cfg.bind_pw,
- LDAP_AUTH_SIMPLE);
- if (_ldap_err) {
- trace(TRACE_ERROR,
- "%s,%s: ldap_bind_s failed: %s",__FILE__,__func__,
- ldap_err2string(_ldap_err));
+ trace(TRACE_DEBUG, "%s,%s: connecting to ldap server on [%s] : [%d]",
+ __FILE__,__func__,
+ _ldap_cfg.hostname,
+ _ldap_cfg.port_int);
+
+ _ldap_conn = ldap_init(
+ _ldap_cfg.hostname,
+ _ldap_cfg.port_int);
+
+ trace(TRACE_DEBUG, "%s,%s: binding to ldap server as [%s] / [xxxxxxxx]",
+ __FILE__,__func__,
+ _ldap_cfg.bind_dn);
+
+ /*
+ *
+ * TODO:
+ *
+ * support tls connects
+ *
+ */
+
+
+ if ((_ldap_err = ldap_bind_s(_ldap_conn,
+ _ldap_cfg.bind_dn,
+ _ldap_cfg.bind_pw,
+ LDAP_AUTH_SIMPLE))) {
+ trace(TRACE_ERROR, "%s,%s: ldap_bind_s failed: %s",
+ __FILE__,__func__,
+ ldap_err2string(_ldap_err));
return -1;
}
- trace(TRACE_DEBUG,
- "%s,%s: successfully bound to ldap server",__FILE__,__func__);
+ trace(TRACE_DEBUG, "%s,%s: successfully bound to ldap server",
+ __FILE__,__func__);
return 0;
}
-/*
-int __auth_add(const char *q)
+void dm_ldap_freeresult(GList *entlist)
{
- LDAP *__ldap_conn;
- LDAPMod **__ldap_mod;
- LDAPMessage *__ldap_res;
- LDAPMessage *__ldap_msg;
- int __ldap_err;
- int __ldap_attrsonly = 0;
- char *__ldap_dn;
- char **__ldap_vals;
- char **__ldap_attrs = NULL;
- char __ldap_query[AUTH_QUERY_SIZE];
-
- if (!q)
- {
- trace(TRACE_ERROR, "%s,%s: got NULL query",__FILE__,__func__);
- return 0;
- }
+ GList *fldlist, *attlist;
+ entlist = g_list_first(entlist);
+ while (entlist) {
+ fldlist = entlist->data;
+ while(fldlist) {
+ attlist = fldlist->data;
+ g_list_foreach(attlist,(GFunc)g_free,NULL);
+ g_list_free(attlist);
+ fldlist = g_list_next(fldlist);
+ }
+ entlist = g_list_next(entlist);
+ }
}
-*/
-/*
- * The list that goes into retlist is really big and scary.
- * Here's how it works...
+
+GList * dm_ldap_entlist_get_values(GList *entlist)
+{
+ GList *fldlist, *attlist;
+ GList *values = NULL;
+ gchar *tmp;
+ entlist = g_list_first(entlist);
+ while (entlist) {
+ fldlist = g_list_first(entlist->data);
+ while (fldlist) {
+ attlist = g_list_first(fldlist->data);
+ while (attlist) {
+ tmp = (gchar *)attlist->data;
+ trace(TRACE_DEBUG,"%s,%s: value [%s]",
+ __FILE__, __func__,
+ tmp);
+ values = g_list_append_printf(values,"%s", g_strdup(tmp));
+ attlist = g_list_next(attlist);
+ }
+ fldlist = g_list_next(fldlist);
+ }
+ entlist = g_list_next(entlist);
+ }
+ return values;
+}
+
+char *dm_ldap_get_filter(const gchar boolean, const gchar *attribute, GList *values)
+{
+ /* build user filter from objectclasses */
+ gchar *s;
+ GString *t = g_string_new("");
+ GString *q = g_string_new("");
+ GList *l = NULL;
+
+ values = g_list_first(values);
+ do {
+ g_string_printf(t,"%s=%s", attribute, (char *)values->data);
+ l = g_list_append(l,g_strdup(t->str));
+ } while ((values = g_list_next(values)));
+
+ t = g_list_join(l,")(");
+ g_string_printf(q,"(%c(%s))", boolean, t->str);
+ s = q->str;
+
+ g_string_free(t,FALSE);
+ g_string_free(q,FALSE);
+ g_list_foreach(l,(GFunc)g_free,NULL);
+ g_list_free(l);
+
+ return s;
+}
+
+u64_t dm_ldap_get_freeid(const gchar *attribute)
+{
+ /* get the first available uidNumber/gidNumber */
+ u64_t id = 0, t;
+ GList *ids, *entlist;
+ u64_t min = 0, max = 0;
+ char *attrs[2] = { (char *)attribute, NULL };
+ GString *q = g_string_new("");
+ GHashTable *ht;
+
+ g_string_printf(q,"(%s=*)", attribute);
+ entlist = __auth_get_every_match(q->str, attrs);
+
+ ids = dm_ldap_entlist_get_values(entlist);
+ trace(TRACE_DEBUG,"%s,%s: found [%d] matches\n",
+ __FILE__,__func__,
+ g_list_length(ids));
+
+ if (strcmp(attribute,_ldap_cfg.field_nid)==0) {
+ min = strtoull(_ldap_cfg.min_nid,NULL,10);
+ max = strtoull(_ldap_cfg.max_nid,NULL,10);
+ }
+ if (strcmp(attribute,_ldap_cfg.field_cid)==0) {
+ min = strtoull(_ldap_cfg.min_cid,NULL,10);
+ max = strtoull(_ldap_cfg.max_cid,NULL,10);
+ }
+
+ ht = g_hash_table_new((GHashFunc)g_int_hash,(GEqualFunc)g_int_equal);
+ ids = g_list_first(ids);
+ while(ids) {
+ t = strtoull(ids->data,NULL,10);
+ if ((t) && (t >= min) && ((max) && (t <= max)))
+ g_hash_table_insert(ht, (gpointer)(&t), (gpointer)(ids->data));
+ ids = g_list_next(ids);
+ }
+ for (t = min; t < max; t++) {
+ if (! (g_hash_table_lookup(ht, (gpointer)(&t))))
+ break;
+ }
+ if ((t >= min) && (t <= max))
+ id=t;
+
+ trace(TRACE_DEBUG,"%s,%s: return free id [%llu]\n",
+ __FILE__, __func__,
+ id);
+ return id;
+}
+
+/* OLD-SCHOOL:
*
* Each node of retlist contains a data field
* which is a pointer to another list, "fieldlist".
@@ -258,298 +359,111 @@ int __auth_add(const char *q)
* }
* }
*
- * */
-
-/* returns the number of matches found */
-int __auth_get_one_entry(const char *q, char **retfields,
- struct list *retlist)
-{
- LDAPMessage *ldap_res;
- LDAPMessage *ldap_msg;
- int ldap_err;
- int ldap_attrsonly = 0;
- /* char *ldap_dn; this variable is unused */
- char **ldap_vals;
- char **ldap_attrs = NULL;
- char ldap_query[AUTH_QUERY_SIZE];
- int i = 0, j = 0, k = 0, m = 0;
- struct list fieldlist, datalist;
-
- if (!q) {
- trace(TRACE_ERROR,
- "%s,%s: got NULL query",__FILE__,__func__);
- goto endnofree;
- }
-
- auth_reconnect();
-
- snprintf(ldap_query, AUTH_QUERY_SIZE, "%s", q);
- trace(TRACE_DEBUG,
- "%s,%s: retrieving entry for DN [%s]",__FILE__,__func__,
- ldap_query);
- ldap_err =
- ldap_search_s(_ldap_conn, ldap_query, LDAP_SCOPE_BASE,
- "(objectClass=*)", ldap_attrs, ldap_attrsonly,
- &ldap_res);
- if (ldap_err) {
- trace(TRACE_ERROR,
- "%s,%s: could not retrieve DN: %s",__FILE__,__func__,
- ldap_err2string(ldap_err));
- goto endnofree;
- }
-
- /* we're just using a little counter variable,
- * since we'll use it in the for loop later */
- j = ldap_count_entries(_ldap_conn, ldap_res);
-
- if (j < 1) {
- trace(TRACE_DEBUG, "%s,%s: none found",__FILE__,__func__);
- goto endnofree;
- }
-
- /* do the first entry here */
- ldap_msg = ldap_first_entry(_ldap_conn, ldap_res);
- if (ldap_msg == NULL) {
- ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
- &_ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_first_entry failed: %s",__FILE__,__func__,
- ldap_err2string(_ldap_err));
- goto endnofree;
- }
-
- list_init(retlist);
-
- /* we'll get the next entry at the _end_ of the loop! */
- /* get the entries to populate retlist */
- for (i = 0; i < j; i++) {
- /* init this list for the field values */
- list_init(&fieldlist);
-
- /* get the fields to populate fieldlist */
- for (k = 0; retfields[k] != NULL; k++) {
- /* init this list for the data values */
- list_init(&datalist);
-
- /* get the values to populate datalist */
- ldap_vals =
- ldap_get_values(_ldap_conn, ldap_msg,
- retfields[k]);
- if (ldap_vals == NULL) {
- ldap_get_option(_ldap_conn,
- LDAP_OPT_ERROR_NUMBER,
- &ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_get_values failed: %s",__FILE__,__func__,
- ldap_err2string(ldap_err));
- /* no need to break, because we WANT the list to contain an entry
- * for each attribute, even if it is simply the freshly-initialized
- * list, which has no nodes -- that's just fine by us and our consumers
- break;
- */
- } else {
- for (m = 0; ldap_vals[m] != NULL; m++) {
- /* add the value to the list */
- if (!list_nodeadd
- (&datalist, ldap_vals[m],
- strlen(ldap_vals[m]) + 1)) {
- trace(TRACE_ERROR,
- "%s,%s: could not add ldap_vals to &datalist",__FILE__,__func__);
- list_freelist(&datalist.
- start);
- break;
- }
- }
- }
- /* add the value to the list */
- if (!list_nodeadd
- (&fieldlist, &datalist, sizeof(struct list))) {
- trace(TRACE_ERROR,
- "%s,%s: could not add &datalist to &fieldlist",__FILE__,__func__);
- list_freelist(&fieldlist.start);
- break;
- }
- /* free the values as we use them */
- ldap_value_free(ldap_vals);
- }
- /* add the value to the list */
- if (!list_nodeadd
- (retlist, &fieldlist, sizeof(struct list))) {
- trace(TRACE_ERROR,
- "%s,%s: could not add &fieldlist to retlist",__FILE__,__func__);
- list_freelist(&retlist->start);
- goto endfree;
- }
-
- /* do the next entry here */
- ldap_msg = ldap_next_entry(_ldap_conn, ldap_msg);
- if (ldap_msg == NULL) {
- ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
- &ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_next_entry failed: %s",__FILE__,__func__,
- ldap_err2string(ldap_err));
- //goto endfree;
- break;
- }
- }
-
- endfree:
- if (ldap_res)
- ldap_msgfree(ldap_res);
+ * TODO: GLIB-STYLIE:
+ *
+ * ghashtable *ldap_entities
+ * {
+ * gchar *dn;
+ * ghashtable *ldap_attributes {
+ * gchar *attribute;
+ * glist *values;
+ * }
+ * }
+ *
+ */
- endnofree:
- return j; /* remember, j = ldap_count_entries() */
-}
/* returns the number of matches found */
-int __auth_get_every_match(const char *q, char **retfields,
- struct list *retlist)
+GList * __auth_get_every_match(const char *q, char **retfields)
{
LDAPMessage *ldap_res;
LDAPMessage *ldap_msg;
int ldap_err;
int ldap_attrsonly = 0;
- /* char *ldap_dn; usunused variable */
+ char *dn;
char **ldap_vals;
char **ldap_attrs = NULL;
char ldap_query[AUTH_QUERY_SIZE];
- int i = 0, j = 0, k = 0, m = 0;
- struct list fieldlist, datalist;
+ int j = 0, k = 0, m = 0;
+ GList *attlist,*fldlist,*entlist;
+
+ attlist = fldlist = entlist = NULL;
if (!q) {
- trace(TRACE_ERROR,
- "%s,%s: got NULL query",__FILE__,__func__);
- goto endnofree;
+ trace(TRACE_ERROR, "%s,%s: got NULL query",__FILE__,__func__);
+ return NULL;
}
auth_reconnect();
snprintf(ldap_query, AUTH_QUERY_SIZE, "%s", q);
- trace(TRACE_DEBUG,
- "%s,%s: searching with query [%s]",__FILE__,__func__,
- ldap_query);
- ldap_err =
- ldap_search_s(_ldap_conn, _ldap_cfg.base_dn,
- _ldap_cfg.scope_int, ldap_query, ldap_attrs,
- ldap_attrsonly, &ldap_res);
- if (ldap_err) {
- trace(TRACE_ERROR,
- "%s,%s: could not execute query: %s",__FILE__,__func__,
+ trace(TRACE_DEBUG, "%s,%s: search with query [%s]",__FILE__,__func__, ldap_query);
+
+ if ((ldap_err = ldap_search_s(_ldap_conn, _ldap_cfg.base_dn, _ldap_cfg.scope_int,
+ ldap_query, ldap_attrs, ldap_attrsonly, &ldap_res))) {
+ trace(TRACE_ERROR, "%s,%s: query failed: %s",__FILE__,__func__,
ldap_err2string(ldap_err));
- if (ldap_res != NULL)
+ if (ldap_res)
ldap_msgfree(ldap_res);
- goto endnofree;
+ return NULL;
}
- /* we're just using a little counter variable,
- * since we'll use it in the for loop later */
- j = ldap_count_entries(_ldap_conn, ldap_res);
-
- if (j < 1) {
- trace(TRACE_DEBUG, "%s,%s: none found",__FILE__,__func__);
- if (ldap_res != NULL)
+ if ((j = ldap_count_entries(_ldap_conn, ldap_res)) < 1) {
+ trace(TRACE_DEBUG, "%s,%s: nothing found",__FILE__,__func__);
+ if (ldap_res)
ldap_msgfree(ldap_res);
- goto endnofree;
+ return NULL;
}
/* do the first entry here */
- ldap_msg = ldap_first_entry(_ldap_conn, ldap_res);
- if (ldap_msg == NULL) {
- ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
- &_ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_first_entry failed: %s",__FILE__,__func__,
+ if ((ldap_msg = ldap_first_entry(_ldap_conn, ldap_res)) == NULL) {
+ ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
+ trace(TRACE_ERROR, "%s,%s: ldap_first_entry failed: [%s]",__FILE__,__func__,
ldap_err2string(_ldap_err));
- if (ldap_res != NULL)
+ if (ldap_res)
ldap_msgfree(ldap_res);
- goto endnofree;
+ return NULL;
}
- list_init(retlist);
-
- /* we'll get the next entry at the _end_ of the loop! */
- /* get the entries to populate retlist */
- for (i = 0; i < j; i++) {
- /* init this list for the field values */
- list_init(&fieldlist);
-
- /* get the fields to populate fieldlist */
+ while (ldap_msg) {
+
+ dn = ldap_get_dn(_ldap_conn, ldap_msg);
+ trace(TRACE_DEBUG,"%s,%s: scan results for DN: [%s]", __FILE__, __func__, dn);
+
for (k = 0; retfields[k] != NULL; k++) {
- /* init this list for the data values */
- list_init(&datalist);
-
- /* get the values to populate datalist */
- ldap_vals =
- ldap_get_values(_ldap_conn, ldap_msg,
- retfields[k]);
- if (ldap_vals == NULL) {
- ldap_get_option(_ldap_conn,
- LDAP_OPT_ERROR_NUMBER,
- &ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_get_values failed: %s",__FILE__,__func__,
- ldap_err2string(ldap_err));
- /* no need to break, because we WANT the list to contain an entry
- * for each attribute, even if it is simply the freshly-initialized
- * list, which has no nodes -- that's just fine by us and our consumers
- break;
- */
+ if (! (ldap_vals = ldap_get_values(_ldap_conn, ldap_msg, retfields[k]))) {
+ ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &ldap_err);
+ trace(TRACE_ERROR, "%s,%s: ldap_get_values failed: [%s] %s",
+ __FILE__,__func__,
+ retfields[k],
+ ldap_err2string(ldap_err));
} else {
- for (m = 0; ldap_vals[m] != NULL; m++) {
- /* add the value to the list */
- if (!list_nodeadd
- (&datalist, ldap_vals[m],
- strlen(ldap_vals[m]) + 1)) {
- trace(TRACE_ERROR,
- "%s,%s: could not add ldap_vals to &datalist",__FILE__,__func__);
- list_freelist(&datalist.
- start);
- break;
- }
+ m = 0;
+ while (ldap_vals[m]) {
+ trace(TRACE_DEBUG,"%s,%s: got value [%s]\n",
+ __FILE__, __func__,
+ ldap_vals[m]);
+ attlist = g_list_append(attlist,g_strdup(ldap_vals[m]));
+ m++;
}
}
- /* add the value to the list */
- if (!list_nodeadd
- (&fieldlist, &datalist, sizeof(struct list))) {
- trace(TRACE_ERROR,
- "%s,%s: could not add &datalist to &fieldlist",__FILE__,__func__);
- list_freelist(&fieldlist.start);
- break;
- }
- /* free the values as we use them */
+ fldlist = g_list_append(fldlist, attlist);
+ attlist = NULL;
+
ldap_value_free(ldap_vals);
}
- /* add the value to the list */
- if (!list_nodeadd
- (retlist, &fieldlist, sizeof(struct list))) {
- trace(TRACE_ERROR,
- "%s,%s: could not add &fieldlist to retlist",__FILE__,__func__);
- list_freelist(&retlist->start);
- goto endfree;
- }
+ entlist = g_list_append(entlist, fldlist);
+ fldlist = NULL;
- /* do the next entry here */
ldap_msg = ldap_next_entry(_ldap_conn, ldap_msg);
- if (ldap_msg == NULL) {
- ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
- &ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_next_entry failed: %s",__FILE__,__func__,
- ldap_err2string(ldap_err));
- //goto endfree;
- break;
- }
}
- endfree:
if (ldap_res)
ldap_msgfree(ldap_res);
if (ldap_msg)
ldap_msgfree(ldap_msg);
- endnofree:
- return j; /* remember, j = ldap_count_entries() */
+ return entlist;
}
char *__auth_get_first_match(const char *q, char **retfields)
@@ -648,6 +562,7 @@ int auth_user_exists(const char *username, u64_t * user_idnr)
snprintf(query, AUTH_QUERY_SIZE, "(%s=%s)", _ldap_cfg.field_uid,
username);
+
id_char = __auth_get_first_match(query, fields);
*user_idnr = (id_char) ? strtoull(id_char, NULL, 0) : 0;
@@ -657,10 +572,14 @@ int auth_user_exists(const char *username, u64_t * user_idnr)
if (id_char)
dm_free(id_char);
- if (*user_idnr == 0)
+ if (*user_idnr != 0)
return 0;
- else
- return 1;
+
+ /* fall back to db-user for DBMAIL_DELIVERY_USERNAME */
+ if (strcmp(username,DBMAIL_DELIVERY_USERNAME)==0)
+ return db_user_exists(DBMAIL_DELIVERY_USERNAME, user_idnr);
+
+ return 1;
}
/* Given a useridnr, find the account/login name
@@ -768,175 +687,36 @@ int auth_getmaxmailsize(u64_t user_idnr, u64_t * maxmail_size)
char *auth_getencryption(u64_t user_idnr UNUSED)
{
/* ldap does not support fancy passwords */
- return 0;
+ return g_strdup("");
}
+
+
/* Fills the users list with all existing users
* return -2 on mem error, -1 on db-error, 0 on success */
-int auth_get_known_users(struct list *users)
+GList * auth_get_known_users(void)
{
- int64_t known;
- /* u64_t curr; unused variable */
- char query[AUTH_QUERY_SIZE];
+ char *query;
char *fields[] = { _ldap_cfg.field_uid, NULL };
- struct list templist;
- struct element *tempelem1, *tempelem2, *tempelem3;
-
- if (!users) {
- trace(TRACE_ERROR,
- "%s,%s: got a NULL pointer as argument",__FILE__,__func__);
- return -2;
- }
-
- list_init(users);
-
- snprintf(query, AUTH_QUERY_SIZE, "(objectClass=%s)",
- _ldap_cfg.objectclass);
- known = __auth_get_every_match(query, fields, &templist);
- trace(TRACE_ERROR, "%s,%s: found %llu users",__FILE__,__func__,
- known);
-
- /* do the first entry here */
- tempelem1 = list_getstart(&templist);
-
- /* we'll get the next entry at the _end_ of the loop! */
- while (tempelem1 != NULL) {
- tempelem2 = list_getstart((struct list *) tempelem1->data);
- while (tempelem2 != NULL) {
- tempelem3 =
- list_getstart((struct list *) tempelem2->data);
- while (tempelem3 != NULL) {
- list_nodeadd(users,
- (char *) tempelem3->data,
- strlen((char *) tempelem3->
- data) + 1);
- tempelem3 = tempelem3->nextnode;
- }
- tempelem2 = tempelem2->nextnode;
- }
- tempelem1 = tempelem1->nextnode;
- }
-
- /* pass through any error from __auth_get_every_match() */
- return (known < 0 ? known : 0);
-}
-
-
-/* recursive function, should be called with checks == -1 from main routine */
-int auth_check_user(const char *address, struct list *userids, int checks)
-{
- int occurences = 0, r;
- /*int i; unused variable */
- int j;
- char query[AUTH_QUERY_SIZE];
- char *fields[] = { _ldap_cfg.field_nid, NULL };
- int c1, c2, c3;
- int count1, count2, count3;
- struct list templist;
- struct element *tempelem1, *tempelem2, *tempelem3;
-
-
- trace(TRACE_DEBUG, "%s,%s: checking for user [%s]",__FILE__,__func__,
- address);
-
- if (checks > MAX_CHECKS_DEPTH) {
- trace(TRACE_ERROR,
- "%s,%s: maximum checking depth reached, there probably is a loop in your alias table",__FILE__,__func__);
- return -1;
- }
-
- list_init(&templist);
-
- snprintf(query, AUTH_QUERY_SIZE, "(|(%s=%s)(%s=%s%s))",
- _ldap_cfg.field_mail, address, _ldap_cfg.field_mailalt,
- _ldap_cfg.mailaltprefix, address);
-
- /* we're just using a little counter variable, since we'll use it in the for loop later */
- j = __auth_get_every_match(query, fields, &templist);
-
- if (j < 1) {
- if (checks > 0) {
- /* found the last one, this is the deliver to
- * but checks needs to be bigger then 0 because
- * else it could be the first query failure */
-
- list_nodeadd(userids, address,
- strlen(address) + 1);
- trace(TRACE_DEBUG,
- "%s,%s: adding [%s] to deliver_to address",__FILE__,__func__,
- address);
- list_freelist(&templist.start);
- return 1;
- } else {
- trace(TRACE_DEBUG,
- "%s,%s: user [%s] not in aliases table",__FILE__,__func__,
- address);
- list_freelist(&templist.start);
- return 0;
- }
- }
-
- /* do the first entry here */
- tempelem1 = list_getstart(&templist);
-
- count1 = templist.total_nodes;
- for (c1 = 0; c1 < count1; c1++) {
- tempelem2 = list_getstart((struct list *) tempelem1->data);
- count2 = ((struct list *) tempelem1->data)->total_nodes;
- for (c2 = 0; c2 < count2; c2++) {
- tempelem3 =
- list_getstart((struct list *) tempelem2->data);
- count3 =
- ((struct list *) tempelem2->data)->total_nodes;
- for (c3 = 0; c3 < count3; c3++) {
-// here begins the meat
- /* do a recursive search for deliver_to */
- trace(TRACE_DEBUG,
- "%s,%s: checking user [%s] to [%s]",__FILE__,__func__,
- address, (char *) tempelem3->data);
-
- r = auth_check_user((char *) tempelem3->
- data, userids,
- (checks <
- 0) ? 1 : checks + 1);
-
- if (r < 0) {
- /* loop detected */
-
- if (checks > 0)
- return -1; /* still in recursive call */
-
- if (userids->start) {
- list_freelist(&userids->
- start);
- userids->total_nodes = 0;
- }
-
- return 0; /* report to calling routine: no results */
- }
-
- occurences += r;
-// here ends the meat
- tempelem3 = tempelem3->nextnode;
- }
- list_freelist(&((struct list *) tempelem2->data)->
- start);
- tempelem2 = tempelem2->nextnode;
- }
- list_freelist(&((struct list *) tempelem1->data)->start);
- tempelem1 = tempelem1->nextnode;
- }
- list_freelist(&templist.start);
-
- trace(TRACE_DEBUG,
- "%s,%s: executing query, checks [%d]",__FILE__,__func__, checks);
- /* trace(TRACE_INFO,"%s,%s: user [%s] has [%d] entries",__FILE__,__func__,address,occurences); */
+ GList *users;
+ GList *entlist;
+
+ GString *t = g_string_new(_ldap_cfg.objectclass);
+ GList *l = g_string_split(t,",");
+ g_string_free(t,TRUE);
+ query = dm_ldap_get_filter('&',"objectClass",l);
+
+ entlist = __auth_get_every_match(query, fields);
+ trace(TRACE_ERROR, "%s,%s: found %d users",
+ __FILE__,__func__,
+ g_list_length(entlist));
- return occurences;
+ users = dm_ldap_entlist_get_values(entlist);
+
+ dm_ldap_freeresult(entlist);
+ return users;
}
-
-
/*
* auth_check_user_ext()
*
@@ -945,50 +725,33 @@ int auth_check_user(const char *address, struct list *userids, int checks)
*
* returns the number of occurences.
*/
+
+
+
int auth_check_user_ext(const char *address, struct list *userids,
struct list *fwds, int checks)
{
- /*int i; unused variable */
- int j;
int occurences = 0;
u64_t id;
char *endptr = NULL;
char query[AUTH_QUERY_SIZE];
- char *fields[] =
- { _ldap_cfg.field_nid, _ldap_cfg.field_members,
- _ldap_cfg.field_fwd, _ldap_cfg.field_fwdsave,
- _ldap_cfg.field_fwdtarget, NULL };
- int c1, c2, c3;
- int count1, count2, count3;
- struct list templist;
- struct element *tempelem1, *tempelem2, *tempelem3;
+ char *fields[] = { _ldap_cfg.field_nid, _ldap_cfg.field_fwdtarget, NULL };
+ unsigned c2;
+ char *attrvalue;
+ GList *entlist, *fldlist, *attlist;
trace(TRACE_DEBUG,
"%s,%s: checking user [%s] in alias table",__FILE__,__func__,
address);
/* This is my private line for sending a DN rather than a search */
- if (checks < -1) {
- snprintf(query, AUTH_QUERY_SIZE, "%s", address);
- j = __auth_get_one_entry(query, fields, &templist);
- } else {
- snprintf(query, AUTH_QUERY_SIZE, "(|(%s=%s)(%s=%s%s))",
- _ldap_cfg.field_mail, address,
- _ldap_cfg.field_mailalt, _ldap_cfg.mailaltprefix,
- address);
- /* we're just using a little counter variable,
- * since we'll use it in the for loop later */
- j = __auth_get_every_match(query, fields, &templist);
- }
-
+ snprintf(query, AUTH_QUERY_SIZE, "(%s=%s)", _ldap_cfg.field_mail, address);
+ entlist = __auth_get_every_match(query, fields);
- trace(TRACE_DEBUG,
- "%s,%s: searching with query [%s]",__FILE__,__func__, query);
- trace(TRACE_DEBUG,
- "%s,%s: executing query, checks [%d]",__FILE__,__func__,
- checks);
+ trace(TRACE_DEBUG, "%s,%s: searching with query [%s], checks [%d]",
+ __FILE__,__func__, query, checks);
- if (j < 1) {
+ if (g_list_length(entlist) < 1) {
if (checks > 0) {
/* found the last one, this is the deliver to
* but checks needs to be bigger then 0 because
@@ -997,181 +760,56 @@ int auth_check_user_ext(const char *address, struct list *userids,
id = strtoull(address, &endptr, 10);
if (*endptr == 0) {
/* numeric deliver-to --> this is a userid */
+ trace(TRACE_DEBUG, "%s,%s: adding [%llu] to userids",__FILE__,__func__, id);
list_nodeadd(userids, &id, sizeof(id));
} else {
- list_nodeadd(fwds, address,
- strlen(address) + 1);
+ trace(TRACE_DEBUG, "%s,%s: adding [%s] to forwards",__FILE__,__func__, address);
+ list_nodeadd(fwds, address, strlen(address) + 1);
dm_free(endptr);
}
-
- trace(TRACE_DEBUG,
- "%s,%s: adding [%s] to deliver_to address",__FILE__,__func__,
- address);
- list_freelist(&templist.start);
+ dm_ldap_freeresult(entlist);
return 1;
} else {
- trace(TRACE_DEBUG,
- "%s,%s: user [%s] not in aliases table",__FILE__,__func__,
- address);
- list_freelist(&templist.start);
+ trace(TRACE_DEBUG, "%s,%s: user [%s] not in aliases table",__FILE__,__func__, address);
+ dm_ldap_freeresult(entlist);
return 0;
}
}
trace(TRACE_DEBUG, "%s,%s: into checking loop",__FILE__,__func__);
-
- /* do the first entry here */
- tempelem1 = list_getstart(&templist);
-
- count1 = templist.total_nodes;
- for (c1 = 0; c1 < count1; c1++) {
- int fwdsave = 1;
- int fwdmaysave = 1;
- tempelem2 = list_getstart((struct list *) tempelem1->data);
- count2 = ((struct list *) tempelem1->data)->total_nodes;
- for (c2 = 0; c2 < count2; c2++) {
- tempelem3 =
- list_getstart((struct list *) tempelem2->data);
- count3 =
- ((struct list *) tempelem2->data)->total_nodes;
- for (c3 = 0; c3 < count3; c3++) {
-// here begins the meat
- /* Note that the fields are in *reverse*
- * order from the definition above! */
- if (4 == c2) {
- /* do a recursive search for deliver_to */
- trace(TRACE_DEBUG,
- "%s,%s: looks like a user id",__FILE__,__func__);
- if (fwdsave) {
- trace(TRACE_DEBUG,
- "%s,%s: checking user %s to %s",__FILE__,__func__,
- address,
- (char *) tempelem3->
- data);
- occurences +=
- auth_check_user_ext((char *) tempelem3->data, userids, fwds, 1);
- } else {
- trace(TRACE_DEBUG,
- "%s,%s: not checking user %s to %s due to fwdsave=0",__FILE__,__func__,
- address,
- (char *) tempelem3->
- data);
- }
- } else if (3 == c2) {
- /* do a recursive search for deliver_to */
- trace(TRACE_DEBUG,
- "%s,%s: looks like a group member",__FILE__,__func__);
- trace(TRACE_DEBUG,
- "%s,%s: checking user %s to %s",__FILE__,__func__,
- address,
- (char *) tempelem3->data);
- occurences +=
- auth_check_user_ext((char *)
- tempelem3->
- data,
- userids,
- fwds, -2);
- } else if (2 == c2) {
- /* do a recursive search for deliver_to */
- trace(TRACE_DEBUG,
- "%s,%s: looks like a forwarding dn",__FILE__,__func__);
- trace(TRACE_DEBUG,
- "%s,%s: checking user %s to %s",__FILE__,__func__,
- address,
- (char *) tempelem3->data);
- occurences +=
- auth_check_user_ext((char *)
- tempelem3->
- data,
- userids,
- fwds, -2);
- /* if the user does not have a forward, their fwdsave will be false
- * but logically, it is true: "save, then forward to nowhere"
- * so here we make sure that before we don't deliver we check:
- * - that the fwdsave value is false
- * AND - that there is a forwarding address */
- if (0 == fwdmaysave)
- fwdsave = 0;
- } else if (1 == c2) {
- /* do a recursive search for deliver_to */
- trace(TRACE_DEBUG,
- "%s,%s: looks like a forwarding state",__FILE__,__func__);
- trace(TRACE_DEBUG,
- "%s,%s: checking user %s to %s",__FILE__,__func__,
- address,
- (char *) tempelem3->data);
- if (0 ==
- strcasecmp((char *) tempelem3->
- data, "true"))
- fwdmaysave = 1;
- else if (0 ==
- strcasecmp((char *)
- tempelem3->
- data, "false"))
- fwdmaysave = 0;
- } else if (0 == c2) {
- /* do a recursive search for deliver_to */
- trace(TRACE_DEBUG,
- "%s,%s: looks like a forwarding target",__FILE__,__func__);
- /* rip the prefix off of the result */
- {
- char target
- [AUTH_QUERY_SIZE];
- /* I am much happier now that this is case insensitive :-)
- * albeit at the cost of complication and uglification...
- * perhaps this could be made into a separate function... */
- if (0 ==
- strncasecmp((char *)
- tempelem3->
- data,
- _ldap_cfg.
- fwdtargetprefix,
- strlen
- (_ldap_cfg.
- fwdtargetprefix)))
- {
- /* Offset the pointer by the length of the prefix to skip */
- sscanf((char *)
- tempelem3->
- data +
- strlen
- (_ldap_cfg.
- fwdtargetprefix),
- " %s ",
- &target[0]);
- } else {
- /* The prefix wasn't in there, so just use what we got */
- snprintf(target,
- AUTH_QUERY_SIZE,
- "%s",
- (char *)
- tempelem3->
- data);
- }
- trace(TRACE_DEBUG,
- "%s,%s: checking user %s to %s",__FILE__,__func__,
- address, target);
- occurences += 1;
- list_nodeadd(fwds, target,
- strlen(target)
- + 1);
- }
+ entlist = g_list_first(entlist);
+ while (entlist) {
+ fldlist = g_list_first(entlist->data);
+ for (c2 = 0; c2 < g_list_length(fldlist); c2++) {
+ attlist = g_list_first(fldlist->data);
+ while(attlist) {
+ attrvalue = (char *)attlist->data;
+ if ((strcmp(fields[c2],_ldap_cfg.field_nid)==0)) {
+ trace(TRACE_DEBUG, "%s,%s: restart with user_idnr [%s]",
+ __FILE__,__func__,
+ attrvalue);
+
+ occurences += auth_check_user_ext(attrvalue, userids, fwds, 1);
+ }
+
+ if ((strcmp(fields[c2],_ldap_cfg.field_fwdtarget)==0)) {
+ trace(TRACE_DEBUG, "%s,%s: add forwarding target [%s]",
+ __FILE__,__func__,
+ attrvalue);
+
+ list_nodeadd(fwds, attrvalue, strlen(attrvalue) + 1);
+ occurences += 1;
}
- tempelem3 = tempelem3->nextnode;
+
+ attlist = g_list_next(attlist);
}
- list_freelist(&((struct list *) tempelem2->data)->
- start);
- tempelem2 = tempelem2->nextnode;
+ fldlist = g_list_next(fldlist);
}
- list_freelist(&((struct list *) tempelem1->data)->start);
- tempelem1 = tempelem1->nextnode;
+ entlist = g_list_next(entlist);
}
- list_freelist(&templist.start);
+ dm_ldap_freeresult(entlist);
- trace(TRACE_DEBUG,
- "%s,%s: executing query, checks [%d]",__FILE__,__func__,
- checks);
- /* trace(TRACE_INFO,"auth_check_user(): user [%s] has [%d] entries",address,occurences); */
+ trace(TRACE_DEBUG, "%s,%s: executing query, checks [%d]",__FILE__,__func__, checks);
return occurences;
}
@@ -1193,55 +831,52 @@ int auth_adduser(const char *username, const char *password,
int i, j;
/*int ret; unused variable */
int NUM_MODS = 9;
- char *kaboom = "123";
- char *cid = (char *)dm_malloc(sizeof(char *)*64);
- char *maxm = (char *)dm_malloc(sizeof(char *)*64);
- sprintf(cid,"%llu",clientid);
- sprintf(maxm,"%llu",maxmail);
+ GString *nid = g_string_new("");
+ GString *cid = g_string_new("");
+ GString *maxm = g_string_new("");
+
+ g_string_printf(nid,"%llu",dm_ldap_get_freeid(_ldap_cfg.field_nid));
+ g_string_printf(cid,"%llu",clientid);
+ g_string_printf(maxm,"%llu",maxmail);
- char *cn_values[] = { (char *)username, NULL };
- char *sn_values[] = { (char *)username, NULL };
+ char **obj_values = g_strsplit(_ldap_cfg.objectclass,",",0);
char *pw_values[] = { (char *)password, NULL };
- char *obj_values[] =
- { "top", "person", _ldap_cfg.objectclass, NULL };
char *uid_values[] = { (char *)username, NULL };
- char *cid_values[] = { cid, NULL };
- char *nid_values[] = { kaboom, NULL };
- char *max_values[] = { maxm, NULL };
- field_t cn_type = "cn";
- field_t sn_type = "sn";
+ char *nid_values[] = { nid->str, NULL };
+ char *cid_values[] = { cid->str, NULL };
+ char *max_values[] = { maxm->str, NULL };
+
field_t mail_type = "mail";
field_t obj_type = "objectClass";
unsigned _ldap_dn_len;
-
+
+ GString *t=g_string_new("");
+
assert(user_idnr != NULL);
*user_idnr = 0;
auth_reconnect();
/* Make the malloc for all of the pieces we're about to to sprintf into it */
- _ldap_dn_len =
- strlen("cn=,") + strlen(username) + strlen(_ldap_cfg.base_dn);
- _ldap_dn = (char *) dm_malloc(_ldap_dn_len + 1);
- snprintf(_ldap_dn, _ldap_dn_len, "cn=%s,%s", username,
- _ldap_cfg.base_dn);
+ g_string_printf(t,"%s=%s,%s", _ldap_cfg.cn_string, username, _ldap_cfg.base_dn);
+ _ldap_dn=g_strdup(t->str);
+ _ldap_dn_len=t->len;
+ g_string_free(t,FALSE);
+
trace(TRACE_DEBUG, "%s,%s: Adding user with DN of [%s]", __FILE__, __func__, _ldap_dn);
/* Construct the array of LDAPMod structures representing the attributes
* of the new entry. There's a 12 byte leak here, better find it... */
- _ldap_mod =
- (LDAPMod **) dm_malloc((NUM_MODS + 1) * sizeof(LDAPMod *));
+ _ldap_mod = (LDAPMod **) dm_malloc((NUM_MODS + 1) * sizeof(LDAPMod *));
if (_ldap_mod == NULL) {
- trace(TRACE_ERROR,
- "%s,%s: Cannot allocate memory for mods array", __FILE__, __func__);
+ trace(TRACE_ERROR, "%s,%s: Cannot allocate memory for mods array", __FILE__, __func__);
return -1;
}
for (i = 0; i < NUM_MODS; i++) {
- if ((_ldap_mod[i] =
- (LDAPMod *) dm_malloc(sizeof(LDAPMod))) == NULL) {
+ if ((_ldap_mod[i] = (LDAPMod *) dm_malloc(sizeof(LDAPMod))) == NULL) {
trace(TRACE_ERROR,
"%s,%s: Cannot allocate memory for mods element %d", __FILE__, __func__,
i);
@@ -1257,27 +892,11 @@ int auth_adduser(const char *username, const char *password,
i = 0;
trace(TRACE_DEBUG,
"%s,%s: Starting to define LDAPMod element %d type %s value %s", __FILE__, __func__, i,
- "objectclass", obj_values[0]);
+ "objectclass", g_strjoinv(",",obj_values));
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = obj_type;
_ldap_mod[i]->mod_values = obj_values;
-
- i++;
- trace(TRACE_DEBUG,
- "%s,%s: Starting to define LDAPMod element %d type %s value %s", __FILE__, __func__, i,
- "cn", cn_values[0]);
- _ldap_mod[i]->mod_op = LDAP_MOD_ADD;
- _ldap_mod[i]->mod_type = cn_type;
- _ldap_mod[i]->mod_values = cn_values;
-
- i++;
- trace(TRACE_DEBUG,
- "%s,%s: Starting to define LDAPMod element %d type %s value %s", __FILE__, __func__, i,
- "sn", cn_values[0]);
- _ldap_mod[i]->mod_op = LDAP_MOD_ADD;
- _ldap_mod[i]->mod_type = sn_type;
- _ldap_mod[i]->mod_values = cn_values;
-
+
if (strlen(_ldap_cfg.field_passwd) > 0) {
i++;
trace(TRACE_DEBUG,
@@ -1285,16 +904,16 @@ int auth_adduser(const char *username, const char *password,
i, _ldap_cfg.field_passwd, pw_values[0]);
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = _ldap_cfg.field_passwd;
- _ldap_mod[i]->mod_values = cn_values;
+ _ldap_mod[i]->mod_values = pw_values;
}
i++;
trace(TRACE_DEBUG,
"%s,%s: Starting to define LDAPMod element %d type %s value %s", __FILE__, __func__, i,
- "mail", sn_values[0]);
+ "mail", uid_values[0]);
_ldap_mod[i]->mod_op = LDAP_MOD_ADD;
_ldap_mod[i]->mod_type = mail_type;
- _ldap_mod[i]->mod_values = sn_values;
+ _ldap_mod[i]->mod_values = uid_values;
i++;
trace(TRACE_DEBUG,
@@ -1340,6 +959,8 @@ int auth_adduser(const char *username, const char *password,
/* make sure to free this stuff even if we do bomb out! */
/* there's a 12 byte leak here, but I can't figure out how to fix it :-( */
+ g_strfreev(obj_values);
+
for (i = 0; i < NUM_MODS; i++)
dm_free(_ldap_mod[i]);
dm_free(_ldap_mod);
@@ -1575,96 +1196,89 @@ int auth_change_password(u64_t user_idnr UNUSED,
return -1;
}
-
-int auth_change_clientid(u64_t user_idnr, u64_t newcid)
-{
- int i, j, NUM_MODS = 2;
- char newcid_str[100];
- char *new_values[] = { newcid_str, NULL };
-
- auth_reconnect();
-
- if (!user_idnr) {
- trace(TRACE_ERROR,
- "%s,%s: got NULL as useridnr",__FILE__,__func__);
- return 0;
- }
-
- if (!newcid) {
- trace(TRACE_ERROR,
- "%s,%s: got NULL as newcid",__FILE__,__func__);
- return 0;
- }
-
- snprintf(new_values[0], 100, "%llu", newcid); // Yeah, something like this...
-
- snprintf(_ldap_query, AUTH_QUERY_SIZE, "(%s=%llu)",
- _ldap_cfg.field_nid, user_idnr);
- trace(TRACE_DEBUG,
- "%s,%s: searching with query [%s]",__FILE__,__func__,
- _ldap_query);
- _ldap_err =
- ldap_search_s(_ldap_conn, _ldap_cfg.base_dn,
- _ldap_cfg.scope_int, _ldap_query, _ldap_attrs,
- _ldap_attrsonly, &_ldap_res);
+char * dm_ldap_user_getdn(u64_t user_idnr) {
+ GString *t = g_string_new("");
+ char *dn;
+
+ g_string_printf(t, "(%s=%llu)", _ldap_cfg.field_nid, user_idnr);
+ trace(TRACE_DEBUG, "%s,%s: searching with query [%s]",
+ __FILE__,__func__,
+ t->str);
+
+ _ldap_err = ldap_search_s(_ldap_conn,
+ _ldap_cfg.base_dn,
+ _ldap_cfg.scope_int,
+ t->str,
+ _ldap_attrs,
+ _ldap_attrsonly,
+ &_ldap_res);
+
if (_ldap_err) {
- trace(TRACE_ERROR,
- "%s,%s: could not execute query: %s",__FILE__,__func__,
- ldap_err2string(_ldap_err));
- return 0;
+ trace(TRACE_ERROR, "%s,%s: could not execute query: %s",
+ __FILE__,__func__,
+ ldap_err2string(_ldap_err));
+ g_string_free(t,TRUE);
+ return NULL;
}
if (ldap_count_entries(_ldap_conn, _ldap_res) < 1) {
- trace(TRACE_DEBUG,
- "%s,%s: no entries found",__FILE__,__func__);
+ trace(TRACE_DEBUG, "%s,%s: no entries found",__FILE__,__func__);
+ g_string_free(t,TRUE);
ldap_msgfree(_ldap_res);
- return 0;
+ return NULL;
}
- _ldap_msg = ldap_first_entry(_ldap_conn, _ldap_res);
- if (_ldap_msg == NULL) {
- ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
- &_ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_first_entry failed: %s",__FILE__,__func__,
- ldap_err2string(_ldap_err));
+ if (! (_ldap_msg = ldap_first_entry(_ldap_conn, _ldap_res))) {
+ ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
+ trace(TRACE_ERROR, "%s,%s: ldap_first_entry failed: %s",
+ __FILE__,__func__,
+ ldap_err2string(_ldap_err));
ldap_msgfree(_ldap_res);
- return 0;
+ return NULL;
}
- _ldap_dn = ldap_get_dn(_ldap_conn, _ldap_msg);
- if (_ldap_dn == NULL) {
- ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER,
- &_ldap_err);
- trace(TRACE_ERROR,
- "%s,%s: ldap_get_dn failed: %s",__FILE__,__func__,
- ldap_err2string(_ldap_err));
+ if (! (dn = ldap_get_dn(_ldap_conn, _ldap_msg))) {
+ ldap_get_option(_ldap_conn, LDAP_OPT_ERROR_NUMBER, &_ldap_err);
+ trace(TRACE_ERROR, "%s,%s: ldap_get_dn failed: %s",
+ __FILE__,__func__,
+ ldap_err2string(_ldap_err));
ldap_msgfree(_ldap_res);
- return -1;
+ return NULL;
}
- trace(TRACE_DEBUG,
- "%s,%s: found something at [%s]",__FILE__,__func__, _ldap_dn);
+ return dn;
+}
- /* Construct the array of LDAPMod structures representing the attributes
- * of the new entry. */
- _ldap_mod =
- (LDAPMod **) dm_malloc((NUM_MODS + 1) * sizeof(LDAPMod *));
- if (_ldap_mod == NULL) {
- trace(TRACE_ERROR,
- "%s,%s: Cannot allocate memory for mods array", __FILE__, __func__);
+int auth_change_clientid(u64_t user_idnr, u64_t newcid)
+{
+ int i, j, NUM_MODS = 2;
+ char newcid_str[100];
+ char *new_values[] = { newcid_str, NULL };
+
+ auth_reconnect();
+
+ if (!user_idnr)
+ return 0;
+ if (!newcid)
+ return 0;
+
+ snprintf(new_values[0], 100, "%llu", newcid);
+
+ if (! (_ldap_dn = dm_ldap_user_getdn(user_idnr)))
+ return -1;
+
+ if (! (_ldap_mod = (LDAPMod **) dm_malloc((NUM_MODS + 1) * sizeof(LDAPMod *)))) {
ldap_memfree(_ldap_dn);
ldap_msgfree(_ldap_res);
return -1;
}
for (i = 0; i < NUM_MODS; i++) {
- if ((_ldap_mod[i] =
- (LDAPMod *) dm_malloc(sizeof(LDAPMod))) == NULL) {
- trace(TRACE_ERROR,
- "%s,%s: Cannot allocate memory for mods element %d", __FILE__, __func__,
- i);
+ if ((_ldap_mod[i] = (LDAPMod *) dm_malloc(sizeof(LDAPMod))) == NULL) {
+ trace(TRACE_ERROR, "%s,%s: Cannot allocate memory for mods element %d",
+ __FILE__, __func__,
+ i);
/* Free everything that did get allocated, which is (i-1) elements */
for (j = 0; j < (i - 1); j++)
dm_free(_ldap_mod[j]);
@@ -1876,8 +1490,6 @@ int auth_validate(char *username, char *password, u64_t * user_idnr)
create_current_timestring(&timestring);
snprintf(query, AUTH_QUERY_SIZE, "(%s=%s)", _ldap_cfg.field_uid,
username);
-// ldap_dn = __auth_get_first_match( query, fields );
-// id_char = __auth_get_first_match( query, _ldap_cfg.field_nid );
/* now, try to rebind as the given DN using the supplied password */
trace(TRACE_ERROR,
@@ -1948,24 +1560,6 @@ int auth_get_users_from_clientid(u64_t client_id,
}
/**
- * \brief get deliver_to from alias. Gets a list of deliver_to
- * addresses
- * \param alias the alias
- * \return
- * - NULL on failure
- * - "" if no such alias found
- * - deliver_to address otherwise
- * \attention caller needs to free the return value
- */
-char *auth_get_deliver_from_alias(const char *alias)
-{
- char *deliver_to = (char *)dm_malloc(sizeof(char *));
- deliver_to = NULL;
-
-
- return deliver_to;
-}
-/**
* \brief get a list of aliases associated with a user's user_idnr
* \param user_idnr idnr of user
* \param aliases list of aliases
@@ -1976,9 +1570,29 @@ char *auth_get_deliver_from_alias(const char *alias)
* \attention aliases list needs to be empty. Method calls list_init()
* which sets list->start to NULL.
*/
-int auth_get_user_aliases(u64_t user_idnr, struct list *aliases)
+
+
+
+GList * auth_get_user_aliases(u64_t user_idnr)
{
- return 0;
+ char *fields[] = { _ldap_cfg.field_mail, NULL };
+ GString *t = g_string_new("");
+ GList *aliases = NULL;
+ GList *entlist, *fldlist, *attlist;
+
+ g_string_printf(t,"%s=%llu", _ldap_cfg.field_nid, user_idnr);
+ if ((entlist = __auth_get_every_match(t->str, fields))) {
+ entlist = g_list_first(entlist);
+ fldlist = g_list_first(entlist->data);
+ attlist = g_list_first(fldlist->data);
+ while (attlist) {
+ aliases = g_list_append(aliases, g_strdup(attlist->data));
+ attlist = g_list_next(attlist);
+ }
+ dm_ldap_freeresult(entlist);
+ }
+ g_string_free(t,TRUE);
+ return aliases;
}
@@ -1992,8 +1606,58 @@ int auth_get_user_aliases(u64_t user_idnr, struct list *aliases)
* - 0 on success
* - 1 if alias already exists for given user
*/
-int auth_addalias(u64_t user_idnr, const char *alias, u64_t clientid)
+int auth_addalias(u64_t user_idnr, const char *alias, u64_t clientid UNUSED)
{
+ char *userid = NULL;
+ char **mailValues = NULL;
+ LDAPMod *modify[2], addMail;
+ GList *aliases;
+ int modNumber = 1;
+
+ if (! (userid = auth_get_userid(user_idnr)))
+ return -1;
+
+ /* check the alias newval against the known aliases for this user */
+ aliases = auth_get_user_aliases(user_idnr);
+ aliases = g_list_first(aliases);
+ while (aliases) {
+ if (strcmp(alias,(char *)aliases->data)==0) {
+ g_list_foreach(aliases,(GFunc)g_free,NULL);
+ g_list_free(aliases);
+ return 1;
+ }
+ aliases = g_list_next(aliases);
+ }
+ g_list_foreach(aliases,(GFunc)g_free,NULL);
+ g_list_free(aliases);
+
+ /* get the DN for this user */
+ if (! (_ldap_dn = dm_ldap_user_getdn(user_idnr)))
+ return -1;
+
+ /* construct and apply the changes */
+ mailValues = g_strsplit(alias,",",1);
+
+ addMail.mod_op = LDAP_MOD_ADD;
+ addMail.mod_type = _ldap_cfg.field_mail;
+ addMail.mod_values = mailValues;
+
+ modify[0] = &addMail;
+ modify[1] = NULL;
+
+
+ _ldap_err = ldap_modify_s(_ldap_conn, _ldap_dn, modify);
+ if (_ldap_err) {
+ trace(TRACE_ERROR, "%s,%s: update failed: %s",
+ __FILE__,__func__,
+ ldap_err2string(_ldap_err));
+ g_strfreev(mailValues);
+ ldap_memfree(_ldap_dn);
+ return -1;
+ }
+ g_strfreev(mailValues);
+ ldap_memfree(_ldap_dn);
+
return 0;
}
@@ -2025,6 +1689,65 @@ int auth_addalias_ext(const char *alias, const char *deliver_to,
*/
int auth_removealias(u64_t user_idnr, const char *alias)
{
+ char *userid = NULL;
+ char **mailValues = NULL;
+ LDAPMod *modify[2], delMail;
+ GList *aliases;
+ int modNumber = 1;
+
+ if (! (userid = auth_get_userid(user_idnr)))
+ return -1;
+
+ /* check the alias against the known aliases for this user */
+ aliases = auth_get_user_aliases(user_idnr);
+ aliases = g_list_first(aliases);
+ while (aliases) {
+ if (strcmp(alias,(char *)aliases->data)==0)
+ break;
+
+ aliases = g_list_next(aliases);
+
+ }
+ if (!aliases) {
+ trace(TRACE_DEBUG,"%s,%s: alias [%s] for user [%s] not found",
+ __FILE__, __func__,
+ alias, userid);
+
+ g_list_foreach(aliases,(GFunc)g_free,NULL);
+ g_list_free(aliases);
+ return 1;
+ }
+
+ g_list_foreach(aliases,(GFunc)g_free,NULL);
+ g_list_free(aliases);
+
+ /* get the DN for this user */
+ if (! (_ldap_dn = dm_ldap_user_getdn(user_idnr)))
+ return -1;
+
+ /* construct and apply the changes */
+ mailValues = g_strsplit(alias,",",1);
+
+ delMail.mod_op = LDAP_MOD_DELETE;
+ delMail.mod_type = _ldap_cfg.field_mail;
+ delMail.mod_values = mailValues;
+
+ modify[0] = &delMail;
+ modify[1] = NULL;
+
+
+ _ldap_err = ldap_modify_s(_ldap_conn, _ldap_dn, modify);
+ if (_ldap_err) {
+ trace(TRACE_ERROR, "%s,%s: update failed: %s",
+ __FILE__,__func__,
+ ldap_err2string(_ldap_err));
+ g_strfreev(mailValues);
+ ldap_memfree(_ldap_dn);
+ return -1;
+ }
+ g_strfreev(mailValues);
+ ldap_memfree(_ldap_dn);
+
return 0;
}
@@ -2043,43 +1766,3 @@ int auth_removealias_ext(const char *alias, const char *deliver_to)
}
-/*
-// {
-// int c1, c2, c3;
-// int count1, count2, count3;
-// struct list templist;
-// struct element *tempelem1, *tempelem2, *tempelem3;
-//
-// // do the first entry here
-// tempelem1 = list_getstart( retlist );
-// count1 = retlist->total_nodes;
-//
-// // we'll get the next entry at the _end_ of the loop!
-// printf( "retlist has %d nodes\n", retlist->total_nodes );
-// for( c1 = 0; c1 < count1; c1++ )
-// {
-// tempelem2 = list_getstart( (struct list *)tempelem1->data );
-// count2 = ((struct list *)tempelem1->data)->total_nodes;
-// for( c2 = 0; c2 < count2; c2++ )
-// {
-// //if( tempelem2 )
-// tempelem3 = list_getstart( (struct list *)tempelem2->data );
-// count3 = ((struct list *)tempelem2->data)->total_nodes;
-// for( c3 = 0; c3 < count3; c3++ )
-// {
-// printf( "I've got %s\n", tempelem3->data );
-// tempelem3 = tempelem3->nextnode;
-// //if( tempelem3->nextnode ) tempelem3 = tempelem3->nextnode;
-// // else { printf(" break at %d\n", __LINE__ ); break; }
-// }
-// //if( tempelem2->nextnode ) tempelem2 = tempelem2->nextnode;
-// tempelem2 = tempelem2->nextnode;
-// // else { printf(" break at %d\n", __LINE__ ); break; }
-// }
-// tempelem1 = tempelem1->nextnode;
-// //if( tempelem1->nextnode ) tempelem1 = tempelem1->nextnode;
-// // else { printf(" break at %d\n", __LINE__ ); break; }
-// }
-// }
-//*/
-
diff --git a/auth/authsql.c b/auth/authsql.c
index 7d479f42..d279f771 100644
--- a/auth/authsql.c
+++ b/auth/authsql.c
@@ -87,45 +87,7 @@ int auth_disconnect()
int auth_user_exists(const char *username, u64_t * user_idnr)
{
- const char *query_result;
- char *escaped_username;
-
- assert(user_idnr != NULL);
- *user_idnr = 0;
- if (!username) {
- trace(TRACE_ERROR, "%s,%s: got NULL as username",
- __FILE__, __func__);
- return 0;
- }
-
- if (!(escaped_username = (char *) dm_malloc(strlen(username) * 2 + 1))) {
- trace(TRACE_ERROR, "%s,%s: out of memory allocating "
- "escaped username", __FILE__, __func__);
- return -1;
- }
-
- db_escape_string(escaped_username, username, strlen(username));
-
- snprintf(__auth_query_data, AUTH_QUERY_SIZE,
- "SELECT user_idnr FROM %susers WHERE userid='%s'",DBPFX,
- escaped_username);
- dm_free(escaped_username);
-
- if (__auth_query(__auth_query_data) == -1) {
- trace(TRACE_ERROR, "%s,%s: could not execute query",
- __FILE__, __func__);
- return -1;
- }
-
- if (db_num_rows() == 0) {
- db_free_result();
- return 0;
- }
-
- query_result = db_get_result(0, 0);
- *user_idnr = (query_result) ? strtoull(query_result, 0, 10) : 0;
- db_free_result();
- return 1;
+ return db_user_exists(username, user_idnr);
}
GList * auth_get_known_users(void)
@@ -249,115 +211,7 @@ char *auth_getencryption(u64_t user_idnr)
return __auth_encryption_desc_string;
}
-int auth_check_user(const char *username, struct list *userids, int checks)
-{
- int occurences = 0;
- int r;
- void *saveres;
- u64_t counter;
- unsigned num_rows;
- const char *query_result;
- char *escaped_username;
-
- trace(TRACE_DEBUG, "%s,%s: checking user [%s] in alias table",
- __FILE__, __func__, username);
-
- saveres = db_get_result_set();
- db_set_result_set(NULL);
-
- if (checks > MAX_CHECKS_DEPTH) {
- trace(TRACE_ERROR,
- "%s,%s: maximum checking depth reached, "
- "there probably is a loop in your alias table",
- __FILE__, __func__);
- return -1;
- }
-
- if (!(escaped_username = (char *) dm_malloc(strlen(username) * 2 + 1))) {
- trace(TRACE_ERROR, "%s,%s: out of memory allocating "
- "escaped username", __FILE__, __func__);
- return -1;
- }
-
- db_escape_string(escaped_username, username, strlen(username));
-
- snprintf(__auth_query_data, AUTH_QUERY_SIZE,
- "SELECT deliver_to FROM %saliases WHERE "
- "lower(alias) = lower('%s')",DBPFX, escaped_username);
- dm_free(escaped_username);
-
- trace(TRACE_DEBUG, "%s,%s: checks [%d]", __FILE__, __func__,
- checks);
-
- if (__auth_query(__auth_query_data) == -1) {
- /* copy the old result set */
- db_set_result_set(saveres);
- return 0;
- }
- num_rows = db_num_rows();
- if (num_rows < 1) {
- if (checks > 0) {
- /* found the last one, this is the deliver to
- * but checks needs to be bigger then 0 because
- * else it could be the first query failure */
- list_nodeadd(userids, username,
- strlen(username) + 1);
- trace(TRACE_DEBUG,
- "%s,%s: adding [%s] to deliver_to address",
- __FILE__, __func__, username);
- db_free_result();
- db_set_result_set(saveres);
- return 1;
- } else {
- trace(TRACE_DEBUG,
- "%s,%s: user %s not in aliases table",
- __FILE__, __func__, username);
- db_free_result();
- db_set_result_set(saveres);
- return 0;
- }
- }
-
- trace(TRACE_DEBUG, "%s,%s: into checking loop", __FILE__,
- __func__);
-
- if (num_rows > 0) {
- for (counter = 0; counter < num_rows; counter++) {
- /* do a recursive search for deliver_to */
- query_result = db_get_result(counter, 0);
- trace(TRACE_DEBUG, "%s,%s: checking user %s to %s",
- __FILE__, __func__, username,
- query_result);
-
- r = auth_check_user(query_result, userids,
- (checks < 0) ? 1 : checks + 1);
- if (r < 0) {
- /* loop detected */
- db_free_result();
- db_set_result_set(saveres);
-
- if (checks > 0)
- return -1; /* still in recursive call */
-
- if (userids->start) {
- list_freelist(&userids->start);
- userids->total_nodes = 0;
- }
-
- return 0; /* report to calling routine: no results */
- }
-
- occurences += r;
- }
- }
-
- db_free_result();
- db_set_result_set(saveres);
- return occurences;
-}
-
-int auth_check_user_ext(const char *username, struct list *userids,
- struct list *fwds, int checks)
+int auth_check_user_ext(const char *username, struct list *userids, struct list *fwds, int checks)
{
int occurences = 0;
void *saveres;
@@ -434,11 +288,8 @@ int auth_check_user_ext(const char *username, struct list *userids,
/* do a recursive search for deliver_to */
query_result = db_get_result(counter, 0);
trace(TRACE_DEBUG, "%s,%s: checking user %s to %s",
- __FILE__, __func__, username,
- query_result);
- occurences +=
- auth_check_user_ext(query_result, userids,
- fwds, 1);
+ __FILE__, __func__, username, query_result);
+ occurences += auth_check_user_ext(query_result, userids, fwds, 1);
}
}
db_free_result();
@@ -1195,18 +1046,11 @@ int auth_removealias_ext(const char *alias, const char *deliver_to)
}
-int auth_get_user_aliases(u64_t user_idnr, struct list *aliases)
+GList * auth_get_user_aliases(u64_t user_idnr)
{
int i, n;
const char *query_result;
-
- if (!aliases) {
- trace(TRACE_ERROR, "%s,%s: got a NULL pointer as argument",
- __FILE__, __func__);
- return -2;
- }
-
- list_init(aliases);
+ GList *aliases = NULL;
/* do a inverted (DESC) query because adding the names to the
* final list inverts again */
@@ -1217,23 +1061,21 @@ int auth_get_user_aliases(u64_t user_idnr, struct list *aliases)
if (__auth_query(__auth_query_data) == -1) {
trace(TRACE_ERROR, "%s,%s: could not retrieve list",
__FILE__, __func__);
- return -1;
+ return NULL;
}
n = db_num_rows();
for (i = 0; i < n; i++) {
query_result = db_get_result(i, 0);
- if (!query_result || !list_nodeadd(aliases,
- query_result,
- strlen(query_result) +
- 1)) {
- list_freelist(&aliases->start);
+ if (!query_result || ! (aliases = g_list_append(aliases,g_strdup(query_result)))) {
+ g_list_foreach(aliases, (GFunc)g_free, NULL);
+ g_list_free(aliases);
db_free_result();
- return -2;
+ return NULL;
}
}
db_free_result();
- return 0;
+ return aliases;
}
diff --git a/check_dbmail.h b/check_dbmail.h
index 0a676cdd..727bacb3 100644
--- a/check_dbmail.h
+++ b/check_dbmail.h
@@ -6,7 +6,7 @@ char *raw_message = "From: <vol@inter7.com>\n"
"Received: at mx.inter7.com from localhost\n"
"Received: at localhost from localhost\n"
"MIME-Version: 1.0\n"
- "Content-type: multipart/mixed; boundary=\"boundary\"\n"
+ "Content-type: multipart/mixed; boundary=boundary\n"
"X-Dbmail-ID: 12345\n"
"\n"
"MIME multipart messages specify that there are multiple\n"
@@ -27,7 +27,7 @@ char *raw_message = "From: <vol@inter7.com>\n"
"\n"
"Test message one\n"
"--boundary\n"
- "Content-type: text/plain; charset=us-ascii; name=\"testfile\"\n"
+ "Content-type: text/plain; charset=us-ascii; name=testfile\n"
"Content-transfer-encoding: base64\n"
"\n"
"IyEvYmluL2Jhc2gNCg0KY2xlYXINCmVjaG8gIi4tLS0tLS0tLS0tLS0tLS0t\n"
diff --git a/check_dbmail_deliver.c b/check_dbmail_deliver.c
index 7b414099..636c40eb 100644
--- a/check_dbmail_deliver.c
+++ b/check_dbmail_deliver.c
@@ -41,6 +41,7 @@
#include "debug.h"
#include "db.h"
#include "auth.h"
+#include "misc.h"
#include "check_dbmail.h"
@@ -73,7 +74,7 @@ u64_t get_first_user_idnr(void)
void setup(void)
{
- configure_debug(4,0,1);
+ configure_debug(5,0,1);
config_read(configFile);
GetDBParams(&_db_params);
db_connect();
@@ -194,6 +195,7 @@ START_TEST(test_auth_getmaxmailsize)
u64_t user_idnr = get_first_user_idnr();
result = auth_getmaxmailsize(user_idnr, &maxmail_size);
fail_unless(result>=0,"auth_getmaxmailsize failed");
+ //fail_unless(maxmail_size>=0,"auth_getmaxmailsize return illegal maxmail_size");
}
END_TEST
@@ -220,18 +222,6 @@ END_TEST
/**
- * \brief find all deliver_to addresses for a username (?, code is not exactly
- * clear to me at the moment, IB 21-08-03)
- * \param username
- * \param userids list of user ids (empty on call)
- * \param checks nr of checks. Used internally in recursive calls. It \b should
- * be set to -1 when called!
- * \return number of deliver_to addresses found
- */
-//int auth_check_user(const char *username, struct list *userids,
-// int checks);
-
-/**
* \brief as auth_check_user() but adds the numeric ID of the user found to
* userids or the forward to the fwds list
* \param username
@@ -242,6 +232,17 @@ END_TEST
*/
//int auth_check_user_ext(const char *username, struct list *userids,
// struct list *fwds, int checks);
+START_TEST(test_auth_check_user_ext)
+{
+ struct list uids;
+ struct list fwds;
+ int checks = -1;
+ int result;
+ list_init(&uids);
+ list_init(&fwds);
+ result = auth_check_user_ext("foobar@foobar.org",&uids,&fwds,checks);
+}
+END_TEST
/**
* \brief add a new user to the database (whichever type of database is
* implemented)
@@ -294,6 +295,20 @@ END_TEST
* - 0 on success
*/
//int auth_change_username(u64_t user_idnr, const char *new_name);
+START_TEST(test_auth_change_username)
+{
+ u64_t user_idnr;
+ char *userid;
+ char *old="testuser1";
+ char *new="asdfasdf1";
+ auth_user_exists(old,&user_idnr);
+
+ userid = auth_get_userid(user_idnr);
+ printf("change username %s -> %s\n", old, new);
+
+}
+END_TEST
+
/**
* \brief change a users password
* \param user_idnr
@@ -358,6 +373,16 @@ END_TEST
* \attention caller should free username string
*/
//char *auth_get_userid(u64_t user_idnr);
+START_TEST(test_auth_get_userid)
+{
+ u64_t testidnr;
+ u64_t user_idnr = get_first_user_idnr();
+ char *username = auth_get_userid(user_idnr);
+ fail_unless(strlen(username)>3,"auth_get_userid failed");
+ auth_user_exists(username, &testidnr);
+ fail_unless(testidnr==user_idnr,"auth_get_userid: auth_user_exists returned wrong idnr");
+}
+END_TEST
/**
* \brief get user ids belonging to a client id
@@ -386,15 +411,20 @@ END_TEST
/**
* \brief get a list of aliases associated with a user's user_idnr
* \param user_idnr idnr of user
- * \param aliases list of aliases
- * \return
- * - -2 on memory failure
- * - -1 on database failure
- * - 0 on success
- * \attention aliases list needs to be empty. Method calls list_init()
- * which sets list->start to NULL.
+ * \return aliases list of aliases
*/
-//int auth_get_user_aliases(u64_t user_idnr, struct list *aliases);
+//GList * auth_get_user_aliases(u64_t user_idnr);
+START_TEST(test_auth_get_user_aliases)
+{
+ u64_t user_idnr;
+ char *username="testuser1";
+ GList *aliases;
+ int result;
+ result = auth_user_exists(username, &user_idnr);
+ aliases = auth_get_user_aliases(user_idnr);
+// fail_unless(g_list_length(aliases)>1,"auth_get_user_aliases failed");
+}
+END_TEST
/**
* \brief add an alias for a user
* \param user_idnr user's id
@@ -406,6 +436,17 @@ END_TEST
* - 1 if alias already exists for given user
*/
//int auth_addalias(u64_t user_idnr, const char *alias, u64_t clientid);
+
+START_TEST(test_auth_addalias)
+{
+ int result;
+ u64_t user_idnr;
+ char *username="testuser1";
+ result = auth_user_exists(username,&user_idnr);
+ result = auth_addalias(user_idnr,"addalias@foobar.org",0);
+ fail_unless(result==0,"auth_addalias failed");
+}
+END_TEST
/**
* \brief add an alias to deliver to an extern address
* \param alias the alias
@@ -427,6 +468,17 @@ END_TEST
* - 0 on success
*/
//int auth_removealias(u64_t user_idnr, const char *alias);
+START_TEST(test_auth_removealias)
+{
+ int result;
+ u64_t user_idnr;
+ char *username="testuser1";
+ result = auth_user_exists(username,&user_idnr);
+ result = auth_removealias(user_idnr,"addalias@foobar.org");
+ fail_unless(result==0,"auth_removealias failed");
+}
+END_TEST
+
/**
* \brief remove external delivery address for an alias
* \param alias the alias
@@ -439,6 +491,33 @@ END_TEST
//int auth_removealias_ext(const char *alias, const char *deliver_to);
+#ifdef AUTHLDAP
+//char *dm_ldap_get_filter(const gchar boolean, const gchar *attribute, GList *values)
+
+START_TEST(test_dm_ldap_get_filter)
+{
+ char *result;
+ char *expect = "(&(objectClasses=top)(objectClasses=account)(objectClasses=dbmailUser))";
+ GString *objclasses = g_string_new("top,account,dbmailUser");
+ GList *l = g_string_split(objclasses,",");
+ result = dm_ldap_get_filter('&',"objectClasses",l);
+ fail_unless(strcmp(result,expect)==0,"dm_ldap_get_filter failed");
+}
+END_TEST
+
+START_TEST(test_dm_ldap_get_freeid)
+{
+ u64_t id;
+
+ id = dm_ldap_get_freeid("uidNumber");
+ fail_unless(id != 0,"dm_ldap_get_freeid failed");
+
+ return;
+}
+END_TEST
+
+#endif
+
Suite *dbmail_deliver_suite(void)
{
@@ -455,29 +534,27 @@ Suite *dbmail_deliver_suite(void)
tcase_add_test(tc_auth, test_auth_getclientid);
tcase_add_test(tc_auth, test_auth_getmaxmailsize);
tcase_add_test(tc_auth, test_auth_getencryption);
- /*
- tcase_add_test(tc_auth, test_auth_check_user);
tcase_add_test(tc_auth, test_auth_check_user_ext);
- */
tcase_add_test(tc_auth, test_auth_adduser);
tcase_add_test(tc_auth, test_auth_delete_user);
- /*
- tcase_add_test(tc_auth, test_auth_change_username);
- tcase_add_test(tc_auth, test_auth_change_password);
- tcase_add_test(tc_auth, test_auth_change_clientid);
- tcase_add_test(tc_auth, test_auth_change_mailboxsize);
- tcase_add_test(tc_auth, test_auth_validate);
- tcase_add_test(tc_auth, test_auth_md5_validate);
- tcase_add_test(tc_auth, test_get_userid);
- tcase_add_test(tc_auth, test_get_users_from_clientid);
- tcase_add_test(tc_auth, test_get_deliver_from_alias);
- tcase_add_test(tc_auth, test_get_user_aliases);
+// tcase_add_test(tc_auth, test_auth_change_username);
+// tcase_add_test(tc_auth, test_auth_change_password);
+// tcase_add_test(tc_auth, test_auth_change_clientid);
+// tcase_add_test(tc_auth, test_auth_change_mailboxsize);
+// tcase_add_test(tc_auth, test_auth_validate);
+// tcase_add_test(tc_auth, test_auth_md5_validate);
+ tcase_add_test(tc_auth, test_auth_get_userid);
+// tcase_add_test(tc_auth, test_auth_get_users_from_clientid);
+ tcase_add_test(tc_auth, test_auth_get_user_aliases);
tcase_add_test(tc_auth, test_auth_addalias);
- tcase_add_test(tc_auth, test_auth_addalias_ext);
+// tcase_add_test(tc_auth, test_auth_addalias_ext);
tcase_add_test(tc_auth, test_auth_removealias);
- tcase_add_test(tc_auth, test_auth_removealias_ext);
- */
-
+// tcase_add_test(tc_auth, test_auth_removealias_ext);
+#ifdef AUTHLDAP
+ tcase_add_test(tc_auth, test_dm_ldap_get_filter);
+ tcase_add_test(tc_auth, test_dm_ldap_get_freeid);
+#endif
+
return s;
}
diff --git a/check_dbmail_imapd.c b/check_dbmail_imapd.c
index a4e6d82a..bcda695b 100644
--- a/check_dbmail_imapd.c
+++ b/check_dbmail_imapd.c
@@ -155,7 +155,7 @@ START_TEST(test_mime_readheader)
list_init(&mimelist);
res = mime_readheader(raw_message,&blkidx,&mimelist,&headersize);
fail_unless(res==9, "number of newlines incorrect");
- fail_unless(blkidx==238, "blkidx incorrect");
+ fail_unless(blkidx==236, "blkidx incorrect");
fail_unless(headersize==blkidx+res, "headersize incorrect");
fail_unless(mimelist.total_nodes==7, "number of message-headers incorrect");
list_freelist(&mimelist.start);
diff --git a/check_dbmail_message.c b/check_dbmail_message.c
index 14c362a8..8e2056bf 100644
--- a/check_dbmail_message.c
+++ b/check_dbmail_message.c
@@ -175,13 +175,13 @@ START_TEST(test_dbmail_message_get_rfcsize)
}
END_TEST
-//void dbmail_message_delete(struct DbmailMessage *self);
-/*
-START_TEST(test_dbmail_message_delete)
+//void dbmail_message_free(struct DbmailMessage *self);
+START_TEST(test_dbmail_message_free)
{
+ struct DbmailMessage *m = dbmail_message_new();
+ dbmail_message_free(m);
}
END_TEST
-*/
START_TEST(test_dbmail_message_new_from_stream)
{
@@ -228,7 +228,7 @@ Suite *dbmail_message_suite(void)
tcase_add_test(tc_message, test_dbmail_message_hdrs_to_string);
tcase_add_test(tc_message, test_dbmail_message_body_to_string);
tcase_add_test(tc_message, test_dbmail_message_get_rfcsize);
-// tcase_add_test(tc_message, test_dbmail_message_delete);
+ tcase_add_test(tc_message, test_dbmail_message_free);
return s;
}
diff --git a/db.c b/db.c
index 31f2ef49..73502780 100644
--- a/db.c
+++ b/db.c
@@ -790,69 +790,6 @@ int db_insert_physmessage(u64_t * physmessage_id)
return 1;
}
-int db_insert_message(u64_t user_idnr,
- const char *mailbox,
- int create_or_error_mailbox,
- const char *unique_id, u64_t * message_idnr)
-{
- u64_t mailboxid;
- u64_t physmessage_id;
- int result;
-
- assert(message_idnr);
- assert(unique_id);
-
- if (!mailbox)
- mailbox = dm_strdup("INBOX");
-
- switch (create_or_error_mailbox) {
- case CREATE_IF_MBOX_NOT_FOUND:
- result =
- db_find_create_mailbox(mailbox, user_idnr, &mailboxid);
- break;
- case ERROR_IF_MBOX_NOT_FOUND:
- default:
- result = db_findmailbox(mailbox, user_idnr, &mailboxid);
- break;
- }
-
- if (result == -1) {
- trace(TRACE_ERROR,
- "%s,%s: error finding and/or creating mailbox [%s]",
- __FILE__, __func__, mailbox);
- return -1;
- }
- if (mailboxid == 0) {
- trace(TRACE_WARNING,
- "%s,%s: mailbox [%s] could not be found!", __FILE__,
- __func__, mailbox);
- return -1;
- }
-
- /* insert a new physmessage entry */
- if (db_insert_physmessage(&physmessage_id) == -1) {
- trace(TRACE_ERROR, "%s,%s: error inserting physmessage",
- __FILE__, __func__);
- return -1;
- }
-
- /* now insert an entry into the messages table */
- snprintf(query, DEF_QUERYSIZE, "INSERT INTO "
- "%smessages(mailbox_idnr, physmessage_id, unique_id,"
- "recent_flag, status) "
- "VALUES ('%llu', '%llu', '%s', '1', '%d')",
- DBPFX, mailboxid, physmessage_id, unique_id,
- MESSAGE_STATUS_INSERT);
-
- if (db_query(query) == -1) {
- trace(TRACE_STOP, "%s,%s: query failed", __FILE__, __func__);
- return -1;
- }
-
- *message_idnr = db_insert_result("message_idnr");
- return 1;
-}
-
int db_message_set_unique_id(u64_t message_idnr, const char *unique_id)
{
assert(unique_id);
@@ -2663,15 +2600,12 @@ int db_find_create_mailbox(const char *name, u64_t owner_idnr,
if (db_findmailbox_owner(name, owner_idnr, &mboxidnr) != 1) {
/* Did we fail to create the mailbox? */
if (db_createmailbox(name, owner_idnr, &mboxidnr) != 0) {
- /* Serious failure situation! */
- trace(TRACE_ERROR,
- "%s, %s: seriously could not create mailbox [%s]",
- __FILE__, __func__, name);
+ trace(TRACE_ERROR, "%s, %s: could not create mailbox [%s]",
+ __FILE__, __func__, name);
return -1;
}
- trace(TRACE_DEBUG,
- "%s, %s: mailbox [%s] created on the fly", __FILE__,
- __func__, name);
+ trace(TRACE_DEBUG, "%s, %s: mailbox [%s] created on the fly",
+ __FILE__, __func__, name);
}
trace(TRACE_DEBUG, "%s, %s: mailbox [%s] found",
__FILE__, __func__, name);
@@ -4024,4 +3958,46 @@ int db_getmailbox_list_result(u64_t mailbox_idnr, u64_t user_idnr, mailbox_t * m
return 0;
}
+int db_user_exists(const char *username, u64_t * user_idnr)
+{
+ const char *query_result;
+ char *escaped_username;
+
+ assert(user_idnr != NULL);
+ *user_idnr = 0;
+ if (!username) {
+ trace(TRACE_ERROR, "%s,%s: got NULL as username",
+ __FILE__, __func__);
+ return 0;
+ }
+
+ if (!(escaped_username = (char *) dm_malloc(strlen(username) * 2 + 1))) {
+ trace(TRACE_ERROR, "%s,%s: out of memory allocating "
+ "escaped username", __FILE__, __func__);
+ return -1;
+ }
+
+ db_escape_string(escaped_username, username, strlen(username));
+
+ snprintf(query, DEF_QUERYSIZE,
+ "SELECT user_idnr FROM %susers WHERE userid='%s'",DBPFX,
+ escaped_username);
+ dm_free(escaped_username);
+
+ if (db_query(query) == -1) {
+ trace(TRACE_ERROR, "%s,%s: could not execute query",
+ __FILE__, __func__);
+ return -1;
+ }
+
+ if (db_num_rows() == 0) {
+ db_free_result();
+ return 0;
+ }
+
+ query_result = db_get_result(0, 0);
+ *user_idnr = (query_result) ? strtoull(query_result, 0, 10) : 0;
+ db_free_result();
+ return 1;
+}
diff --git a/db.h b/db.h
index 9214bdfe..098eabc8 100644
--- a/db.h
+++ b/db.h
@@ -473,29 +473,6 @@ int db_insert_physmessage_with_internal_date(timestring_t internal_date,
u64_t * physmessage_id);
/**
- * \brief insert a message into inbox. This function creates an entry
- * into the messages table and an entry into the physmessage table
- * \param user_idnr user idnr
- * \param deliver_to mailbox to deliver to
- * \param create_or_error_mailbox responds to the constants
- * - CREATE_IF_MBOX_NOT_FOUND
- * - ERROR_IF_MBOX_NOT_FOUND
- * \param unique_id unique id of message
- * \param messge_idnr call by reference to new message id number
- * \return
- * - -1 on failure
- * - 1 on success
- */
-int db_insert_message(u64_t user_idnr,
- const char *deliver_to,
- int create_or_error_mailbox,
- const char *unique_id, u64_t * message_idnr);
-
-#define CREATE_IF_MBOX_NOT_FOUND 1
-#define ERROR_IF_MBOX_NOT_FOUND -1
-
-
-/**
* \brief update unique_id, message_size and rfc_size of
* a message identified by message_idnr
* \param message_idnr
@@ -1261,4 +1238,11 @@ char *date2char_str(const char *column);
int db_getmailbox_list_result(u64_t mailbox_idnr, u64_t user_idnr, mailbox_t * mb);
+
+/*
+ * db-user accessors
+ */
+
+int db_user_exists(const char *username, u64_t * user_idnr);
+
#endif
diff --git a/dbmail-message.c b/dbmail-message.c
index 23e94868..e29a38bc 100644
--- a/dbmail-message.c
+++ b/dbmail-message.c
@@ -70,6 +70,10 @@ static void _map_headers(struct DbmailMessage *self);
static void _set_content(struct DbmailMessage *self, const GString *content);
static void _set_content_from_stream(struct DbmailMessage *self, GMimeStream *stream, int type);
+static int _message_insert(struct DbmailMessage *self,
+ u64_t user_idnr,
+ const char *mailbox,
+ const char *unique_id);
struct DbmailMessage * dbmail_message_new(void)
{
@@ -126,7 +130,6 @@ struct DbmailMessage * dbmail_message_init_with_string(struct DbmailMessage *sel
}
_map_headers(self);
- self->rfcsize = dbmail_message_get_rfcsize(self);
return self;
}
@@ -134,7 +137,6 @@ struct DbmailMessage * dbmail_message_init_with_stream(struct DbmailMessage *sel
{
_set_content_from_stream(self,stream,type);
_map_headers(self);
- self->rfcsize = dbmail_message_get_rfcsize(self);
return self;
}
@@ -194,7 +196,6 @@ static void _set_content_from_stream(struct DbmailMessage *self, GMimeStream *st
break;
}
- self->size = g_mime_stream_length(ostream);
g_object_unref(filter);
g_object_unref(fstream);
@@ -226,11 +227,9 @@ size_t dbmail_message_get_rfcsize(struct DbmailMessage *self)
* the rfcsize
*/
+ size_t rfcsize;
GMimeStream *ostream, *fstream;
GMimeFilter *filter;
-
- if (self->rfcsize)
- return self->rfcsize;
ostream = g_mime_stream_mem_new();
fstream = g_mime_stream_filter_new_with_stream(ostream);
@@ -239,42 +238,60 @@ size_t dbmail_message_get_rfcsize(struct DbmailMessage *self)
g_mime_stream_filter_add((GMimeStreamFilter *) fstream, filter);
g_mime_object_write_to_stream((GMimeObject *)self->content,fstream);
- self->rfcsize = g_mime_stream_length(ostream);
+ rfcsize = g_mime_stream_length(ostream);
g_object_unref(filter);
g_object_unref(fstream);
g_object_unref(ostream);
- return self->rfcsize;
+ return rfcsize;
}
+/* dump message(parts) to char ptrs */
gchar * dbmail_message_to_string(struct DbmailMessage *self)
{
gchar *s;
- GString *msg = g_string_new(g_mime_object_to_string(GMIME_OBJECT(self->content)));
- s=msg->str;
- g_string_free(msg,FALSE);
+ GString *t;
+ assert(self->content);
+
+ t = g_string_new(g_mime_object_to_string(GMIME_OBJECT(self->content)));
+
+ s = t->str;
+ g_string_free(t,FALSE);
return s;
}
-
gchar * dbmail_message_hdrs_to_string(struct DbmailMessage *self)
{
char *s;
- GString *headers = g_string_new(g_mime_object_get_headers((GMimeObject *)(self->content)));
- s = headers->str;
- g_string_free(headers,FALSE);
+ GString *t;
+ assert(self->headers);
+
+ t = g_string_new(g_mime_object_get_headers((GMimeObject *)(self->content)));
+
+ s = t->str;
+ g_string_free(t,FALSE);
return s;
}
-
gchar * dbmail_message_body_to_string(struct DbmailMessage *self)
{
char *s;
- GString *body;
- body = g_string_new(g_mime_object_to_string((GMimeObject *)(self->content)));
- body = g_string_erase(body,0,dbmail_message_get_hdrs_size(self));
- s = body->str;
- g_string_free(body,FALSE);
+ GString *t;
+ assert(self->content);
+
+ t = g_string_new(g_mime_object_to_string((GMimeObject *)(self->content)));
+ t = g_string_erase(t,0,dbmail_message_get_hdrs_size(self));
+
+ s = t->str;
+ g_string_free(t,FALSE);
return s;
}
+/*
+ * we don't cache these values
+ * to allow changes in message content
+ */
+size_t dbmail_message_get_size(struct DbmailMessage *self)
+{
+ return strlen(dbmail_message_to_string(self));
+}
size_t dbmail_message_get_hdrs_size(struct DbmailMessage *self)
{
return strlen(dbmail_message_hdrs_to_string(self));
@@ -284,20 +301,15 @@ size_t dbmail_message_get_body_size(struct DbmailMessage *self)
return strlen(dbmail_message_body_to_string(self));
}
-size_t dbmail_message_get_size(struct DbmailMessage *self)
+void dbmail_message_free(struct DbmailMessage *self)
{
- return self->size;
-}
-
-void dbmail_message_delete(struct DbmailMessage *self)
-{
- g_relation_destroy(self->headers);
- g_object_unref(self->content);
+ if (self->headers)
+ g_relation_destroy(self->headers);
+ if (self->content)
+ g_object_unref(self->content);
self->headers=NULL;
self->content=NULL;
self->id=0;
- self->size=0;
- self->rfcsize=0;
dm_free(self);
}
@@ -393,20 +405,15 @@ struct DbmailMessage * dbmail_message_retrieve(struct DbmailMessage *self, u64_t
/**
* store a temporary copy of a message.
- * \param header the header to the message
- * \param body body of the message
- * \param headersize size of header
- * \param bodysize size of body
- * \param rfcsize rfc size of message
- * \param[out] temp_message_idnr message idnr of temporary message
+ * \param self
+ * \param[out] temp_message_idnr message idnr of temporary message
* \return
* - -1 on error
* - 1 on success
*/
-int dbmail_message_store_temp(struct DbmailMessage *self, /*@out@*/ u64_t * temp_message_idnr)
+int dbmail_message_store_temp(struct DbmailMessage *self)
{
u64_t user_idnr;
- u64_t msgidnr;
u64_t messageblk_idnr;
char unique_id[UID_SIZE];
char *hdrs, *body;
@@ -430,7 +437,7 @@ int dbmail_message_store_temp(struct DbmailMessage *self, /*@out@*/ u64_t * temp
create_unique_id(unique_id, user_idnr);
/* create a message record */
- if(db_insert_message(user_idnr, DBMAIL_TEMPMBOX, CREATE_IF_MBOX_NOT_FOUND, unique_id, &msgidnr) < 0)
+ if(_message_insert(self, user_idnr, DBMAIL_TEMPMBOX, unique_id) < 0)
return -1;
hdrs = dbmail_message_hdrs_to_string(self);
@@ -439,26 +446,66 @@ int dbmail_message_store_temp(struct DbmailMessage *self, /*@out@*/ u64_t * temp
body_size = (u64_t)dbmail_message_get_body_size(self);
rfcsize = (u64_t)dbmail_message_get_rfcsize(self);
-
- if(db_insert_message_block(hdrs, hdrs_size, msgidnr, &messageblk_idnr,1) < 0)
+ if(db_insert_message_block(hdrs, hdrs_size, self->id, &messageblk_idnr,1) < 0)
return -1;
trace(TRACE_DEBUG, "%s,%s: allocating [%ld] bytes of memory "
"for readblock", __FILE__, __func__, READ_BLOCK_SIZE);
/* store body in several blocks (if needed */
- if (store_message_in_blocks(body, body_size, msgidnr) < 0)
+ if (store_message_in_blocks(body, body_size, self->id) < 0)
return -1;
- if (db_update_message(msgidnr, unique_id, (hdrs_size + body_size), rfcsize) < 0)
+ if (db_update_message(self->id, unique_id, (hdrs_size + body_size), rfcsize) < 0)
return -1;
- *temp_message_idnr = msgidnr;
-
g_free(hdrs);
g_free(body);
return 1;
}
+int _message_insert(struct DbmailMessage *self,
+ u64_t user_idnr,
+ const char *mailbox,
+ const char *unique_id)
+{
+ u64_t mailboxid;
+ u64_t physmessage_id;
+
+ assert(unique_id);
+
+ if (!mailbox)
+ mailbox = dm_strdup("INBOX");
+
+ if (db_find_create_mailbox(mailbox, user_idnr, &mailboxid) == -1)
+ return -1;
+
+ if (mailboxid == 0) {
+ trace(TRACE_ERROR, "%s,%s: mailbox [%s] could not be found!",
+ __FILE__, __func__, mailbox);
+ return -1;
+ }
+
+ /* insert a new physmessage entry */
+ if (db_insert_physmessage(&physmessage_id) == -1)
+ return -1;
+
+ /* now insert an entry into the messages table */
+ snprintf(query, DEF_QUERYSIZE, "INSERT INTO "
+ "%smessages(mailbox_idnr, physmessage_id, unique_id,"
+ "recent_flag, status) "
+ "VALUES ('%llu', '%llu', '%s', '1', '%d')",
+ DBPFX, mailboxid, physmessage_id, unique_id,
+ MESSAGE_STATUS_INSERT);
+
+ if (db_query(query) == -1) {
+ trace(TRACE_STOP, "%s,%s: query failed", __FILE__, __func__);
+ return -1;
+ }
+
+ self->id = db_insert_result("message_idnr");
+ return 1;
+}
+
diff --git a/dbmail-message.h b/dbmail-message.h
index 90497eb4..d1830393 100644
--- a/dbmail-message.h
+++ b/dbmail-message.h
@@ -64,10 +64,8 @@ enum DBMAIL_STREAM_TYPE {
};
struct DbmailMessage {
- gulong id;
+ u64_t id;
enum DBMAIL_MESSAGE_CLASS klass;
- size_t size;
- size_t rfcsize;
GMimeObject *content;
GRelation *headers;
};
@@ -95,13 +93,12 @@ gchar * dbmail_message_to_string(struct DbmailMessage *self);
gchar * dbmail_message_hdrs_to_string(struct DbmailMessage *self);
gchar * dbmail_message_body_to_string(struct DbmailMessage *self);
-size_t dbmail_message_get_hdrs_size(struct DbmailMessage *self);
-size_t dbmail_message_get_body_size(struct DbmailMessage *self);
-
size_t dbmail_message_get_size(struct DbmailMessage *self);
size_t dbmail_message_get_rfcsize(struct DbmailMessage *self);
+size_t dbmail_message_get_hdrs_size(struct DbmailMessage *self);
+size_t dbmail_message_get_body_size(struct DbmailMessage *self);
-void dbmail_message_delete(struct DbmailMessage *self);
+void dbmail_message_free(struct DbmailMessage *self);
/*
*
@@ -112,13 +109,11 @@ void dbmail_message_delete(struct DbmailMessage *self);
/**
* store a temporary copy of a message.
- * \param message pointer to dbmailmessage struct
- * \param[out] temp_message_idnr message idnr of temporary message
* \return
* - -1 on error
* - 1 on success
*/
-int dbmail_message_store_temp(struct DbmailMessage *message, /*@out@*/ u64_t * temp_message_idnr);
+int dbmail_message_store_temp(struct DbmailMessage *message);
#endif
diff --git a/dbmail.h b/dbmail.h
index 2e94398e..0306e143 100644
--- a/dbmail.h
+++ b/dbmail.h
@@ -165,4 +165,5 @@ void GetDBParams(db_param_t * db_params);
*/
void SetTraceLevel(const char *service_name);
+
#endif
diff --git a/debian/rules b/debian/rules
index af10bfeb..d55319e5 100755
--- a/debian/rules
+++ b/debian/rules
@@ -10,7 +10,8 @@ export DH_COMPAT=3
export DEB_BUILD_OPTIONS=debug
#export WITH_GC="--with-gc"
-export WITH_CHECK="--with-check"
+export WITH_CHECK=--with-check
+export NOSHARED=--enable-share=no
CFLAGS = -Wall -O1
LDFLAGS = -lcrypt
@@ -35,7 +36,7 @@ include /usr/share/dpatch/dpatch.make
CONFFLAGS=--host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr --mandir=\$${prefix}/share/man --sysconfdir=/etc/dbmail/ \
- --infodir=\$${prefix}/share/info $(WITH_GC) $(WITH_CHECK)
+ --infodir=\$${prefix}/share/info $(WITH_GC) $(WITH_CHECK) $(NOSHARED)
build: stamps/build
stamps/build: stamps patch configure $(PACKAGES)
diff --git a/imaputil.c b/imaputil.c
index 50c85258..6a01d011 100644
--- a/imaputil.c
+++ b/imaputil.c
@@ -102,56 +102,6 @@ const char *envelope_items[] = {
static const char *search_cost[] = { "b","b","c","c","c","d","d","d","d","c","e","e","b","b","j","j","j" };
-/*
- *
- *
- * Some basic string handling utilities
- *
- *
- *
- */
-GString * g_list_join(GList * list, char * sep)
-{
- GString *string = g_string_new("");
- if (sep == NULL)
- sep="";
- if (list == NULL)
- return string;
- list = g_list_first(list);
- string = g_string_append(string, (gchar *)list->data);
- while((list = g_list_next(list))) {
- string = g_string_append(string,sep);
- string = g_string_append(string,(gchar *)list->data);
- }
- return string;
-}
-
-GList * g_string_split(GString * string, char * sep)
-{
- GList * list = NULL;
- char **array = (char **)g_strsplit((const gchar *)string->str, (const gchar *)sep,0);
- int i, len = 0;
- while(array[len++]);
- len--;
- for (i=0; i<len; i++)
- list = g_list_append(list,g_strdup(array[i]));
- g_strfreev(array);
- return list;
-}
-/*
- * append a formatted GString to a GList
- */
-GList * g_list_append_printf(GList * list, char * format, ...)
-{
- char *str = (char *)dm_malloc(sizeof(char) * BUFLEN);
- va_list argp;
- va_start(argp, format);
- vsnprintf(str, sizeof(char) * BUFLEN, format, argp);
- list = g_list_append(list, strdup(str));
- dm_free(str);
- return list;
-}
-
/* some basic imap type utils */
/*
diff --git a/imaputil.h b/imaputil.h
index 030a1adf..8aa592f8 100644
--- a/imaputil.h
+++ b/imaputil.h
@@ -98,10 +98,6 @@ char * dbmail_imap_astring_as_string(const char *s);
char * dbmail_imap_plist_as_string(GList *plist);
GList *dbmail_imap_list_slices(GList *list, unsigned limit);
-GString * g_list_join(GList * list, char * sep);
-GList * g_string_split(GString * string, char * sep);
-GList * g_list_append_printf(GList * list, char * format, ...);
-
int mime_unwrap(char *to, const char *from);
int sort_search(struct list *searchlist);
diff --git a/list.c b/list.c
index a62bda67..a6f8ba27 100644
--- a/list.c
+++ b/list.c
@@ -217,6 +217,19 @@ void list_showlist(struct list *tlist)
temp = temp->nextnode;
}
}
+/*
+ * shallow copy of struct list into GList
+ */
+
+GList * g_list_copy_list(GList *dst, struct element *el)
+{
+ while(el) {
+ dst = g_list_append(dst, el->data);
+ el = el->nextnode;
+ }
+ return dst;
+}
+
/* basic binary tree */
void list_btree_insert(sortitems_t ** tree, sortitems_t * item) {
diff --git a/list.h b/list.h
index 2d9f7e83..65162856 100644
--- a/list.h
+++ b/list.h
@@ -57,6 +57,8 @@ long list_totalnodes(struct list *tlist);
void list_showlist(struct list *tlist);
void list_init(struct list *tlist);
+GList * g_list_copy_list(GList *dst, struct element *el);
+
/* this function had to be renamed because some MySQL versions
* export a function with the name list_reverse(). Nice of them,
* but a pretty "strange" way to pollute the global namespace
diff --git a/main.c b/main.c
index 9f143a24..03b4e9d4 100644
--- a/main.c
+++ b/main.c
@@ -392,7 +392,7 @@ int main(int argc, char *argv[])
list_freelist(&returnpath.start);
list_freelist(&users.start);
- dbmail_message_delete(msg);
+ dbmail_message_free(msg);
trace(TRACE_DEBUG, "main(): they're all free. we're done.");
diff --git a/misc.c b/misc.c
index 7b513cbd..388626c9 100644
--- a/misc.c
+++ b/misc.c
@@ -491,3 +491,54 @@ int find_bounded(char *value, char left, char right, char **retchar,
return 0;
}
}
+
+/*
+ *
+ *
+ * Some basic string handling utilities
+ *
+ *
+ *
+ */
+GString * g_list_join(GList * list, char * sep)
+{
+ GString *string = g_string_new("");
+ if (sep == NULL)
+ sep="";
+ if (list == NULL)
+ return string;
+ list = g_list_first(list);
+ string = g_string_append(string, (gchar *)list->data);
+ while((list = g_list_next(list))) {
+ string = g_string_append(string,sep);
+ string = g_string_append(string,(gchar *)list->data);
+ }
+ return string;
+}
+
+GList * g_string_split(GString * string, char * sep)
+{
+ GList * list = NULL;
+ char **array = (char **)g_strsplit((const gchar *)string->str, (const gchar *)sep,0);
+ int i, len = 0;
+ while(array[len++]);
+ len--;
+ for (i=0; i<len; i++)
+ list = g_list_append(list,g_strdup(array[i]));
+ g_strfreev(array);
+ return list;
+}
+/*
+ * append a formatted GString to a GList
+ */
+GList * g_list_append_printf(GList * list, char * format, ...)
+{
+ char *str = (char *)dm_malloc(sizeof(char) * BUFLEN);
+ va_list argp;
+ va_start(argp, format);
+ vsnprintf(str, sizeof(char) * BUFLEN, format, argp);
+ list = g_list_append(list, strdup(str));
+ dm_free(str);
+ return list;
+}
+
diff --git a/misc.h b/misc.h
index 841afc21..c0ec8489 100644
--- a/misc.h
+++ b/misc.h
@@ -35,6 +35,8 @@
#include "debug.h"
#include "list.h"
+#define BUFLEN 2048
+
/**
\brief drop process privileges. Change change euid and egid to
uid and gid of newuser and newgroup
@@ -108,4 +110,8 @@ int find_bounded(char *value, char left, char right, char **retchar,
int base64_grow_ret(char ***inchar, size_t ** inint, size_t newcount,
size_t newchar);
+GString * g_list_join(GList * list, char * sep);
+GList * g_string_split(GString * string, char * sep);
+GList * g_list_append_printf(GList * list, char * format, ...);
+
#endif
diff --git a/pipe.c b/pipe.c
index 34dae7b9..0a796777 100644
--- a/pipe.c
+++ b/pipe.c
@@ -424,7 +424,7 @@ int insert_messages(struct DbmailMessage *message,
char *header, *body;
u64_t headersize, bodysize, rfcsize;
struct element *element, *ret_path;
- u64_t msgsize, tmpmsgidnr;
+ u64_t msgsize;
/* first start a new database transaction */
if (db_begin_transaction() < 0) {
@@ -434,17 +434,15 @@ int insert_messages(struct DbmailMessage *message,
return -1;
}
- switch (dbmail_message_store_temp(message, &tmpmsgidnr)) {
+ switch (dbmail_message_store_temp(message)) {
case -1:
- /* Major trouble. Bail out immediately. */
- trace(TRACE_ERROR,
- "%s, %s: failed to store temporary message.",
+ trace(TRACE_ERROR, "%s, %s: failed to store temporary message.",
__FILE__, __func__);
db_rollback_transaction();
return -1;
default:
trace(TRACE_DEBUG, "%s, %s: temporary msgidnr is [%llu]",
- __FILE__, __func__, tmpmsgidnr);
+ __FILE__, __func__, message->id);
break;
}
@@ -474,7 +472,7 @@ int insert_messages(struct DbmailMessage *message,
"%s, %s: calling sort_and_deliver for useridnr [%llu]",
__FILE__, __func__, useridnr);
- switch (sort_and_deliver(tmpmsgidnr, header, headersize, msgsize, useridnr, delivery->mailbox)) {
+ switch (sort_and_deliver(message->id, header, headersize, msgsize, useridnr, delivery->mailbox)) {
case DSN_CLASS_OK:
/* Indicate success. */
trace(TRACE_DEBUG,
@@ -548,7 +546,7 @@ int insert_messages(struct DbmailMessage *message,
ret_path = list_getstart(returnpath);
/* Forward using the temporary stored message. */
- if (forward(tmpmsgidnr, delivery->forwards,
+ if (forward(message->id, delivery->forwards,
(ret_path ? ret_path->
data : "DBMAIL-MAILER"), header,
headersize) < 0)
@@ -563,9 +561,9 @@ int insert_messages(struct DbmailMessage *message,
/* Always delete the temporary message, even if the delivery failed.
* It is the MTA's job to requeue or bounce the message,
* and our job to keep a tidy database ;-) */
- if (db_delete_message(tmpmsgidnr) < 0)
+ if (db_delete_message(message->id) < 0)
trace(TRACE_ERROR, "%s,%s: failed to delete temporary message "
- "[%llu]", __FILE__, __func__, tmpmsgidnr);
+ "[%llu]", __FILE__, __func__, message->id);
trace(TRACE_DEBUG,
"insert_messages(): temporary message deleted from database");
diff --git a/user.c b/user.c
index cf738cf0..3cae58fb 100644
--- a/user.c
+++ b/user.c
@@ -35,6 +35,7 @@
#include "list.h"
#include "debug.h"
#include "db.h"
+#include "misc.h"
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
@@ -103,8 +104,8 @@ int do_add(const char * const user,
const char * const password,
const char * const enctype,
const u64_t maxmail, const u64_t clientid,
- struct list * const alias_add,
- struct list * const alias_del);
+ GList * alias_add,
+ GList * alias_del);
int do_delete(const u64_t useridnr, const char * const user);
int do_show(const char * const user);
int do_empty(const u64_t useridnr);
@@ -116,12 +117,12 @@ int do_password(const u64_t useridnr,
const char * const password,
const char * const enctype);
int do_aliases(const u64_t useridnr,
- struct list * const alias_add,
- struct list * const alias_del);
+ GList * alias_add,
+ GList * alias_del);
/* External forwards */
int do_forwards(const char *alias, const u64_t clientid,
- struct list * const fwds_add,
- struct list * const fwds_del);
+ GList * fwds_add,
+ GList * fwds_del);
/* Helper functions */
int is_valid(const char * const str);
@@ -185,14 +186,10 @@ int main(int argc, char *argv[])
*passwdfile = NULL;
char *password = NULL, *enctype = NULL;
u64_t useridnr = 0, clientid = 0, maxmail = 0;
- struct list alias_add, alias_del, fwds_add, fwds_del;
+ GList *alias_add = NULL, *alias_del = NULL, *fwds_add = NULL, *fwds_del = NULL;
struct change_flags change_flags;
size_t len = 0;
- list_init(&alias_add);
- list_init(&alias_del);
- list_init(&fwds_add);
- list_init(&fwds_del);
openlog(PNAME, LOG_PID, LOG_MAIL);
setvbuf(stdout, 0, _IONBF, 0);
@@ -299,25 +296,25 @@ int main(int argc, char *argv[])
case 's':
// Add this item to the user's aliases.
if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_add, optarg, len+1);
+ alias_add = g_list_append(alias_add, g_strdup(optarg));
break;
case 'S':
// Delete this item from the user's aliases.
if (optarg && (len = strlen(optarg)))
- list_nodeadd(&alias_del, optarg, len+1);
+ alias_del = g_list_append(alias_del, g_strdup(optarg));
break;
case 't':
// Add this item to the alias's forwards.
if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_add, optarg, len+1);
+ fwds_add = g_list_append(fwds_add, g_strdup(optarg));
break;
case 'T':
// Delete this item from the alias's forwards.
if (optarg && (len = strlen(optarg)))
- list_nodeadd(&fwds_del, optarg, len+1);
+ fwds_del = g_list_append(fwds_del, g_strdup(optarg));
break;
/* Common options */
@@ -394,7 +391,6 @@ int main(int argc, char *argv[])
GetDBParams(&_db_params);
/* open database connection */
- qprintf("Opening connection to database...\n");
if (db_connect() != 0) {
qerrorf
("Failed. Could not connect to database (check log)\n");
@@ -403,7 +399,6 @@ int main(int argc, char *argv[])
}
/* open authentication connection */
- qprintf("Opening connection to authentication...\n");
if (auth_connect() != 0) {
qerrorf
("Failed. Could not connect to authentication (check log)\n");
@@ -411,8 +406,7 @@ int main(int argc, char *argv[])
goto freeall;
}
- qprintf("Ok. Connected\n");
- configure_debug(TRACE_ERROR, 1, 0);
+ //configure_debug(TRACE_ERROR, 1, 0);
switch (mode) {
case 'c':
@@ -482,7 +476,7 @@ int main(int argc, char *argv[])
switch (mode) {
case 'a':
result = do_add(user, password, enctype, maxmail, clientid,
- &alias_add, &alias_del);
+ alias_add, alias_del);
break;
case 'd':
result = do_delete(useridnr, user);
@@ -501,7 +495,7 @@ int main(int argc, char *argv[])
if (change_flags.newmaxmail) {
result |= do_maxmail(useridnr, maxmail);
}
- result |= do_aliases(useridnr, &alias_add, &alias_del);
+ result |= do_aliases(useridnr, alias_add, alias_del);
break;
case 'e':
result = do_empty(useridnr);
@@ -510,7 +504,7 @@ int main(int argc, char *argv[])
result = do_show(userspec);
break;
case 'x':
- result = do_forwards(alias, clientid, &fwds_add, &fwds_del);
+ result = do_forwards(alias, clientid, fwds_add, fwds_del);
break;
default:
result = 1;
@@ -521,14 +515,22 @@ int main(int argc, char *argv[])
freeall:
/* Free the lists. */
- if (alias_del.start)
- list_freelist(&alias_del.start);
- if (alias_add.start)
- list_freelist(&alias_add.start);
- if (fwds_del.start)
- list_freelist(&alias_del.start);
- if (fwds_add.start)
- list_freelist(&alias_add.start);
+ if (alias_del) {
+ g_list_foreach(alias_del, (GFunc)g_free, NULL);
+ g_list_free(alias_del);
+ }
+ if (alias_add) {
+ g_list_foreach(alias_add, (GFunc)g_free, NULL);
+ g_list_free(alias_add);
+ }
+ if (fwds_del) {
+ g_list_foreach(fwds_del, (GFunc)g_free, NULL);
+ g_list_free(fwds_del);
+ }
+ if (fwds_add) {
+ g_list_foreach(fwds_add, (GFunc)g_free, NULL);
+ g_list_free(fwds_add);
+ }
db_disconnect();
auth_disconnect();
@@ -542,8 +544,8 @@ freeall:
int do_add(const char * const user,
const char * const password, const char * const enctype,
const u64_t maxmail, const u64_t clientid,
- struct list * const alias_add,
- struct list * const alias_del)
+ GList * alias_add,
+ GList * alias_del)
{
u64_t useridnr;
u64_t mailbox_idnr;
@@ -775,18 +777,17 @@ int do_maxmail(u64_t useridnr, u64_t maxmail)
}
int do_forwards(const char * const alias, const u64_t clientid,
- struct list * const fwds_add,
- struct list * const fwds_del)
+ GList * fwds_add,
+ GList * fwds_del)
{
int result = 0;
char *forward;
- struct element *tmp;
/* Delete aliases for the user. */
if (fwds_del) {
- tmp = list_getstart(fwds_del);
- while (tmp) {
- forward = (char *)tmp->data;
+ fwds_del = g_list_first(fwds_del);
+ while (fwds_del) {
+ forward = (char *)fwds_del->data;
qprintf("[%s]\n", forward);
@@ -795,15 +796,15 @@ int do_forwards(const char * const alias, const u64_t clientid,
forward);
result = -1;
}
- tmp = tmp->nextnode;
+ fwds_del = g_list_next(fwds_del);
}
}
/* Add aliases for the user. */
if (fwds_add) {
- tmp = list_getstart(fwds_add);
- while (tmp) {
- forward = (char *)tmp->data;
+ fwds_add = g_list_first(fwds_add);
+ while (fwds_add) {
+ forward = (char *)fwds_add->data;
qprintf("[%s]\n", forward);
if (auth_addalias_ext(alias, forward, clientid) < 0) {
@@ -811,7 +812,7 @@ int do_forwards(const char * const alias, const u64_t clientid,
alias);
result = -1;
}
- tmp = tmp->nextnode;
+ fwds_add = g_list_next(fwds_add);
}
}
@@ -840,53 +841,43 @@ int do_forwards(const char * const alias, const u64_t clientid,
}
int do_aliases(const u64_t useridnr,
- struct list * const alias_add,
- struct list * const alias_del)
+ GList * alias_add,
+ GList * alias_del)
{
int result = 0;
+ char *alias;
u64_t clientid;
auth_getclientid(useridnr, &clientid);
/* Delete aliases for the user. */
if (alias_del) {
- char *alias;
- struct element *tmp;
-
- tmp = list_getstart(alias_del);
- while (tmp) {
- alias = (char *)tmp->data;
+ alias_del = g_list_first(alias_del);
+ while (alias_del) {
+ alias = (char *)alias_del->data;
qprintf("[%s]\n", alias);
- if (auth_removealias(useridnr, alias) <
- 0) {
- qerrorf("Error: could not remove alias [%s] \n",
- alias);
+ if (auth_removealias(useridnr, alias) < 0) {
+ qerrorf("Error: could not remove alias [%s] \n", alias);
result = -1;
}
- tmp = tmp->nextnode;
+ alias_del = g_list_next(alias_del);
}
}
/* Add aliases for the user. */
if (alias_add) {
- char *alias;
- struct element *tmp;
-
-
- tmp = list_getstart(alias_add);
- while (tmp) {
- alias = (char *)tmp->data;
+ alias_add = g_list_first(alias_add);
+ while (alias_add) {
+ alias = (char *)alias_add->data;
qprintf("[%s]\n", alias);
- if (auth_addalias
- (useridnr, alias, clientid) < 0) {
- qerrorf("Error: could not add alias [%s]\n",
- alias);
+ if (auth_addalias (useridnr, alias, clientid) < 0) {
+ qerrorf("Error: could not add alias [%s]\n", alias);
result = -1;
}
- tmp = tmp->nextnode;
+ alias_add = g_list_next(alias_add);
}
}
@@ -899,11 +890,11 @@ int do_aliases(const u64_t useridnr,
int do_delete(const u64_t useridnr, const char * const name)
{
int result;
- struct list aliases;
+ GList *aliases = NULL;
qprintf("Deleting aliases for user [%s]...\n", name);
- auth_get_user_aliases(useridnr, &aliases);
- do_aliases(useridnr, NULL, &aliases);
+ aliases = auth_get_user_aliases(useridnr);
+ do_aliases(useridnr, NULL, aliases);
qprintf("Deleting user [%s]...\n", name);
result = auth_delete_user(name);
@@ -921,19 +912,21 @@ int do_show(const char * const name)
{
u64_t useridnr, cid, quotum, quotumused;
GList *users = NULL;
- struct list userlist;
- struct element *tmp;
- char *deliver_to;
+ GList *userlist = NULL;
+ char *username;
+ int result;
+ struct list uids;
+ struct list fwds;
+ GList *userids = NULL;
+ GList *forwards = NULL;
if (!name) {
/* show all users */
- qprintf("Existing users:\n");
-
users = auth_get_known_users();
if (g_list_length(users) > 0) {
users = g_list_first(users);
while (users) {
- qprintf("[%s]\n", (char *) users->data);
+ do_show(users->data);
users = g_list_next(users);
}
g_list_foreach(users,(GFunc)g_free,NULL);
@@ -941,74 +934,79 @@ int do_show(const char * const name)
g_list_free(users);
} else {
- qprintf("Info for user [%s]", name);
-
if (auth_user_exists(name, &useridnr) == -1) {
- qerrorf("Error: cannot verify existence of user [%s].\n",
- name);
+ qerrorf("Error while verifying user [%s].\n", name);
return -1;
}
if (useridnr == 0) {
- /* 'name' is not a user, try it as an alias */
- qprintf
- ("..is not a user, trying as an alias");
-
- deliver_to = auth_get_deliver_from_alias(name);
-
- if (!deliver_to) {
- qerrorf("Error: cannot verify existence of alias [%s].\n",
- name);
+ /* not a user, search aliases */
+ list_init(&fwds);
+ list_init(&uids);
+ result = auth_check_user_ext(name,&uids,&fwds,-1);
+
+ if (!result) {
+ qerrorf("Nothing found searching for [%s].\n", name);
return -1;
}
-
- if (deliver_to[0] == '\0') {
- qprintf("..is not an alias.\n");
- return -1;
+
+ if (list_getstart(&uids))
+ userids = g_list_copy_list(userids,list_getstart(&uids));
+ if (list_getstart(&fwds))
+ forwards = g_list_copy_list(forwards,list_getstart(&fwds));
+
+ forwards = g_list_first(forwards);
+ if (forwards) {
+ while(forwards) {
+ qerrorf("forward [%s] to [%s]\n", name, (char *)forwards->data);
+ forwards = g_list_next(forwards);
+ }
+ g_list_foreach(forwards,(GFunc)g_free, NULL);
+ g_list_free(forwards);
}
-
- useridnr = strtoul(deliver_to, NULL, 10);
- if (useridnr == 0) {
- qprintf
- ("\n[%s] is an alias for [%s]\n", name,
- deliver_to);
- dm_free(deliver_to);
- return 0;
+
+ userids = g_list_first(userids);
+ if (userids) {
+ while (userids) {
+ username = auth_get_userid(*(u64_t *)userids->data);
+ qerrorf("deliver [%s] to [%s]\n-------\n", name, username);
+ do_show(username);
+ userids = g_list_next(userids);
+ }
+ g_list_free(userids);
}
-
- dm_free(deliver_to);
- qprintf("\nFound user for alias [%s]:\n\n",
- name);
+ return 0;
}
auth_getclientid(useridnr, &cid);
auth_getmaxmailsize(useridnr, &quotum);
db_get_quotum_used(useridnr, &quotumused);
- qprintf("\n");
- qprintf("User ID : %llu\n", useridnr);
- qprintf("Username : %s\n",
- auth_get_userid(useridnr));
- qprintf("Client ID : %llu\n", cid);
- qprintf("Max. mailboxsize: %.02f MB\n",
- (double) quotum / (1024.0 * 1024.0));
- qprintf("Quotum used : %.02f MB (%.01f%%)\n",
- (double) quotumused / (1024.0 * 1024.0),
- (100.0 * quotumused) / (double) quotum);
- qprintf("\n");
-
- qprintf("Aliases:\n");
- auth_get_user_aliases(useridnr, &userlist);
-
- tmp = list_getstart(&userlist);
- while (tmp) {
- qprintf("%s\n", (char *) tmp->data);
- tmp = tmp->nextnode;
+ GList *out = NULL;
+ GString *s = g_string_new("");
+ out = g_list_append_printf(out,"%s", auth_get_userid(useridnr));
+ out = g_list_append_printf(out,"x");
+ out = g_list_append_printf(out,"%llu", useridnr);
+ out = g_list_append_printf(out,"%llu", cid);
+ out = g_list_append_printf(out,"%.02f",
+ (double) quotum / (1024.0 * 1024.0));
+ out = g_list_append_printf(out,"%.02f",
+ (double) quotumused / (1024.0 * 1024.0));
+ out = g_list_append_printf(out,"%.01f%%",
+ (100.0 * quotumused) / ( quotum ? (double) quotum: 1));
+
+ userlist = auth_get_user_aliases(useridnr);
+
+ if (g_list_length(userlist)) {
+ userlist = g_list_first(userlist);
+ s = g_list_join(userlist,",");
+ g_list_append_printf(out,"%s", s->str);
+ g_list_foreach(userlist,(GFunc)g_free, NULL);
}
-
- qprintf("\n");
- if (userlist.start)
- list_freelist(&userlist.start);
+ g_list_free(userlist);
+ s = g_list_join(out,":");
+ qprintf("%s\n", s->str);
+ g_string_free(s,TRUE);
}
return 0;