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