1
+ #include <config.h>
2
+
1
3
#include <dirent.h>
2
4
#include <errno.h>
5
+ #include <fcntl.h>
3
6
#include <stdio.h>
4
7
#include <stdlib.h>
5
8
#include <string.h>
13
16
#include "run_part.h"
14
17
#include "shadowlog_internal.h"
15
18
16
- int run_part (char * script_path , const char * name , const char * action )
19
+ #ifdef HAVE_EXECVEAT
20
+ int run_part (int script_fd , const char * script_name , const char * name , const char * action )
21
+ #else
22
+ int run_part (const char * script_path , const char * script_name , const char * name , const char * action )
23
+ #endif /* HAVE_EXECVEAT */
17
24
{
18
25
int pid ;
19
26
int wait_status ;
20
27
int pid_status ;
21
- char * args [] = { script_path , NULL };
28
+ char * args [] = { ( char * ) script_name , NULL };
22
29
23
30
pid = fork ();
24
31
if (pid == -1 ) {
@@ -28,7 +35,11 @@ int run_part (char *script_path, const char *name, const char *action)
28
35
if (pid == 0 ) {
29
36
setenv ("ACTION" ,action ,1 );
30
37
setenv ("SUBJECT" ,name ,1 );
31
- execv (script_path ,args );
38
+ #ifdef HAVE_EXECVEAT
39
+ execveat (script_fd , "" , args , environ , AT_EMPTY_PATH );
40
+ #else
41
+ execv (script_path , args );
42
+ #endif /* HAVE_EXECVEAT */
32
43
perror ("execv" );
33
44
exit (1 );
34
45
}
@@ -49,16 +60,38 @@ int run_parts (const char *directory, const char *name, const char *action)
49
60
int n ;
50
61
int execute_result = 0 ;
51
62
63
+ #ifdef HAVE_EXECVEAT
64
+ int dfd = open (directory , O_PATH | O_DIRECTORY | O_CLOEXEC );
65
+ if (dfd == -1 ) {
66
+ perror ("open" );
67
+ return (1 );
68
+ }
69
+ #endif /* HAVE_EXECVEAT */
70
+
52
71
scanlist = scandir (directory , & namelist , 0 , alphasort );
53
72
if (scanlist <=0 ) {
73
+ #ifdef HAVE_EXECVEAT
74
+ (void ) close (dfd );
75
+ #endif /* HAVE_EXECVEAT */
54
76
return (0 );
55
77
}
56
78
57
79
for (n = 0 ; n < scanlist ; n ++ ) {
58
- int path_length ;
59
80
struct stat sb ;
60
81
61
- path_length = strlen (directory ) + strlen (namelist [n ]-> d_name ) + 2 ;
82
+ #ifdef HAVE_EXECVEAT
83
+ int fd = openat (dfd , namelist [n ]-> d_name , O_PATH | O_CLOEXEC );
84
+ if (fd == -1 ) {
85
+ perror ("open" );
86
+ for (; n < scanlist ; n ++ ) {
87
+ free (namelist [n ]);
88
+ }
89
+ free (namelist );
90
+ (void ) close (dfd );
91
+ return (1 );
92
+ }
93
+ #else
94
+ int path_length = strlen (directory ) + strlen (namelist [n ]-> d_name ) + 2 ;
62
95
char * s = MALLOCARRAY (path_length , char );
63
96
if (!s ) {
64
97
fprintf (shadow_logfd , "could not allocate memory\n" );
@@ -69,11 +102,20 @@ int run_parts (const char *directory, const char *name, const char *action)
69
102
return (1 );
70
103
}
71
104
snprintf (s , path_length , "%s/%s" , directory , namelist [n ]-> d_name );
105
+ #endif /* HAVE_EXECVEAT */
72
106
73
- execute_result = 0 ;
107
+ #ifdef HAVE_EXECVEAT
108
+ if (fstat (fd , & sb ) == -1 ) {
109
+ #else
74
110
if (stat (s , & sb ) == -1 ) {
111
+ #endif /* HAVE_EXECVEAT */
75
112
perror ("stat" );
113
+ #ifdef HAVE_EXECVEAT
114
+ (void ) close (fd );
115
+ (void ) close (dfd );
116
+ #else
76
117
free (s );
118
+ #endif /* HAVE_EXECVEAT */
77
119
for (; n < scanlist ; n ++ ) {
78
120
free (namelist [n ]);
79
121
}
@@ -82,7 +124,11 @@ int run_parts (const char *directory, const char *name, const char *action)
82
124
}
83
125
84
126
if (!S_ISREG (sb .st_mode )) {
85
- free (s );
127
+ #ifdef HAVE_EXECVEAT
128
+ (void ) close (fd );
129
+ #else
130
+ free (s );
131
+ #endif /* HAVE_EXECVEAT */
86
132
free (namelist [n ]);
87
133
continue ;
88
134
}
@@ -92,14 +138,22 @@ int run_parts (const char *directory, const char *name, const char *action)
92
138
(sb .st_mode & 0002 )) {
93
139
fprintf (shadow_logfd , "skipping %s due to insecure ownership/permission\n" ,
94
140
namelist [n ]-> d_name );
95
- free (s );
141
+ #ifdef HAVE_EXECVEAT
142
+ (void ) close (fd );
143
+ #else
144
+ free (s );
145
+ #endif /* HAVE_EXECVEAT */
96
146
free (namelist [n ]);
97
147
continue ;
98
148
}
99
149
100
- execute_result = run_part (s , name , action );
101
-
150
+ #ifdef HAVE_EXECVEAT
151
+ execute_result = run_part (fd , namelist [n ]-> d_name , name , action );
152
+ (void ) close (fd );
153
+ #else
154
+ execute_result = run_part (s , namelist [n ]-> d_name , name , action );
102
155
free (s );
156
+ #endif /* HAVE_EXECVEAT */
103
157
104
158
if (execute_result != 0 ) {
105
159
fprintf (shadow_logfd ,
@@ -115,6 +169,10 @@ int run_parts (const char *directory, const char *name, const char *action)
115
169
}
116
170
free (namelist );
117
171
172
+ #ifdef HAVE_EXECVEAT
173
+ (void ) close (dfd );
174
+ #endif /* HAVE_EXECVEAT */
175
+
118
176
return (execute_result );
119
177
}
120
178
0 commit comments