blob: 0306678e1fbe8c2af17375e7e4e1ef38cb358b63 [file] [log] [blame]
Juan Cespedesd44c6b81998-09-25 14:48:42 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Juan Cespedes5e01f651998-03-08 22:31:44 +01005#include <stdio.h>
Juan Cespedese1887051998-03-10 00:08:41 +01006#include <sys/types.h>
7#include <sys/stat.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +01008#include <unistd.h>
9#include <errno.h>
10#include <string.h>
Juan Cespedese1887051998-03-10 00:08:41 +010011#include <pwd.h>
12#include <grp.h>
Juan Cespedes5e01f651998-03-08 22:31:44 +010013
14#include "ltrace.h"
15#include "options.h"
16#include "output.h"
17#include "sysdep.h"
18
Juan Cespedese1887051998-03-10 00:08:41 +010019static void change_uid(struct process * proc);
20
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010021void
22execute_program(struct process * sp, char **argv) {
Juan Cespedesd44c6b81998-09-25 14:48:42 +020023 pid_t pid;
Juan Cespedes5e01f651998-03-08 22:31:44 +010024
25 if (opt_d) {
26 output_line(0, "Executing `%s'...", sp->filename);
27 }
28
29 pid = fork();
30 if (pid<0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020031 perror("ltrace: fork");
Juan Cespedes5e01f651998-03-08 22:31:44 +010032 exit(1);
33 } else if (!pid) { /* child */
Juan Cespedes28f60191998-04-12 00:04:39 +020034 change_uid(sp);
Juan Cespedes666da8b1998-04-29 20:21:48 +020035 trace_me();
Juan Cespedes5e01f651998-03-08 22:31:44 +010036 execvp(sp->filename, argv);
37 fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno));
38 exit(1);
39 }
40
41 if (opt_d) {
42 output_line(0, "PID=%d", pid);
43 }
44
45 sp->pid = pid;
46
47 return;
48}
Juan Cespedese1887051998-03-10 00:08:41 +010049
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010050static void
51change_uid(struct process * proc) {
Juan Cespedese1887051998-03-10 00:08:41 +010052 uid_t run_uid, run_euid;
53 gid_t run_gid, run_egid;
54
55 if (opt_u) {
56 struct passwd *pent;
57
58 if (getuid() != 0 || geteuid() != 0) {
59 fprintf(stderr, "you must be root to use the -u option\n");
60 exit(1);
61 }
62 if ((pent = getpwnam(opt_u)) == NULL) {
63 fprintf(stderr, "cannot find user `%s'\n", opt_u);
64 exit(1);
65 }
66 run_uid = pent->pw_uid;
67 run_gid = pent->pw_gid;
68
69 if (initgroups(opt_u, run_gid) < 0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020070 perror("ltrace: initgroups");
Juan Cespedese1887051998-03-10 00:08:41 +010071 exit(1);
72 }
73 } else {
74 run_uid = getuid();
75 run_gid = getgid();
76 }
77 if (opt_u || !geteuid()) {
78 struct stat statbuf;
79 run_euid = run_uid;
80 run_egid = run_gid;
81
82 if (!stat(proc->filename, &statbuf)) {
83 if (statbuf.st_mode & S_ISUID) {
84 run_euid = statbuf.st_uid;
85 }
86 if (statbuf.st_mode & S_ISGID) {
Juan Cespedes666da8b1998-04-29 20:21:48 +020087 run_egid = statbuf.st_gid;
Juan Cespedese1887051998-03-10 00:08:41 +010088 }
89 }
90 if (setregid(run_gid, run_egid) < 0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020091 perror("ltrace: setregid");
Juan Cespedese1887051998-03-10 00:08:41 +010092 exit(1);
93 }
94 if (setreuid(run_uid, run_euid) < 0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020095 perror("ltrace: setreuid");
Juan Cespedese1887051998-03-10 00:08:41 +010096 exit(1);
97 }
98 }
99}