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
33 void error_sys(char *str
)
36 /* Output error message to syslog */
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
;
50 if ((pw_entry
= getpwnam(name
)) == NULL
)
52 snprintf(msg
, sizeof(msg
), "failed to get password entry for %s", name
);
58 *pw_uid
= pw_entry
->pw_uid
;
59 *pw_gid
= pw_entry
->pw_gid
;
68 int main (int argc
, char **argv
)
81 error_sys("arg buffer too small");
87 error_sys("must be called by root");
92 /* fork child that will become dirmngr */
93 if ((pid
= fork()) < 0)
95 error_sys("fork error");
105 /* We're the child */
106 char *args
[MAX_ARGS
];
109 if (!obtainUIDandGID(DIRMNGR_USER
, &UID
, &GID
))
112 /* Drop privileges immediately */
115 /* It is VERY important to check return
116 value and not continue if setgid fails
118 error_sys ("setgid failed");
124 /* It is VERY important to check return
125 value and not continue if setuid fails
127 error_sys ("setuid failed");
131 /* Build calling argv */
132 args
[0] = DIRMNGR_PATH
;
139 /* Finally transform self into dirmngr */
140 if (execvp(DIRMNGR_PATH
, args
) < 0)
141 error_sys("execve error");
143 ; /* avoid if-then ambiguity */
150 Wait for child to terminate
152 pidwait
= waitpid(pid
, &waitstat
, 0);
156 perror(strerror(errno
));
159 if (WIFEXITED(waitstat
)) {
160 exit(WEXITSTATUS(waitstat
));