Fixup fromcvs/togit conversion
[minix-pkgsrc.git] / security / dirmngr / files / runDirmngr.c
blobddb4f1d5c0850c3f84d33658acaf91b9c848d20a
1 /*
2 Spawns dirmngr with UID and GID with a specific UID and GID.
3 The path for dirmngr is specified by the compiled-in definition
4 DIRMNGR_USER, normally passed as a compiler argument:
6 `-D DIRMNGR_USER=DEFINITION'
8 The UID and GID are the uid and gid for user DIRMNGR_USER.
9 DIRMNGR_USER is normally defined through a compiler argument
10 also.
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <errno.h>
18 #include <stdlib.h>
19 #include <sys/wait.h>
20 #include <pwd.h>
21 #include <syslog.h>
23 #define MAX_ARGS 40
24 #ifndef TRUE
25 #define TRUE 1
26 #endif /* TRUE */
28 #ifndef FALSE
29 #define FALSE 0
30 #endif /* FALSE */
33 void error_sys(char *str)
36 /* Output error message to syslog */
37 char msg[1024];
38 snprintf(msg, sizeof(msg), "runDirmngr : %s : %s", str, strerror(errno));
39 syslog(LOG_ALERT, msg);
44 int obtainUIDandGID(const char *name, uid_t *pw_uid, gid_t *pw_gid)
46 /* Obtain UID and GID from passwd entry identified by name */
47 struct passwd *pw_entry;
48 char msg[100];
50 if ((pw_entry = getpwnam(name)) == NULL)
52 snprintf(msg, sizeof(msg), "failed to get password entry for %s", name);
53 error_sys(msg);
54 return FALSE;
56 else
58 *pw_uid = pw_entry->pw_uid;
59 *pw_gid = pw_entry->pw_gid;
60 return TRUE;
68 int main (int argc, char **argv )
72 pid_t pid;
73 uid_t UID;
74 gid_t GID;
75 pid_t pidwait;
76 int waitstat;
78 /* Sanity check */
79 if (argc > MAX_ARGS)
81 error_sys("arg buffer too small");
82 exit(-1);
85 if (getpid() != 0)
87 error_sys("must be called by root");
88 exit(-1);
92 /* fork child that will become dirmngr */
93 if ((pid = fork()) < 0)
95 error_sys("fork error");
97 else
101 if (pid == 0)
105 /* We're the child */
106 char *args[MAX_ARGS];
107 unsigned int i;
109 if (!obtainUIDandGID(DIRMNGR_USER, &UID, &GID))
110 exit(-1);
112 /* Drop privileges immediately */
113 if (setgid(GID) < 0)
115 /* It is VERY important to check return
116 value and not continue if setgid fails
118 error_sys ("setgid failed");
119 exit (-1);
122 if (setuid(UID) < 0)
124 /* It is VERY important to check return
125 value and not continue if setuid fails
127 error_sys ("setuid failed");
128 exit (-1);
131 /* Build calling argv */
132 args[0] = DIRMNGR_PATH;
133 for (i=1;i<argc;i++)
135 args[i] = argv[i];
137 args[i++] = NULL;
139 /* Finally transform self into dirmngr */
140 if (execvp(DIRMNGR_PATH, args) < 0)
141 error_sys("execve error");
142 else
143 ; /* avoid if-then ambiguity */
146 else
149 /* We're the parent
150 Wait for child to terminate
152 pidwait = waitpid(pid, &waitstat, 0);
153 switch (pidwait) {
154 case 0: exit(0);
155 case -1:
156 perror(strerror(errno));
157 exit(-1);
158 default:
159 if (WIFEXITED(waitstat)) {
160 exit(WEXITSTATUS(waitstat));
162 else
164 exit(-1);