/* to see if this should be searched */
} Base;
-/*
- * We should limit the search to objectclass=mailRecipient or
- * objectclass=mailGroup.
- */
-
-/*
-Base base[] = {
- {"dc=StlInter, dc=Net",
- 0, 0xff,
- {"mail=%s", "mailAlternateAddress=%s", NULL}},
- {NULL}
-};
-*/
-
Base **base = NULL;
char *sendmailargs[] = { MAIL500_SENDMAIL, "-oMrLDAP", "-odi", "-oi", "-f", NULL, NULL };
#define AS_KIND_MODERATOR 7
#define AS_KIND_ROUTE_TO_ADDR 8 /* Rewrite recipient address as */
#define AS_KIND_OWN_ADDR 9 /* RFC822 name of this entry */
+#define AS_KIND_DELIVERY_TYPE 10 /* How to deliver mail to this entry */
AttrSemantics **attr_semantics = NULL;
int current_priority = 0;
char **groupclasses = NULL;
char **def_attr = NULL;
-char **mydomains = NULL; /* FQDNs not to route elsewhere */
+char **myhosts = NULL; /* FQDNs not to route elsewhere */
+char **mydomains = NULL; /* If an RFC822 address points to one
+ of these domains, search it in the
+ directory instead of returning it
+ to hte MTA */
static void load_config( char *filespec );
static void split_address( char *address, char **localpart, char **domainpart);
while ( (i = getopt( argc, argv, "d:C:f:h:l:m:v:" )) != EOF ) {
switch( i ) {
case 'd': /* turn on debugging */
- debug = atoi( optarg );
+ debug |= atoi( optarg );
break;
case 'C': /* path to configuration file */
as->as_syntax = AS_SYNTAX_DN;
} else if ( !strcasecmp( p, "url" ) ) {
as->as_syntax = AS_SYNTAX_URL;
- } else if ( !strncasecmp( p, "search-with-filter=", 19 ) ) {
+ } else if ( !strcasecmp( p, "search-with-filter" ) ) {
as->as_syntax = AS_SYNTAX_BOOL_FILTER;
+ } else if ( !strncasecmp( p, "param=", 6 ) ) {
q = strchr( p, '=' );
if ( q ) {
p = q + 1;
as->as_param = strdup( p );
p = q;
}
- } else {
- syslog( LOG_ALERT,
- "Missing filter in %s", s );
- exit( EX_TEMPFAIL );
}
} else if ( !strcasecmp( p, "host" ) ) {
as->as_kind = AS_SYNTAX_HOST;
as->as_kind = AS_KIND_REQUEST;
} else if ( !strcasecmp( p, "owner" ) ) {
as->as_kind = AS_KIND_OWNER;
+ } else if ( !strcasecmp( p, "delivery-type" ) ) {
+ as->as_kind = AS_KIND_DELIVERY_TYPE;
} else {
syslog( LOG_ALERT,
"Unknown semantics word %s", p );
} else if ( !strncmp(line, "domain", p-line) ) {
p += strspn(p, " \t");
add_single_to( &mydomains, p );
+ } else if ( !strncmp(line, "host", p-line) ) {
+ p += strspn(p, " \t");
+ add_single_to( &myhosts, p );
} else {
syslog( LOG_ALERT,
"Unparseable config definition at line %d",
* We should probably take MX records into account to cover all bases,
* but really, routing belongs in the MTA.
*/
+static int
+is_my_host(
+ char * host
+)
+{
+ char **d;
+
+ if ( d == NULL )
+ return 0;
+ for ( d = myhosts; *d; d++ ) {
+ if ( !strcasecmp(*d,host) ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int
is_my_domain(
- char * domain
+ char * address
)
{
char **d;
+ char *p;
if ( d == NULL )
return 0;
+ p = strchr( address, '@' );
+ if ( p == NULL)
+ return 0;
for ( d = mydomains; *d; d++ ) {
- if ( !strcasecmp(*d,domain) ) {
+ if ( !strcasecmp(*d,p+1) ) {
return 1;
}
}
return 0;
}
+static void
+do_addresses(
+ char **addresses,
+ char ***to,
+ int *nto,
+ Group ***togroups,
+ int *ngroups,
+ Error **err,
+ int *nerr,
+ int type
+)
+{
+ int i, j;
+ int n;
+
+ /*
+ * Well, this is tricky, every address in my_addresses will be
+ * removed from the list while we shift the other values down
+ * and we do it in a single scan of the address list and
+ * without using additional memory. We are going to be
+ * modifying the value list in a way that the later
+ * ldap_value_free works.
+ */
+ j = 0;
+ for ( i = 0; addresses[i]; i++ ) {
+ if ( is_my_domain(addresses[i]) ) {
+ do_address( addresses[i], to, nto, togroups, ngroups,
+ err, nerr, type );
+ ldap_memfree( addresses[i] );
+ } else {
+ if ( j < i ) {
+ addresses[j] = addresses[i];
+ }
+ j++;
+ }
+ }
+ addresses[j] = NULL;
+ if ( addresses[0] ) {
+ add_to( to, nto, addresses );
+ }
+}
+
/*
* The entry engine processes an entry. Normally, each entry will resolve
* to one or more values that will be added to the 'to' argument. This
int needs_mta_routing = 0;
char **own_addresses = NULL;
int own_addresses_total = 0;
+ char **delivery_types = NULL;
+ int delivery_types_total = 0;
char *nvals[2];
for ( i=0; attr_semantics[i] != NULL; i++ ) {
break;
switch ( as->as_syntax ) {
case AS_SYNTAX_RFC822:
- add_to( current_to, current_nto, vals );
+ do_addresses( vals, current_to, current_nto,
+ togroups, ngroups, err, nerr,
+ USER );
resolved = 1;
break;
case AS_SYNTAX_RFC822_EXT:
* We used to send a copy to the vacation host
* if onVacation to uid@vacationhost
*/
- add_to( current_to, current_nto, vals );
- resolved = 1;
+ if ( as->as_param ) {
+ for ( j=0; j<delivery_types_total; j++ ) {
+ if ( !strcasecmp( as->as_param, delivery_types[j] ) ) {
+ add_to( current_to, current_nto, vals );
+ resolved = 1;
+ break;
+ }
+ }
+ } else {
+ add_to( current_to, current_nto, vals );
+ resolved = 1;
+ }
break;
case AS_SYNTAX_DN:
break;
case AS_KIND_ROUTE_TO_HOST:
- if ( !is_my_domain( vals[0] ) ) {
+ if ( !is_my_host( vals[0] ) ) {
cur_priority = as->as_priority;
if ( as->as_syntax == AS_SYNTAX_PRESENT ) {
needs_mta_routing = 1;
cur_priority = as->as_priority;
break;
+ case AS_KIND_DELIVERY_TYPE:
+ add_to( &delivery_types, &delivery_types_total, vals );
+ cur_priority = as->as_priority;
+ break;
+
default:
syslog( LOG_ALERT,
"Invalid kind %d", as->as_kind );
if ( own_addresses ) {
ldap_value_free( own_addresses );
}
+ if ( delivery_types ) {
+ ldap_value_free( delivery_types );
+ }
return( resolved );
}
int type
)
{
- struct timeval timeout;
char *localpart = NULL, *domainpart = NULL;
char *synthname = NULL;
int resolved;
if ( synthname[i] == '.' || synthname[i] == '_' )
synthname[i] = ' ';
}
- timeout.tv_sec = MAIL500_TIMEOUT;
- timeout.tv_usec = 0;
substs[0].sub_char = 'm';
substs[0].sub_value = name;
substs[1].sub_char = 'h';