void suidgid(char *user, unsigned int ext) { struct uidgid ugid; if (ext) { if (! uidgids_get(&ugid, user)) { if (*user == ':') fatalx("invalid uid/gids", user +1); if (errno) fatal("unable to get password/group file entry"); fatalx("unknown user/group", user); } } else if (! uidgid_get(&ugid, user)) { if (errno) fatal("unable to get password file entry"); fatalx("unknown account", user); } if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to setgroups"); if (setgid(*ugid.gid) == -1) fatal("unable to setgid"); if (prot_uid(ugid.uid) == -1) fatal("unable to setuid"); }
void euidgid(char *user, unsigned int ext) { struct uidgid ugid; char bufnum[FMT_ULONG]; if (ext) { if (! uidgids_get(&ugid, user)) { if (*user == ':') fatalx("invalid uid/gids", user +1); if (errno) fatal("unable to get password/group file entry"); fatalx("unknown user/group", user); } } else if (! uidgid_get(&ugid, user)) { if (errno) fatal("unable to get password file entry"); fatalx("unknown account", user); } bufnum[fmt_ulong(bufnum, *ugid.gid)] =0; if (! pathexec_env("GID", bufnum)) die_nomem(); bufnum[fmt_ulong(bufnum, ugid.uid)] =0; if (! pathexec_env("UID", bufnum)) die_nomem(); }
int main(int argc, char **argv) { int opt; char *user =0; char *host; unsigned long port; int pid; int s; int conn; int delim; progname =*argv; phccmax =0; #ifdef SSLSVD while ((opt =getopt(argc, (const char **)argv, "c:C:i:x:u:l:Eb:hpt:vVU:/:Z:K:")) != opteof) { #else while ((opt =getopt(argc, (const char **)argv, "c:C:i:x:u:l:Eb:hpt:vV")) != opteof) { #endif switch(opt) { case 'c': scan_ulong(optarg, &cmax); if (cmax < 1) usage(); break; case 'C': delim =scan_ulong(optarg, &phccmax); if (phccmax < 1) usage(); if (optarg[delim] == ':') { if (ipsvd_fmt_msg(&msg, optarg +delim +1) == -1) die_nomem(); if (! stralloc_0(&msg)) die_nomem(); phccmsg =msg.s; } break; case 'i': if (instructs) usage(); instructs =optarg; break; case 'x': if (instructs) usage(); instructs =optarg; iscdb =1; break; case 'u': user =(char*)optarg; break; case 'l': if (! stralloc_copys(&local_hostname, optarg)) die_nomem(); if (! stralloc_0(&local_hostname)) die_nomem(); break; case 'E': ucspi =0; break; case 'b': scan_ulong(optarg, &backlog); break; case 'h': lookuphost =1; break; case 'p': lookuphost =1; paranoid =1; break; case 't': scan_ulong(optarg, &timeout); break; case 'v': ++verbose; break; #ifdef SSLSVD case 'U': ssluser =(char*)optarg; break; case '/': root =(char*)optarg; break; case 'Z': cert =(char*)optarg; break; case 'K': key =(char*)optarg; break; #endif case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); host =*argv++; if (! argv || ! *argv) usage(); local_port =*argv++; if (! argv || ! *argv) usage(); prog =(const char **)argv; if (phccmax > cmax) phccmax =cmax; if (user) if (! uidgids_get(&ugid, user)) { if (errno) strerr_die4sys(111, FATAL, "unable to get user/group: ", user, ": "); strerr_die3x(100, FATAL, "unknown user/group: ", user); } #ifdef SSLSVD svuser =user; client =0; if ((getuid() == 0) && (! ssluser)) strerr_die2x(100, FATAL, "-U ssluser must be set when running as root"); if (ssluser) if (! uidgids_get(&sslugid, ssluser)) { if (errno) strerr_die4sys(111, FATAL, "unable to get user/group: ", ssluser, ": "); strerr_die3x(100, FATAL, "unknown user/group: ", ssluser); } if (! cert) cert ="./cert.pem"; if (! key) key =cert; if (matrixSslOpen() < 0) fatal("unable to initialize ssl"); if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) { if (client) fatal("unable to read cert, key, or ca file"); fatal("unable to read cert or key file"); } if (matrixSslNewSession(&ssl, keys, 0, SSL_FLAGS_SERVER) < 0) strerr_die2x(111, FATAL, "unable to create ssl session"); #endif dns_random_init(seed); sig_block(sig_child); sig_catch(sig_child, sig_child_handler); sig_catch(sig_term, sig_term_handler); sig_ignore(sig_pipe); if (phccmax) if (ipsvd_phcc_init(cmax) == -1) die_nomem(); if (str_equal(host, "")) host ="0.0.0.0"; if (str_equal(host, "0")) host ="0.0.0.0"; if (! ipsvd_scan_port(local_port, "tcp", &port)) strerr_die3x(100, FATAL, "unknown port number or name: ", local_port); if (! stralloc_copys(&sa, host)) die_nomem(); if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4)) if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1) fatal2("unable to look up ip address", host); if (ips.len < 4) strerr_die3x(100, FATAL, "unable to look up ip address: ", host); ips.len =4; if (! stralloc_0(&ips)) die_nomem(); local_ip[ipsvd_fmt_ip(local_ip, ips.s)] =0; if (! lookuphost) { if (! stralloc_copys(&remote_hostname, "")) die_nomem(); if (! stralloc_0(&remote_hostname)) die_nomem(); } if ((s =socket_tcp()) == -1) fatal("unable to create socket"); if (socket_bind4_reuse(s, ips.s, port) == -1) fatal("unable to bind socket"); if (listen(s, backlog) == -1) fatal("unable to listen"); ndelay_off(s); #ifdef SSLSVD #else if (user) { /* drop permissions */ if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups"); if (setgid(*ugid.gid) == -1) fatal("unable to set gid"); if (prot_uid(ugid.uid) == -1) fatal("unable to set uid"); } #endif close(0); if (verbose) { out(INFO); out("listening on "); outfix(local_ip); out(":"); outfix(local_port); #ifdef SSLSVD #else if (user) { bufnum[fmt_ulong(bufnum, (unsigned long)ugid.uid)] =0; out(", uid "); out(bufnum); bufnum[fmt_ulong(bufnum, (unsigned long)ugid.gid)] =0; out(", gid "); out(bufnum); } #endif flush(", starting.\n"); } for (;;) { while (cnum >= cmax) sig_pause(); socka_size =sizeof(socka); sig_unblock(sig_child); conn =accept(s, (struct sockaddr *)&socka, &socka_size); sig_block(sig_child); if (conn == -1) { if (errno != error_intr) warn("unable to accept connection"); continue; } cnum++; if (verbose) connection_status(); if (phccmax) phcc =ipsvd_phcc_add((char*)&socka.sin_addr); if ((pid =fork()) == -1) { warn2("drop connection", "unable to fork"); close(conn); continue; } if (pid == 0) { /* child */ close(s); #ifdef SSLSVD if (*progname) *progname ='\\'; #endif connection_accept(conn); } if (phccmax) ipsvd_phcc_setpid(pid); close(conn); } _exit(0); }