|
|
1.1 ! root 1: /* ! 2: * asdrcv - receive sealed packages ! 3: * ! 4: * This program will normally be installed as /etc/asd/asdrcv ! 5: * and will be run as root (!). It is invoked as follows: ! 6: * ! 7: * /etc/asdrcv machine uid ! 8: * ! 9: * where the standard input is a sealed package. First it ! 10: * verifies that machine and uid are valid: they must consist ! 11: * entirely of letters and digits and may not be empty. ! 12: * Next we look at the file /etc/asd/perm/machine/uid. ! 13: * If this file doesn't exist, reject. If it does exist, ! 14: * it represents the uid and gid on the receiving machine ! 15: * to use. The default is the uid/gid under which asdrcv ! 16: * invoked, usually (root, other). ! 17: * ! 18: * ! 19: * We next arrange to send all stderr output to machine!uid. ! 20: * Finally, operating as the appropriate user, we create the ! 21: * following pipeline: ! 22: * ! 23: * unseal -K /etc/asd/keys/machine/uid | inspkg ! 24: */ ! 25: ! 26: #include "asd.h" ! 27: ! 28: static char *keybase = "/etc/asd/keys"; ! 29: static char *permbase = "/etc/asd/perm"; ! 30: static char *buildname(); ! 31: ! 32: main (argc, argv) ! 33: int argc; ! 34: char **argv; ! 35: { ! 36: register int i; ! 37: char *permfile, *keyfile, *user; ! 38: register FILE *permfd; ! 39: int pipefd[2]; ! 40: ! 41: /* check for exactly two arguments */ ! 42: if (argc != 2 + 1) { ! 43: fprintf (stderr, "asdrcv: arg count\n"); ! 44: exit (1); ! 45: } ! 46: ! 47: /* each argument must be nonempty and all letters or digits */ ! 48: for (i = 1; i < argc; i++) { ! 49: register char *p = argv[i]; ! 50: if (*p == '\0') { ! 51: fprintf (stderr, "asdrcv: null argument\n"); ! 52: exit (1); ! 53: } ! 54: ! 55: do { ! 56: register c = *p++; ! 57: if (!isalpha (c) && !isdigit (c)) { ! 58: fprintf (stderr, "asdrcv: invalid argument\n"); ! 59: exit (1); ! 60: } ! 61: } while (*p != '\0'); ! 62: } ! 63: ! 64: /* develop the names of the permission file and keyfile */ ! 65: permfile = buildname (permbase, argv[1], argv[2]); ! 66: keyfile = buildname (keybase, argv[1], argv[2]); ! 67: ! 68: /* now try to read the permission file */ ! 69: permfd = fopen (permfile, "r"); ! 70: if (permfd == NULL) { ! 71: perror (permfile); ! 72: exit (1); ! 73: } ! 74: ! 75: /* the optional line represents a uid/gid pair */ ! 76: i = getc (permfd); ! 77: if (i != EOF) { ! 78: int uid, gid; ! 79: ungetc (i, permfd); ! 80: uid = numuid (getfield (permfd)); ! 81: gid = numgid (getfield (permfd)); ! 82: setgid (gid); ! 83: setuid (uid); ! 84: } ! 85: ! 86: /* we're done with the file */ ! 87: fclose (permfd); ! 88: ! 89: /* build the stderr pipe */ ! 90: if (pipe (pipefd) < 0) { ! 91: perror ("stderr pipe"); ! 92: exit (1); ! 93: } ! 94: ! 95: /* fork off a mail process */ ! 96: switch (fork()) { ! 97: ! 98: case 0: /* child */ ! 99: close (pipefd[1]); /* close the write end */ ! 100: dup2 (pipefd[0], 0); /* stdin := read end */ ! 101: if (pipefd[0] != 0) ! 102: close (pipefd[0]); /* close the read end */ ! 103: ! 104: /* make a string for machine!user */ ! 105: user = alloc (strlen (argv[1]) + strlen (argv[2]) + 2); ! 106: strcpy (user, argv[1]); ! 107: strcat (user, "!"); ! 108: strcat (user, argv[2]); ! 109: ! 110: /* send mail */ ! 111: execl ("/bin/mail", "mail", user, (char *) 0); ! 112: execl ("/usr/bin/mail", "mail", user, (char *) 0); ! 113: exit (1); ! 114: ! 115: case -1: ! 116: perror ("stderr fork"); ! 117: exit (1); ! 118: ! 119: default: /* parent */ ! 120: close (pipefd[0]); /* close the read end */ ! 121: dup2 (pipefd[1], 2); /* stderr := write end */ ! 122: close (pipefd[1]); /* close the write end */ ! 123: } ! 124: ! 125: /* build the next pipe */ ! 126: if (pipe (pipefd) < 0) { ! 127: perror ("pipe"); ! 128: exit (1); ! 129: } ! 130: ! 131: /* create the processes */ ! 132: fflush (stdout); ! 133: switch (fork()) { ! 134: ! 135: case -1: /* error */ ! 136: perror ("fork"); ! 137: exit (1); ! 138: ! 139: case 0: /* child */ ! 140: close (pipefd[0]); ! 141: if (dup2 (pipefd[1], 1) < 0) { ! 142: perror ("stdout dup"); ! 143: exit (1); ! 144: } ! 145: close (pipefd[1]); ! 146: execl ("/bin/unseal", "unseal", "-K", keyfile, (char *) 0); ! 147: execl ("/usr/bin/unseal", "unseal", "-K", keyfile, (char *) 0); ! 148: fprintf (stderr, "asdrcv: cannot exec unseal\n"); ! 149: exit (1); ! 150: ! 151: default: /* parent */ ! 152: close (pipefd[1]); ! 153: if (dup2 (pipefd[0], 0) < 0) { ! 154: perror ("stdin dup"); ! 155: exit (1); ! 156: } ! 157: close (pipefd[0]); ! 158: execl ("/bin/inspkg", "inspkg", (char *) 0); ! 159: execl ("/usr/bin/inspkg", "inspkg", (char *) 0); ! 160: fprintf (stderr, "asdrcv: cannot exec inspkg\n"); ! 161: exit (1); ! 162: } ! 163: } ! 164: ! 165: /* return a name of the form dir/comp1/comp2 */ ! 166: static char * ! 167: buildname (dir, comp1, comp2) ! 168: char *dir, *comp1, *comp2; ! 169: { ! 170: register char *r; ! 171: ! 172: r = alloc ( ! 173: strlen (dir) + /* name of directory */ ! 174: strlen (comp1) + /* first component */ ! 175: strlen (comp2) + /* second component */ ! 176: 3 /* two slashes and ending null */ ! 177: ); ! 178: ! 179: strcpy (r, dir); ! 180: strcat (r, "/"); strcat (r, comp1); ! 181: strcat (r, "/"); strcat (r, comp2); ! 182: ! 183: return r; ! 184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.