1/*	$NetBSD$	*/
2
3/*++
4/* NAME
5/*	local_expand 3
6/* SUMMARY
7/*	set up attribute list for $name expansion
8/* SYNOPSIS
9/*	#include "local.h"
10/*
11/*	int	local_expand(result, pattern, state, usr_attr, filter)
12/*	VSTRING	*result;
13/*	const	char *pattern;
14/*	LOCAL_STATE state;
15/*	USER_ATTR usr_attr;
16/*	const char *filter;
17/* DESCRIPTION
18/*	local_expand() performs conditional and unconditional $name
19/*	expansion based on message delivery attributes.
20/*	The result is the bitwise OR or zero or more of the following:
21/* .IP LOCAL_EXP_EXTENSION_MATCHED
22/*	The result of expansion contains the $extension attribute.
23/* .IP MAC_PARSE_XXX
24/*	See mac_parse(3).
25/* .PP
26/*	Attributes:
27/* .IP client_address
28/*	The client network address.
29/* .IP client_helo
30/*	The client HELO command parameter.
31/* .IP client_hostname
32/*	The client hostname.
33/* .IP client_protocol
34/*	The client protocol.
35/* .IP domain
36/*	The recipient address domain.
37/* .IP extension
38/*	The recipient address extension.
39/* .IP home
40/*	The recipient home directory.
41/* .IP local
42/*	The entire recipient address localpart.
43/* .IP recipient
44/*	The entire recipient address.
45/* .IP recipient_delimiter
46/*	The recipient delimiter.
47/* .IP shell
48/*	The recipient shell program.
49/* .IP sasl_method
50/*	The SASL authentication method.
51/* .IP sasl_sender
52/*	The SASL MAIL FROM address.
53/* .IP sasl_username
54/*	The SASL login name.
55/* .IP user
56/*	The recipient user name.
57/* .PP
58/*	Arguments:
59/* .IP result
60/*	Storage for the result of expansion. The buffer is truncated
61/*	upon entry.
62/* .IP pattern
63/*	The string with unconditional and conditional macro expansions.
64/* .IP state
65/*	Message delivery attributes (sender, recipient etc.).
66/*	Attributes describing alias, include or forward expansion.
67/*	A table with the results from expanding aliases or lists.
68/*	A table with delivered-to: addresses taken from the message.
69/* .IP usr_attr
70/*	Attributes describing user rights and environment.
71/* .IP filter
72/*	A null pointer, or a string of allowed characters in $name
73/*	expansions. Illegal characters are replaced by underscores.
74/* DIAGNOSTICS
75/*	Fatal errors: out of memory.
76/* SEE ALSO
77/*	mac_expand(3) macro expansion
78/* LICENSE
79/* .ad
80/* .fi
81/*	The Secure Mailer license must be distributed with this software.
82/* AUTHOR(S)
83/*	Wietse Venema
84/*	IBM T.J. Watson Research
85/*	P.O. Box 704
86/*	Yorktown Heights, NY 10598, USA
87/*--*/
88
89/* System library. */
90
91#include <sys_defs.h>
92#include <string.h>
93
94/* Utility library. */
95
96#include <vstring.h>
97#include <mac_expand.h>
98
99/* Global library */
100
101#include <mail_params.h>
102
103/* Application-specific. */
104
105#include "local.h"
106
107typedef struct {
108    LOCAL_STATE *state;
109    USER_ATTR *usr_attr;
110    int     status;
111} LOCAL_EXP;
112
113/* local_expand_lookup - mac_expand() lookup routine */
114
115static const char *local_expand_lookup(const char *name, int mode, char *ptr)
116{
117    LOCAL_EXP *local = (LOCAL_EXP *) ptr;
118
119#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
120
121    if (STREQ(name, "user")) {
122	return (local->state->msg_attr.user);
123    } else if (STREQ(name, "home")) {
124	return (local->usr_attr->home);
125    } else if (STREQ(name, "shell")) {
126	return (local->usr_attr->shell);
127    } else if (STREQ(name, "domain")) {
128	return (local->state->msg_attr.domain);
129    } else if (STREQ(name, "local")) {
130	return (local->state->msg_attr.local);
131    } else if (STREQ(name, "mailbox")) {
132	return (local->state->msg_attr.local);
133    } else if (STREQ(name, "recipient")) {
134	return (local->state->msg_attr.rcpt.address);
135    } else if (STREQ(name, "extension")) {
136	if (mode == MAC_EXP_MODE_USE)
137	    local->status |= LOCAL_EXP_EXTENSION_MATCHED;
138	return (local->state->msg_attr.extension);
139    } else if (STREQ(name, "recipient_delimiter")) {
140	return (*var_rcpt_delim ? var_rcpt_delim : 0);
141#if 0
142    } else if (STREQ(name, "client_hostname")) {
143	return (local->state->msg_attr.request->client_name);
144    } else if (STREQ(name, "client_address")) {
145	return (local->state->msg_attr.request->client_addr);
146    } else if (STREQ(name, "client_protocol")) {
147	return (local->state->msg_attr.request->client_proto);
148    } else if (STREQ(name, "client_helo")) {
149	return (local->state->msg_attr.request->client_helo);
150    } else if (STREQ(name, "sasl_method")) {
151	return (local->state->msg_attr.request->sasl_method);
152    } else if (STREQ(name, "sasl_sender")) {
153	return (local->state->msg_attr.request->sasl_sender);
154    } else if (STREQ(name, "sasl_username")) {
155	return (local->state->msg_attr.request->sasl_username);
156#endif
157    } else {
158	return (0);
159    }
160}
161
162/* local_expand - expand message delivery attributes */
163
164int     local_expand(VSTRING *result, const char *pattern,
165	        LOCAL_STATE *state, USER_ATTR *usr_attr, const char *filter)
166{
167    LOCAL_EXP local;
168    int     expand_status;
169
170    local.state = state;
171    local.usr_attr = usr_attr;
172    local.status = 0;
173    expand_status = mac_expand(result, pattern, MAC_EXP_FLAG_NONE,
174			       filter, local_expand_lookup, (char *) &local);
175    return (local.status | expand_status);
176}
177