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