int login_user(POP *p) { struct stat st; struct passwd *pw; /* Look for the user in the password file */ if ((pw = k_getpwnam(p->user)) == NULL) { pop_log(p, POP_PRIORITY, "user %s (from %s) not found", p->user, p->ipaddr); return pop_msg(p, POP_FAILURE, "Login incorrect."); } pop_log(p, POP_INFO, "login from %s as %s", p->ipaddr, p->user); /* Build the name of the user's maildrop */ snprintf(p->drop_name, sizeof(p->drop_name), "%s/%s", POP_MAILDIR, p->user); if(stat(p->drop_name, &st) < 0 || !S_ISDIR(st.st_mode)){ /* Make a temporary copy of the user's maildrop */ /* and set the group and user id */ if (pop_dropcopy(p, pw) != POP_SUCCESS) return (POP_FAILURE); /* Get information about the maildrop */ if (pop_dropinfo(p) != POP_SUCCESS) return(POP_FAILURE); } else { if(changeuser(p, pw) != POP_SUCCESS) return POP_FAILURE; if(pop_maildir_info(p) != POP_SUCCESS) return POP_FAILURE; } /* Initialize the last-message-accessed number */ p->last_msg = 0; return POP_SUCCESS; }
static void closecal(FILE *fp) { struct stat sbuf; ssize_t nread; int pdes[2]; int status; char buf[1024]; if (!doall) return; (void)rewind(fp); if (fstat(fileno(fp), &sbuf) == -1 || sbuf.st_size == 0) goto done; if (pipe(pdes) == -1) goto done; switch (fork()) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]); break; case 0: /* child -- set stdin to pipe output */ if (pdes[0] != STDIN_FILENO) { (void)dup2(pdes[0], STDIN_FILENO); (void)close(pdes[0]); } (void)close(pdes[1]); if (doall) { /* become the user properly */ changeuser(); } (void)execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F", "\"Reminder Service\"", "-f", "root", NULL); err(EXIT_FAILURE, "Cannot exec `%s'", _PATH_SENDMAIL); /*NOTREACHED*/ default: /* parent -- write to pipe input */ (void)close(pdes[0]); header[1].iov_base = header[3].iov_base = (void *)pw->pw_name; header[1].iov_len = header[3].iov_len = strlen(pw->pw_name); (void)writev(pdes[1], header, 7); while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0) (void)write(pdes[1], buf, (size_t)nread); (void)close(pdes[1]); break; } done: (void)fclose(fp); (void)unlink(path); while (wait(&status) != -1) continue; }
int cron_parent_main(int argc, char *argv[]) { int pid, p2; extern int errno; #ifdef ERRFD dup2(2, ERRFD); errf = fdopen(ERRFD, "w"); #endif if (argc != 4) exit(1); /* Enough args? */ av = malloc(sizeof(char *) * 101); /* Allocate an argv array */ if (av == NULL) { print("Malloc failed: errno = %d", errno); _exit(1); } setsid(); /* Create our own little group */ changeuser(atoi(argv[2]), argv[3]); /* Give up privs */ setenviron(); /* Sanitise environ and extract useful information */ parseargs(argv[1]); /* Process the jobs command line */ setupfds(); /* Set up file descriptors */ pid = vfork(); /* Create the child process */ if (pid == 0) { close(PLISTENFD); /* Close parent only FDs */ close(PSENDFD); execve(path, av, environ); /* Run the job */ print("Exec failed: errno = %d", errno); _exit(1); } if (pid < 0) exit(1); /* Parent processing */ close(0); close(1); close(2); p2 = handlestdout(); /* Pass stdout to mail */ sendstdin(); /* Send stdin to process if required */ waitpid(pid, NULL, 0); /* Wait for children to exit */ if (p2 != 0) waitpid(p2, NULL, 0); return 0; }
static FILE * opencal(FILE **in) { int fd = -1; int pdes[2]; /* open up calendar file as stdin */ if (fname == NULL) { for (const char **name = defaultnames; *name != NULL; name++) { if ((fd = tryopen(*name, O_RDONLY)) == -1) continue; else break; } if (fd == -1) { if (doall) return NULL; err(EXIT_FAILURE, "Cannot open calendar file"); } } else if ((fd = tryopen(fname, O_RDONLY)) == -1) { if (doall) return NULL; err(EXIT_FAILURE, "Cannot open `%s'", fname); } if (pipe(pdes) == -1) { warn("Cannot open pipe"); return NULL; } switch (fork()) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]); return NULL; case 0: /* child */ /* set stdin to calendar file */ if (fd != STDIN_FILENO) { (void)dup2(fd, STDIN_FILENO); (void)close(fd); } /* set stdout to pipe input */ if (pdes[1] != STDOUT_FILENO) { (void)dup2(pdes[1], STDOUT_FILENO); (void)close(pdes[1]); } (void)close(pdes[0]); if (doall) { /* become the user properly */ changeuser(); } /* tell CPP to only open regular files */ if(!cpp_restricted && setenv("CPP_RESTRICTED", "", 1) == -1) err(EXIT_FAILURE, "Cannot restrict cpp"); cpp_restricted = true; (void)execl(_PATH_CPP, "cpp", "-traditional", "-P", "-I.", "-I" _PATH_CALENDARS, NULL); err(EXIT_FAILURE, "Cannot exec `%s'", _PATH_CPP); /*NOTREACHED*/ default: /* parent -- fdopen *in to pipe output */ *in = fdopen(pdes[0], "r"); (void)close(pdes[1]); /* close calendar file */ close(fd); /* not reading all calendar files, just set output to stdout */ if (!doall) return stdout; /* * Set output to a temporary file, so if no output * don't send mail. */ (void)snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP); if ((fd = mkstemp(path)) == -1) { warn("Cannot create temporary file"); return NULL; } return fdopen(fd, "w+"); } /*NOTREACHED*/ }