Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run_parts updates #707

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ AC_CHECK_HEADERS(crypt.h utmp.h \
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])

AC_CHECK_FUNCS(arc4random_buf futimes \
AC_CHECK_FUNCS(arc4random_buf execveat futimes \
getentropy getrandom getspnam getusershell \
initgroups lckpwdf lutimes mempcpy \
setgroups updwtmp updwtmpx innetgr \
Expand Down
90 changes: 81 additions & 9 deletions lib/run_part.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <config.h>

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -13,12 +16,16 @@
#include "run_part.h"
#include "shadowlog_internal.h"

int run_part (char *script_path, const char *name, const char *action)
#ifdef HAVE_EXECVEAT
int run_part (int script_fd, const char *script_name, const char *name, const char *action)
#else
int run_part (const char *script_path, const char *script_name, const char *name, const char *action)
#endif /* HAVE_EXECVEAT */
{
int pid;
int wait_status;
int pid_status;
char *args[] = { script_path, NULL };
char *args[] = { (char *) script_name, NULL };

pid=fork();
if (pid==-1) {
Expand All @@ -28,7 +35,11 @@
if (pid==0) {
setenv ("ACTION",action,1);
setenv ("SUBJECT",name,1);
execv (script_path,args);
#ifdef HAVE_EXECVEAT
execveat (script_fd, "", args, environ, AT_EMPTY_PATH);
#else
execv (script_path, args);
#endif /* HAVE_EXECVEAT */
perror ("execv");
exit(1);
}
Expand All @@ -49,43 +60,100 @@
int n;
int execute_result = 0;

#ifdef HAVE_EXECVEAT
int dfd = open (directory, O_PATH | O_DIRECTORY | O_CLOEXEC);
if (dfd == -1) {
perror ("open");
return (1);
}
#endif /* HAVE_EXECVEAT */

scanlist = scandir (directory, &namelist, 0, alphasort);
if (scanlist<=0) {
#ifdef HAVE_EXECVEAT
(void) close (dfd);
#endif /* HAVE_EXECVEAT */
return (0);
}

for (n=0; n<scanlist; n++) {
int path_length;
struct stat sb;

path_length=strlen(directory) + strlen(namelist[n]->d_name) + 2;
#ifdef HAVE_EXECVEAT
int fd = openat (dfd, namelist[n]->d_name, O_PATH | O_CLOEXEC);
if (fd == -1) {
perror ("open");
for (; n<scanlist; n++) {

Check notice

Code scanning / CodeQL

For loop variable changed in body Note

Loop counters should not be modified in the body of the
loop
.
free (namelist[n]);
}
free (namelist);
(void) close (dfd);
return (1);
}
#else
int path_length=strlen(directory) + strlen(namelist[n]->d_name) + 2;
char *s = MALLOCARRAY(path_length, char);
if (!s) {
printf ("could not allocate memory\n");
fprintf (shadow_logfd, "could not allocate memory\n");
for (; n<scanlist; n++) {
free (namelist[n]);
}
free (namelist);
return (1);
}
snprintf (s, path_length, "%s/%s", directory, namelist[n]->d_name);
#endif /* HAVE_EXECVEAT */

execute_result = 0;
#ifdef HAVE_EXECVEAT
if (fstat (fd, &sb) == -1) {
#else
if (stat (s, &sb) == -1) {
#endif /* HAVE_EXECVEAT */
perror ("stat");
#ifdef HAVE_EXECVEAT
(void) close (fd);
(void) close (dfd);
#else
free (s);
#endif /* HAVE_EXECVEAT */
for (; n<scanlist; n++) {
free (namelist[n]);
}
free (namelist);
return (1);
}

if (S_ISREG (sb.st_mode) || S_ISLNK (sb.st_mode)) {
execute_result = run_part (s, name, action);
if (!S_ISREG (sb.st_mode)) {
#ifdef HAVE_EXECVEAT
(void) close (fd);
#else
free (s);
#endif /* HAVE_EXECVEAT */
free (namelist[n]);
continue;
}

if ((sb.st_uid != 0 && sb.st_uid != getuid()) ||
(sb.st_gid != 0 && sb.st_gid != getgid()) ||
(sb.st_mode & 0002)) {
fprintf (shadow_logfd, "skipping %s due to insecure ownership/permission\n",
namelist[n]->d_name);
#ifdef HAVE_EXECVEAT
(void) close (fd);
#else
free (s);
#endif /* HAVE_EXECVEAT */
free (namelist[n]);
continue;
}

#ifdef HAVE_EXECVEAT
execute_result = run_part (fd, namelist[n]->d_name, name, action);
(void) close (fd);
#else
execute_result = run_part (s, namelist[n]->d_name, name, action);
free (s);
#endif /* HAVE_EXECVEAT */

if (execute_result!=0) {
fprintf (shadow_logfd,
Expand All @@ -101,6 +169,10 @@
}
free (namelist);

#ifdef HAVE_EXECVEAT
(void) close (dfd);
#endif /* HAVE_EXECVEAT */

return (execute_result);
}

1 change: 0 additions & 1 deletion lib/run_part.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef _RUN_PART_H
#define _RUN_PART_H

int run_part (char *script_path, const char *name, const char *action);
int run_parts (const char *directory, const char *name, const char *action);

#endif /* _RUN_PART_H */