/* * SPDsoft * CAP make user * * IRIX 6.2, Wed Apr 15 21:03:03 DST 1998 */ #include #include #include #include #include #include #include #include #include #include #ifdef _BSD_ extern char *sys_errlist[]; # define raise(s) kill(getpid(),(s)) # define strerror(e) sys_errlist[(e)] extern char *crypt( char *key, char *salt); extern char *getpass( char *prompt); #endif #ifndef AUFSMKUSR # define AUFSMKUSR "/usr/local/cap/bin/aufsmkusr" #endif char __ident[] = "@(#)(c)SPDsoft, Wed Apr 15, 1998"; extern char *safepwd(struct passwd *pwd, char *pass); void output(const char *fmt, ...); int main(int argc, char **argv, char **envp); int main(int argc, char **argv, char **envp) { register char **p1, **p2; int fd[2]; int pid; int st; int error; char s[256]; char user[256]; char *msg; char *path="PATH=/bin:/usr/bin:/etc"; char *pass; char pass1[9]; char pass2[9]; struct passwd *pwd; char *cmd[]={AUFSMKUSR, "-f", "-", 0x00 }; extern int errno; if ( argc != 1 ) { fprintf(stderr,"%s: %s\n", argv[0], ((char*)&__ident[4])); fprintf(stderr,"Usage: %s\n", argv[0] ); exit(-1); } if ( NULL == ( pwd = getpwuid ( getuid () ))) { output("getpwuid failed for %s (%s)", getuid(), strerror(errno) ); error = errno; } else { sprintf(s, "%s's CAP new password? ", pwd->pw_name); if ( NULL == (pass = getpass(s))) { output( "getpass failed for %s (%s)", pwd->pw_name, strerror(errno)); error = errno; exit(1); } strncpy(pass1, pass, sizeof(pass1)); pass1[8]=0x00; sprintf(s, "%s's CAP new password again? ", pwd->pw_name); if ( NULL == (pass = getpass(s))) { output( "getpass failed for %s (%s)", pwd->pw_name, strerror(errno)); error = errno; exit(1); } strncpy(pass2, pass, sizeof(pass2)); pass2[8]=0x00; if ( 0 != strcmp( pass1, pass2 )) { output( "they don't match, bye\n" ); exit(3); } if ( NULL != ( msg = safepwd( pwd, pass1 ))) { output("%s\n",msg); exit(4); } else { /* * open a pipe to aufsmkusr */ if ( -1 == pipe(fd)) { output( "pipe failed (%s)\n", strerror(errno)); exit(5); } switch ( pid = fork () ) { case -1: output( "can't fork: %s (%s)\n", pwd->pw_name, strerror(errno)); exit(3); break; case 0: /* son */ close(0); dup(fd[0]); close(fd[1]); if( (error = setuid((uid_t) 0L)) != 0 ) { output( "setuid failed for %s (%s)\n", pwd->pw_name, strerror(errno)); error = errno; } else { void (*sys)(int); if ( 0 != putenv ( path )) { output( "putenv failed for %s (%s)\n", pwd->pw_name, strerror(errno)); error = errno; } else { for(p1 = p2 = envp; *p1; p1++) { if (strncmp(*p1, "LD_", 3) != 0 && strncmp(*p1, "_RLD", 4) != 0 && strncmp(*p1, "LIBPATH=", 8) != 0 && strncmp(*p1, "ELF_LD_", 7) != 0 && strncmp(*p1, "AOUT_LD_", 8) != 0 && strncmp(*p1, "IFS=", 4) != 0 ) { *p2++ = *p1; } } *p2 = 0; execve( cmd[0], cmd, p2 ); perror( "exec" ); } } exit(255); break; default: close(1); dup(fd[1]); close(fd[0]); fprintf(stdout,"%s \"%s\"\n", pwd->pw_name, pass1 ); fflush(stdout); close(1); close(fd[1]); wait(&st); break; } } } exit(error); } void output(const char *fmt, ...) { char StrTmp[1024]; va_list vl; va_start(vl,fmt); vsprintf(StrTmp, fmt, vl); va_end(vl); fprintf(stderr, StrTmp); }