#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "helpers.h" int get_file_info(struct file_info *f_info, char *xpath_base) { return 0; } /** * \brief Open a temporary file in a safe way * * Use this function to create a temporary file in a safe way with the help of * mkstemp and set file properties. * * \param name name of the temporary file in the format mkstemp expects, i.e. * ending with XXXXXX; mkstemp will modify name to contain the name of the * temporary file * \param permission string wit hthe octal repesentation of the file access * permissions * \param user name of the file owner * \param group name of the owning group * \param selinux_context_string string containing the SELinux file context * * \return file descriptor or -1 in case of an error * */ int open_temporary_file(char *name, const char *permission, const char *user, const char *group, const char *selinux_context_string) { int fd; int ret; struct passwd *pwd_info; struct group *grp_info; pwd_info=getpwnam(user); CHECK(pwd_info, NULL, ("Cannot find user %s.\n", user), return -1); grp_info=getgrnam(group); CHECK(grp_info, NULL, ("Cannot find group %s.\n", group), return -1); fd=mkstemp(name); if (fd==-1) { DEBUG(0,("mkstemp failed with template %s: %s\n",name, strerror(errno))); return -1; } ret=fchmod(fd, (mode_t) strtol(permission, NULL, 8)); CHECK(ret, -1, ("Cannot chmod temporary file to %s: %s\n", permission, strerror(errno)), return -1); ret=fchown(fd, pwd_info->pw_uid, grp_info->gr_gid); CHECK(ret, -1, ("Cannot chown temporary file to %s:%s: %s\n", user, group, strerror(errno)), return -1); if (selinux_context_string != NULL ) { ret=fsetfilecon(fd, (security_context_t ) selinux_context_string); CHECK(ret, -1, ("fsetfilecon failed: %s\n",strerror(errno)), return -1); } return fd; } /** * \brief run an external command * * This is a helper function to run an external command in a different user * context. * * \param command command to run * \param user name of the user to run the command * \param group name of the group to run the command * \param arguments space separated list of arguments, may be NULL * \param extra_args another space separated list of arguments, useful if you * have some static and some generated/extracted arguments, may be NULL * * \return return code of the external command or -1 in an error occurred * */ int exec_command(const char *command, const char *user, const char *group, char *arguments, char *extra_args) { char *argv[10]; /* FIXME */ int c=0; int i; char *cur; char *next_arg; pid_t pid; int ret; int status; int stdout_pipe[2]; int stderr_pipe[2]; char buffer[255]; struct passwd *pwd_info; struct group *grp_info; pwd_info=getpwnam(user); CHECK(pwd_info, NULL, ("Cannot find user %s.\n", user), return -1); grp_info=getgrnam(group); CHECK(grp_info, NULL, ("Cannot find group %s.\n", group), return -1); argv[c++]=strdup(command); if (arguments!=NULL) { cur=arguments; while( (next_arg=strchr(cur, ' '))!=NULL) { argv[c++]=strndup(cur, next_arg-cur); cur=next_arg+1; } argv[c++]=strdup(cur); } if (extra_args!=NULL) { cur=extra_args; while( (next_arg=strchr(cur, ' '))!=NULL) { argv[c++]=strndup(cur, next_arg-cur); cur=next_arg+1; } argv[c++]=strdup(cur); } argv[c++]=NULL; for(i=0;igr_gid); CHECK(ret, -1, ("setgid failed: %s\n",strerror(errno)), exit(1)); ret=setuid(pwd_info->pw_uid); CHECK(ret, -1, ("setuid failed: %s\n",strerror(errno)), exit(1)); execv(command, argv); } close(stdout_pipe[1]); close(stderr_pipe[1]); *buffer='\0'; ret=read(stdout_pipe[0], &buffer, 255); buffer[ret]='\0'; DEBUG(3,("stdout from child: >>%s<<\n",buffer)); *buffer='\0'; ret=read(stderr_pipe[0], &buffer, 255); buffer[ret]='\0'; DEBUG(3,("stderr from child: >>%s<<\n",buffer)); close(stdout_pipe[0]); close(stderr_pipe[0]); ret = waitpid(pid, & status, 0); if (WIFEXITED(status)) { DEBUG(3,("Child terminated normally with exit status %d\n",WEXITSTATUS(status))); } else { DEBUG(1,("Child terminated not normally.\n")); } for(i=0;i