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