blob: 6efc03c3ae585a3043fc8e665ad025d2b2046fd7 [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"
Juan Cespedescac15c32003-01-31 18:58:58 +010016#include "debug.h"
Juan Cespedes5e01f651998-03-08 22:31:44 +010017#include "sysdep.h"
18
Juan Cespedes8cc1b9d2002-03-01 19:54:23 +010019static void
20change_uid(struct process * proc) {
Juan Cespedese1887051998-03-10 00:08:41 +010021 uid_t run_uid, run_euid;
22 gid_t run_gid, run_egid;
23
24 if (opt_u) {
25 struct passwd *pent;
26
27 if (getuid() != 0 || geteuid() != 0) {
28 fprintf(stderr, "you must be root to use the -u option\n");
29 exit(1);
30 }
31 if ((pent = getpwnam(opt_u)) == NULL) {
32 fprintf(stderr, "cannot find user `%s'\n", opt_u);
33 exit(1);
34 }
35 run_uid = pent->pw_uid;
36 run_gid = pent->pw_gid;
37
38 if (initgroups(opt_u, run_gid) < 0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020039 perror("ltrace: initgroups");
Juan Cespedese1887051998-03-10 00:08:41 +010040 exit(1);
41 }
42 } else {
43 run_uid = getuid();
44 run_gid = getgid();
45 }
46 if (opt_u || !geteuid()) {
47 struct stat statbuf;
48 run_euid = run_uid;
49 run_egid = run_gid;
50
51 if (!stat(proc->filename, &statbuf)) {
52 if (statbuf.st_mode & S_ISUID) {
53 run_euid = statbuf.st_uid;
54 }
55 if (statbuf.st_mode & S_ISGID) {
Juan Cespedes666da8b1998-04-29 20:21:48 +020056 run_egid = statbuf.st_gid;
Juan Cespedese1887051998-03-10 00:08:41 +010057 }
58 }
59 if (setregid(run_gid, run_egid) < 0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020060 perror("ltrace: setregid");
Juan Cespedese1887051998-03-10 00:08:41 +010061 exit(1);
62 }
63 if (setreuid(run_uid, run_euid) < 0) {
Juan Cespedese3eb9aa1999-04-03 03:21:52 +020064 perror("ltrace: setreuid");
Juan Cespedese1887051998-03-10 00:08:41 +010065 exit(1);
66 }
67 }
68}
Juan Cespedescac15c32003-01-31 18:58:58 +010069
70void
71execute_program(struct process * sp, char **argv) {
72 pid_t pid;
73
74 debug(1, "Executing `%s'...", sp->filename);
75
76 pid = fork();
77 if (pid<0) {
78 perror("ltrace: fork");
79 exit(1);
80 } else if (!pid) { /* child */
81 change_uid(sp);
82 trace_me();
83 execvp(sp->filename, argv);
84 fprintf(stderr, "Can't execute `%s': %s\n", sp->filename, strerror(errno));
85 exit(1);
86 }
87
88 debug(1, "PID=%d", pid);
89
90 sp->pid = pid;
91
92 return;
93}