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 
105 typedef 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 
local_expand_lookup(const char * name,int mode,void * ptr)113 static const char *local_expand_lookup(const char *name, int mode, void *ptr)
114 {
115     LOCAL_EXP *local = (LOCAL_EXP *) ptr;
116     static char rcpt_delim[2];
117 
118 #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
119 
120     if (STREQ(name, "user")) {
121 	return (local->state->msg_attr.user);
122     } else if (STREQ(name, "home")) {
123 	return (local->usr_attr->home);
124     } else if (STREQ(name, "shell")) {
125 	return (local->usr_attr->shell);
126     } else if (STREQ(name, "domain")) {
127 	return (local->state->msg_attr.domain);
128     } else if (STREQ(name, "local")) {
129 	return (local->state->msg_attr.local);
130     } else if (STREQ(name, "mailbox")) {
131 	return (local->state->msg_attr.local);
132     } else if (STREQ(name, "recipient")) {
133 	return (local->state->msg_attr.rcpt.address);
134     } else if (STREQ(name, "extension")) {
135 	if (mode == MAC_EXP_MODE_USE)
136 	    local->status |= LOCAL_EXP_EXTENSION_MATCHED;
137 	return (local->state->msg_attr.extension);
138     } else if (STREQ(name, "recipient_delimiter")) {
139 	rcpt_delim[0] =
140 	    local->state->msg_attr.local[strlen(local->state->msg_attr.user)];
141 	rcpt_delim[1] = 0;
142 	return (rcpt_delim[0] ? rcpt_delim : 0);
143 #if 0
144     } else if (STREQ(name, "client_hostname")) {
145 	return (local->state->msg_attr.request->client_name);
146     } else if (STREQ(name, "client_address")) {
147 	return (local->state->msg_attr.request->client_addr);
148     } else if (STREQ(name, "client_protocol")) {
149 	return (local->state->msg_attr.request->client_proto);
150     } else if (STREQ(name, "client_helo")) {
151 	return (local->state->msg_attr.request->client_helo);
152     } else if (STREQ(name, "sasl_method")) {
153 	return (local->state->msg_attr.request->sasl_method);
154     } else if (STREQ(name, "sasl_sender")) {
155 	return (local->state->msg_attr.request->sasl_sender);
156     } else if (STREQ(name, "sasl_username")) {
157 	return (local->state->msg_attr.request->sasl_username);
158 #endif
159     } else {
160 	return (0);
161     }
162 }
163 
164 /* local_expand - expand message delivery attributes */
165 
local_expand(VSTRING * result,const char * pattern,LOCAL_STATE * state,USER_ATTR * usr_attr,const char * filter)166 int     local_expand(VSTRING *result, const char *pattern,
167 	        LOCAL_STATE *state, USER_ATTR *usr_attr, const char *filter)
168 {
169     LOCAL_EXP local;
170     int     expand_status;
171 
172     local.state = state;
173     local.usr_attr = usr_attr;
174     local.status = 0;
175     expand_status = mac_expand(result, pattern, MAC_EXP_FLAG_NONE,
176 			       filter, local_expand_lookup, (void *) &local);
177     return (local.status | expand_status);
178 }
179