@@ -61,6 +61,22 @@ static char *canon_hostname;
61
61
static char * ip_address ;
62
62
static char * tcp_port ;
63
63
64
+ static int hostname_lookup_done ;
65
+
66
+ static void lookup_hostname (void );
67
+
68
+ static const char * get_canon_hostname (void )
69
+ {
70
+ lookup_hostname ();
71
+ return canon_hostname ;
72
+ }
73
+
74
+ static const char * get_ip_address (void )
75
+ {
76
+ lookup_hostname ();
77
+ return ip_address ;
78
+ }
79
+
64
80
static void logreport (int priority , const char * err , va_list params )
65
81
{
66
82
if (log_syslog ) {
@@ -106,6 +122,46 @@ static void NORETURN daemon_die(const char *err, va_list params)
106
122
exit (1 );
107
123
}
108
124
125
+ static void strbuf_addstr_or_null (struct strbuf * sb , const char * s )
126
+ {
127
+ if (s )
128
+ strbuf_addstr (sb , s );
129
+ }
130
+
131
+ struct expand_path_context {
132
+ const char * directory ;
133
+ };
134
+
135
+ static size_t expand_path (struct strbuf * sb , const char * placeholder , void * ctx )
136
+ {
137
+ struct expand_path_context * context = ctx ;
138
+
139
+ switch (placeholder [0 ]) {
140
+ case 'H' :
141
+ strbuf_addstr_or_null (sb , hostname );
142
+ return 1 ;
143
+ case 'C' :
144
+ if (placeholder [1 ] == 'H' ) {
145
+ strbuf_addstr_or_null (sb , get_canon_hostname ());
146
+ return 2 ;
147
+ }
148
+ break ;
149
+ case 'I' :
150
+ if (placeholder [1 ] == 'P' ) {
151
+ strbuf_addstr_or_null (sb , get_ip_address ());
152
+ return 2 ;
153
+ }
154
+ break ;
155
+ case 'P' :
156
+ strbuf_addstr_or_null (sb , tcp_port );
157
+ return 1 ;
158
+ case 'D' :
159
+ strbuf_addstr (sb , context -> directory );
160
+ return 1 ;
161
+ }
162
+ return 0 ;
163
+ }
164
+
109
165
static const char * path_ok (const char * directory )
110
166
{
111
167
static char rpath [PATH_MAX ];
@@ -144,22 +200,18 @@ static const char *path_ok(const char *directory)
144
200
}
145
201
else if (interpolated_path && saw_extended_args ) {
146
202
struct strbuf expanded_path = STRBUF_INIT ;
147
- struct strbuf_expand_dict_entry dict [6 ];
148
-
149
- dict [0 ].placeholder = "H" ; dict [0 ].value = hostname ;
150
- dict [1 ].placeholder = "CH" ; dict [1 ].value = canon_hostname ;
151
- dict [2 ].placeholder = "IP" ; dict [2 ].value = ip_address ;
152
- dict [3 ].placeholder = "P" ; dict [3 ].value = tcp_port ;
153
- dict [4 ].placeholder = "D" ; dict [4 ].value = directory ;
154
- dict [5 ].placeholder = NULL ; dict [5 ].value = NULL ;
203
+ struct expand_path_context context ;
204
+
205
+ context .directory = directory ;
206
+
155
207
if (* dir != '/' ) {
156
208
/* Allow only absolute */
157
209
logerror ("'%s': Non-absolute path denied (interpolated-path active)" , dir );
158
210
return NULL ;
159
211
}
160
212
161
213
strbuf_expand (& expanded_path , interpolated_path ,
162
- strbuf_expand_dict_cb , & dict );
214
+ expand_path , & context );
163
215
strlcpy (interp_path , expanded_path .buf , PATH_MAX );
164
216
strbuf_release (& expanded_path );
165
217
loginfo ("Interpolated dir '%s'" , interp_path );
@@ -254,8 +306,8 @@ static int run_access_hook(struct daemon_service *service, const char *dir, cons
254
306
* arg ++ = service -> name ;
255
307
* arg ++ = path ;
256
308
* arg ++ = STRARG (hostname );
257
- * arg ++ = STRARG (canon_hostname );
258
- * arg ++ = STRARG (ip_address );
309
+ * arg ++ = STRARG (get_canon_hostname () );
310
+ * arg ++ = STRARG (get_ip_address () );
259
311
* arg ++ = STRARG (tcp_port );
260
312
* arg = NULL ;
261
313
#undef STRARG
@@ -509,6 +561,7 @@ static void parse_host_arg(char *extra_args, int buflen)
509
561
}
510
562
free (hostname );
511
563
hostname = xstrdup_tolower (host );
564
+ hostname_lookup_done = 0 ;
512
565
}
513
566
514
567
/* On to the next one */
@@ -517,11 +570,14 @@ static void parse_host_arg(char *extra_args, int buflen)
517
570
if (extra_args < end && * extra_args )
518
571
die ("Invalid request" );
519
572
}
573
+ }
520
574
521
- /*
522
- * Locate canonical hostname and its IP address.
523
- */
524
- if (hostname ) {
575
+ /*
576
+ * Locate canonical hostname and its IP address.
577
+ */
578
+ static void lookup_hostname (void )
579
+ {
580
+ if (!hostname_lookup_done && hostname ) {
525
581
#ifndef NO_IPV6
526
582
struct addrinfo hints ;
527
583
struct addrinfo * ai ;
@@ -569,6 +625,7 @@ static void parse_host_arg(char *extra_args, int buflen)
569
625
ip_address = xstrdup (addrbuf );
570
626
}
571
627
#endif
628
+ hostname_lookup_done = 1 ;
572
629
}
573
630
}
574
631
0 commit comments