summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/gssd/gssd_proc.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
index 36aff5d..11168b2 100644
--- a/utils/gssd/gssd_proc.c
+++ b/utils/gssd/gssd_proc.c
@@ -603,33 +603,11 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
gss_buffer_desc token;
int err, downcall_err = -EACCES;
OM_uint32 maj_stat, min_stat, lifetime_rec;
- pid_t pid;
+ pid_t pid, childpid = -1;
gss_name_t gacceptor = GSS_C_NO_NAME;
gss_OID mech;
gss_buffer_desc acceptor = {0};
- pid = fork();
- switch(pid) {
- case 0:
- /* Child: fall through to rest of function */
- break;
- case -1:
- /* fork() failed! */
- printerr(0, "WARNING: unable to fork() to handle upcall: %s\n",
- strerror(errno));
- return;
- default:
- /* Parent: just wait on child to exit and return */
- do {
- pid = wait(&err);
- } while(pid == -1 && errno != -ECHILD);
-
- if (WIFSIGNALED(err))
- printerr(0, "WARNING: forked child was killed with signal %d\n",
- WTERMSIG(err));
- return;
- }
-
printerr(1, "handling krb5 upcall (%s)\n", clp->relpath);
token.length = 0;
@@ -661,6 +639,37 @@ process_krb5_upcall(struct clnt_info *clp, uid_t uid, int fd, char *tgtname,
service ? service : "<null>");
if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0 &&
service == NULL)) {
+
+ /* already running as uid 0 */
+ if (uid == 0)
+ goto no_fork;
+
+ pid = fork();
+ switch(pid) {
+ case 0:
+ /* Child: fall through to rest of function */
+ childpid = getpid();
+ unsetenv("KRB5CCNAME");
+ printerr(1, "CHILD forked pid %d \n", childpid);
+ break;
+ case -1:
+ /* fork() failed! */
+ printerr(0, "WARNING: unable to fork() to handle"
+ "upcall: %s\n", strerror(errno));
+ return;
+ default:
+ /* Parent: just wait on child to exit and return */
+ do {
+ pid = wait(&err);
+ } while(pid == -1 && errno != -ECHILD);
+
+ if (WIFSIGNALED(err))
+ printerr(0, "WARNING: forked child was killed"
+ "with signal %d\n", WTERMSIG(err));
+ return;
+ }
+no_fork:
+
auth = krb5_not_machine_creds(clp, uid, tgtname, &downcall_err,
&err, &rpc_clnt);
if (err)
@@ -727,7 +736,12 @@ out:
AUTH_DESTROY(auth);
if (rpc_clnt)
clnt_destroy(rpc_clnt);
- exit(0);
+
+ pid = getpid();
+ if (pid == childpid)
+ exit(0);
+ else
+ return;
out_return_error:
do_error_downcall(fd, uid, downcall_err);