/* xs.c by me@, then jhs@ */ #include #include extern int errno; main (argc, argv, envp) int argc; char *argv []; char *envp []; { char *shell, *name, *getenv(); struct passwd *ent; char ps1[128]; char **av = argv; int ac = argc; int uid ; int rslt = 0 ; uid = getuid(); #ifdef DEBUG printf("Your UID is %d\n",uid); #endif /* Makefile usually reads ~/.xs_uid then passes in eg -DROOT_UID=200 */ #ifndef ROOT_UID #define ROOT_UID 0 /* FreeBSD default first user on 5.0-RC1 is 1001:1001 */ #endif if ((uid != ROOT_UID ) && ( uid != 0 )) { /* Perhaps dont tell user permission is refused as it tempts him */ /* fprintf(stderr, "Try /usr/local/bin/sx (for Zmodem)\n"); */ fprintf(stderr, "UID err.\n"); exit(1); } if ( uid == 0 ) /* Complain about waste of shell process space */ fprintf(stderr, "Un-necessary: You were previously root.\n"); if ((argc > 1) && (argv[1][0] == '-')) { name = av[1] + 1; sprintf(ps1, "PS1=(%s) ", name); av++; ac--; } else { name = "root"; strcpy(ps1, "PS1=(#) "); } if ((ent = getpwnam(name)) == NULL) { fprintf(stderr, "Can't find password entry for \"%s\"\n", name); exit(1); } if (!(setgid(ent->pw_gid) || setuid(ent->pw_uid))) { #ifndef scs /* { BSD 4.2 */ putenv(ps1); #endif /* } */ if (ac == 1) if(shell = getenv("SHELL")) rslt = execl(shell, shell, (char *)0L); else rslt = execl("/bin/sh", "sh", (char *)(0L)); else { rslt = execvp(av[1], av + 1); } fprintf(stderr, "Error in %s: ", argv[0]); perror(""); } else { fprintf(stderr, "%s setuid failed - ", argv[0]); perror(""); } /* man execl: If any of the exec() functions returns, an error will have occurred. The return value is -1, and the global variable errno will be set to indicate the error. */ exit(rslt) ; }