/* * Program: bindcmd * * Description: * This program binds to the given network address and executes the * given command upon accepting a connection. * Copyright (c) 2003, John T. Criswell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the author nor the contributors may be used to * endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * RCS_ID: $Header: /u/jcriswel/src/bindshell/RCS/bindcmd.c,v 1.1 2003/04/11 21:53:56 jcriswel Exp $ */ #include #include #include #include #include #include int main (int argc, char ** argv) { /* Network Addresses */ struct sockaddr_in in_address; struct sockaddr * address; /* Network address size */ int address_size; /* Socket file descriptor */ int s; /* New connection socket file descriptor */ int connfd; /* Child process ID */ int pid; /* Variable for setting socket options */ int yes=1; /* * First, determine whether the number of command line arguments is * correct. */ if (argc < 3) { usage (argv[0]); exit (1); } /* * Next, construct the network address. */ in_address.sin_family = AF_INET; in_address.sin_addr.s_addr = htonl (0); in_address.sin_port = htons (atoi (argv[1])); address = (void *) &(in_address); address_size = sizeof (in_address); /* * Create a socket and bind it to the specified address. */ if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror (argv[0]); exit (2); } setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes)); if ((bind (s, address, address_size)) == -1) { perror (argv[0]); exit (2); } if (listen (s, 5)) { perror (argv[0]); exit (2); } while (1) { if ((connfd = accept (s, NULL, NULL)) == -1) { perror (argv[0]); exit (3); } /* * Create a new child process. */ switch (pid = fork()) { case -1: perror (argv[0]); exit (4); break; case 0: break; default: close (connfd); continue; } /* * Close the parent's accepting socket. */ close (s); /* * Close stdin and stdout and make them the new socket. */ close (STDIN_FILENO); close (STDOUT_FILENO); close (STDERR_FILENO); dup (connfd); dup (connfd); dup (connfd); /* * Execute the new program. */ execvp (argv[2], &(argv[2])); perror (argv[0]); exit (5); } } int usage (char * name) { fprintf (stderr, "%s: file [file ...]\n", name); fprintf (stderr, "\t can be any combination of r,w,x where:"); fprintf (stderr, "\t\tr=read access"); fprintf (stderr, "\t\tw=write access"); fprintf (stderr, "\t\tx=execute access"); return 0; }