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