static int serve(struct string_list *listen_addr, int listen_port, struct credentials *cred) { struct socketlist socklist = { NULL, 0, 0 }; socksetup(listen_addr, listen_port, &socklist); if (socklist.nr == 0) die("unable to allocate any listen sockets on port %u", listen_port); drop_privileges(cred); return service_loop(&socklist); }
static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid) { struct socketlist socklist = { NULL, 0, 0 }; socksetup(listen_addr, listen_port, &socklist); if (socklist.nr == 0) die("unable to allocate any listen sockets on port %u", listen_port); if (pass && gid && (initgroups(pass->pw_name, gid) || setgid (gid) || setuid(pass->pw_uid))) die("cannot drop privileges"); return service_loop(&socklist); }
static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid) { int socknum, *socklist; socknum = socksetup(listen_addr, listen_port, &socklist); if (socknum == 0) die("unable to allocate any listen sockets on host %s port %u", listen_addr, listen_port); if (pass && gid && (initgroups(pass->pw_name, gid) || setgid (gid) || setuid(pass->pw_uid))) die("cannot drop privileges"); return service_loop(socknum, socklist); }
int main(int argc, char *argv[]){ int sockfd, numbytes, childproc; int y, x , i , L, index; char *msg, *user, *buffer = (char*) malloc((USERNAMESIZE + MAXDATASIZE + 4)*sizeof(char)); char *addr = NULL; if(argc >= 2){ addr=argv[1]; } sockfd=socksetup(addr); user=startscreen(); L=strlen(user); // SETTING UP ncurses WINDOWS WINDOW *in, *out; initscr(); cbreak(); echo(); in = newwin(4, 0, LINES-4, 0); out = newwin(LINES-4, 0, 0, 0); scrollok(in, TRUE); scrollok(out, TRUE); childproc = fork(); if(childproc >= 0){ if(childproc > 0){ //RECEIVING MESSAGES while((numbytes = recv(sockfd, buffer, (USERNAMESIZE + MAXDATASIZE + 4), 0)) >0) { if(0 < strlen(buffer)){ index=getuser(buffer); wattron(out, A_BOLD); for(i=0;i<index;i++) wprintw(out, "%c", buffer[i]); wattroff(out, A_BOLD); wprintw(out, "%s\n", buffer + index); } wrefresh(out); wrefresh(in); wmove(in, 0, 0); } } else //SENDING MESSAGES while(1){ mvwgetstr(in,0, 0, buffer); wmove(in, 0, 0); werase(in); wrefresh(in); msg=parsemsg(user, buffer, L); if (send(sockfd, msg, MAXDATASIZE + USERNAMESIZE + 4, 0) == -1) close(sockfd); } } wgetch(in); delwin(in); delwin(out); endwin(); close(sockfd); free(buffer); return 0; }
int main(int argc, char **argv) { int ch_options, errs, f, funix, *finet, i, lfd, socket_debug; fd_set defreadfds; struct sockaddr_un un, fromunix; struct sockaddr_storage frominet; socklen_t fromlen; sigset_t omask, nmask; struct servent *sp, serv; int inet_flag = 0, inet6_flag = 0; euid = geteuid(); /* these shouldn't be different */ uid = getuid(); ch_options = 0; socket_debug = 0; gethostname(local_host, sizeof(local_host)); progname = "lpd"; if (euid != 0) errx(EX_NOPERM,"must run as root"); errs = 0; while ((i = getopt(argc, argv, "cdlpswW46")) != -1) switch (i) { case 'c': /* log all kinds of connection-errors to syslog */ ch_options |= LPD_LOGCONNERR; break; case 'd': socket_debug++; break; case 'l': lflag++; break; case 'p': /* letter initially used for -s */ /* * This will probably be removed with 5.0-release. */ /* FALLTHROUGH */ case 's': /* secure (no inet) */ sflag++; break; case 'w': /* netbsd uses -w for maxwait */ /* * This will be removed after the release of 4.4, as * it conflicts with -w in netbsd's lpd. For now it * is just a warning, so we won't suddenly break lpd * for anyone who is currently using the option. */ syslog(LOG_WARNING, "NOTE: the -w option has been renamed -W"); syslog(LOG_WARNING, "NOTE: please change your lpd config to use -W"); /* FALLTHROUGH */ case 'W': /* allow connections coming from a non-reserved port */ /* (done by some lpr-implementations for MS-Windows) */ ch_options |= LPD_NOPORTCHK; break; case '4': family = PF_INET; inet_flag++; break; case '6': #ifdef INET6 family = PF_INET6; inet6_flag++; #else errx(EX_USAGE, "lpd compiled sans INET6 (IPv6 support)"); #endif break; /* * The following options are not in FreeBSD (yet?), but are * listed here to "reserve" them, because the option-letters * are used by either NetBSD or OpenBSD (as of July 2001). */ case 'b': /* set bind-addr */ case 'n': /* set max num of children */ case 'r': /* allow 'of' for remote ptrs */ /* ...[not needed in freebsd] */ /* FALLTHROUGH */ default: errs++; } if (inet_flag && inet6_flag) family = PF_UNSPEC; argc -= optind; argv += optind; if (errs) usage(); if (argc == 1) { if ((i = atoi(argv[0])) == 0) usage(); if (i < 0 || i > USHRT_MAX) errx(EX_USAGE, "port # %d is invalid", i); serv.s_port = htons(i); sp = &serv; argc--; } else { sp = getservbyname("printer", "tcp"); if (sp == NULL) errx(EX_OSFILE, "printer/tcp: unknown service"); } if (argc != 0) usage(); /* * We run chkprintcap right away to catch any errors and blat them * to stderr while we still have it open, rather than sending them * to syslog and leaving the user wondering why lpd started and * then stopped. There should probably be a command-line flag to * ignore errors from chkprintcap. */ { pid_t pid; int status; pid = fork(); if (pid < 0) { err(EX_OSERR, "cannot fork"); } else if (pid == 0) { /* child */ execl(_PATH_CHKPRINTCAP, _PATH_CHKPRINTCAP, (char *)0); err(EX_OSERR, "cannot execute %s", _PATH_CHKPRINTCAP); } if (waitpid(pid, &status, 0) < 0) { err(EX_OSERR, "cannot wait"); } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) errx(EX_OSFILE, "%d errors in printcap file, exiting", WEXITSTATUS(status)); } #ifndef DEBUG /* * Set up standard environment by detaching from the parent. */ daemon(0, 0); #endif openlog("lpd", LOG_PID, LOG_LPR); syslog(LOG_INFO, "lpd startup: logging=%d%s%s", lflag, socket_debug ? " dbg" : "", sflag ? " net-secure" : ""); (void) umask(0); /* * NB: This depends on O_NONBLOCK semantics doing the right thing; * i.e., applying only to the O_EXLOCK and not to the rest of the * open/creation. As of 1997-12-02, this is the case for commonly- * used filesystems. There are other places in this code which * make the same assumption. */ lfd = open(_PATH_MASTERLOCK, O_WRONLY|O_CREAT|O_EXLOCK|O_NONBLOCK, LOCK_FILE_MODE); if (lfd < 0) { if (errno == EWOULDBLOCK) /* active daemon present */ exit(0); syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); exit(1); } fcntl(lfd, F_SETFL, 0); /* turn off non-blocking mode */ ftruncate(lfd, 0); /* * write process id for others to know */ sprintf(line, "%u\n", getpid()); f = strlen(line); if (write(lfd, line, f) != f) { syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK); exit(1); } signal(SIGCHLD, reapchild); /* * Restart all the printers. */ startup(); (void) unlink(_PATH_SOCKETNAME); funix = socket(AF_UNIX, SOCK_STREAM, 0); if (funix < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } sigemptyset(&nmask); sigaddset(&nmask, SIGHUP); sigaddset(&nmask, SIGINT); sigaddset(&nmask, SIGQUIT); sigaddset(&nmask, SIGTERM); sigprocmask(SIG_BLOCK, &nmask, &omask); (void) umask(07); signal(SIGHUP, mcleanup); signal(SIGINT, mcleanup); signal(SIGQUIT, mcleanup); signal(SIGTERM, mcleanup); memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; strcpy(un.sun_path, _PATH_SOCKETNAME); #ifndef SUN_LEN #define SUN_LEN(unp) (strlen((unp)->sun_path) + 2) #endif if (bind(funix, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) { syslog(LOG_ERR, "ubind: %m"); exit(1); } (void) umask(0); sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); FD_ZERO(&defreadfds); FD_SET(funix, &defreadfds); listen(funix, 5); if (sflag == 0) { finet = socksetup(family, socket_debug); } else finet = NULL; /* pretend we couldn't open TCP socket. */ if (finet) { for (i = 1; i <= *finet; i++) { FD_SET(finet[i], &defreadfds); listen(finet[i], 5); } } /* * Main loop: accept, do a request, continue. */ memset(&frominet, 0, sizeof(frominet)); memset(&fromunix, 0, sizeof(fromunix)); if (lflag) syslog(LOG_INFO, "lpd startup: ready to accept requests"); /* * XXX - should be redone for multi-protocol */ for (;;) { int domain, nfds, s; fd_set readfds; FD_COPY(&defreadfds, &readfds); nfds = select(20, &readfds, 0, 0, 0); if (nfds <= 0) { if (nfds < 0 && errno != EINTR) syslog(LOG_WARNING, "select: %m"); continue; } domain = -1; /* avoid compile-time warning */ s = -1; /* avoid compile-time warning */ if (FD_ISSET(funix, &readfds)) { domain = AF_UNIX, fromlen = sizeof(fromunix); s = accept(funix, (struct sockaddr *)&fromunix, &fromlen); } else { for (i = 1; i <= *finet; i++) if (FD_ISSET(finet[i], &readfds)) { domain = AF_INET; fromlen = sizeof(frominet); s = accept(finet[i], (struct sockaddr *)&frominet, &fromlen); } } if (s < 0) { if (errno != EINTR) syslog(LOG_WARNING, "accept: %m"); continue; } if (fork() == 0) { /* * Note that printjob() also plays around with * signal-handling routines, and may need to be * changed when making changes to signal-handling. */ signal(SIGCHLD, SIG_DFL); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); (void) close(funix); if (sflag == 0 && finet) { for (i = 1; i <= *finet; i++) (void)close(finet[i]); } dup2(s, STDOUT_FILENO); (void) close(s); if (domain == AF_INET) { /* for both AF_INET and AF_INET6 */ from_remote = 1; chkhost((struct sockaddr *)&frominet, ch_options); } else from_remote = 0; doit(); exit(0); } (void) close(s); } }