/* * Passwd.c for MiNT version 0.2 (c) S.R.Usher 1991/92. */ #define TMP_FILE "/etc/pwtmp" #include #include #include #include struct passwd *pswdent, dummy; struct sgttyb orig, noecho; char *fcrypt(); static char *default_host = "this machine"; main(argc, argv) int argc; char *argv[]; { int i, nopasswd = 0, oktologin = 0, noentry = 0; int preserve, name_in_argv; char name[80], oldpassword[80], newpassword1[80], newpassword2[80]; char objecttype[5], object[20], hostname[80]; #if defined(atarist) && defined (PASSWD_FILE) setpwfile(PASSWD_FILE); #else #ifndef PASSWD_FILE #define PASSWD_FILE "/etc/passwd" #endif #endif ioctl(fileno(stdin), TIOCGETP, &orig); ioctl(fileno(stdin), TIOCGETP, &noecho); noecho.sg_flags &= ~ECHO; if (parse_args(argc, argv, name, &preserve) == 0) { fail(name); } #ifndef MINT /* Oh dear.. mntlib16 doesn't have these! */ seteuid(0); setegid(0); #else setuid(0); setgid(0); #endif pswdent = getpwnam(name); if (pswdent == NULL) { pswdent = &dummy; pswdent->pw_passwd = "\0"; oktologin = 0; noentry = 1; printf("%s: %s: unknown user.\n", argv[0], name); exit(1); } else { if (strlen(pswdent->pw_passwd) == 0) { nopasswd = 1; oktologin = 1; #ifdef DEBUG printf("Ooer! No password! (%s)\n", pswdent->pw_passwd); #endif } noentry = 0; } gethostname(hostname, 79); if (strcmp("local", hostname) == 0) strcpy(hostname, default_host); strcpy(object, "password"); printf("Changing %s for %s on %s.\n", object, pswdent->pw_name, hostname); if (nopasswd == 0) { ioctl(fileno(stdin), TIOCSETP, &noecho); printf("Old password:"); fflush(stdout); gets(oldpassword); printf("\n"); ioctl(fileno(stdin), TIOCSETP, &orig); if ((check_passwd((char *)(fcrypt(oldpassword, "su") +2L), pswdent->pw_passwd) == 1) && (noentry == 0)) oktologin = 1; } endpwent(); if (!oktologin) { printf("Sorry.\n"); exit(1); } if ((oktologin == 1) && (noentry == 0)) { ioctl(fileno(stdin), TIOCSETP, &noecho); retry: printf("New password:"); fflush(stdout); gets(newpassword1); printf("\n"); if (strlen(newpassword1) < 6) { ioctl(fileno(stdin), TIOCSETP, &orig); printf("Please use a longer password.\n"); goto retry; } printf("Retype new password:"); fflush(stdout); gets(newpassword2); printf("\n"); ioctl(fileno(stdin), TIOCSETP, &orig); if (strcmp(newpassword1, newpassword2) == 0) { static char newbuf[16]; strcpy(newbuf, (char *)(fcrypt(newpassword1, "su") + 2L)); pswdent->pw_passwd = newbuf; setpwnam(name, pswdent); } else { printf("Mismatch - password unchanged.\n"); exit(1); } } else fail(name); } check_passwd(given_pw, encrypted_pw) char *given_pw; char *encrypted_pw; { if ((strncmp(given_pw, encrypted_pw, strlen(given_pw)) == 0) && (strlen(given_pw) == strlen(encrypted_pw))) return 1; else return 0; } parse_args(argc, argv, name, preserve) int argc; char *argv[]; char *name; { register int i = 1, j, retval; if (argc < 2) { strcpy(name, getenv("USER")); return 1; } if (argc > 3) usage(argv); if (i < argc) { if ((j = strlen(argv[i])) > 8) j = 8; strncpy(name, argv[i], j); name[8] = '\0'; } if (getuid()) { return 0; } else { return 1; } } usage(argv) char *argv[]; { fprintf(stderr, "Usage: %s [-p] [name]\n", argv[0]); exit(0); } getstring(string) char *string; { register int i, c; *string = '\0'; for (i = 0; (c = fgetc(stdin)) != '\n'; i++) { if ((c == '\004') || (c == EOF)) { printf("^D\n"); return EOF; } if (c < 32) printf("^%c", (c + 0x40)); string[i] = c; } string[i] = '\0'; return 0; } fail(name) char *name; { char hostname[80]; gethostname(hostname, 79); fprintf(stderr, "Can't change password for %s on %s\n", name, hostname); exit(1); } setpwnam(name, entry) char *name; struct passwd *entry; { FILE *fp1, *fp2; char record[256], testnam[80]; if ((fp1 = fopen(PASSWD_FILE, "r")) == NULL) fail(name); if ((fp2 = fopen(TMP_FILE, "w")) == NULL) { fclose(fp1); fail(name); } while(fgets(record, 1024, fp1) != NULL) { sscanf(record, "%s:", testnam); if (strncmp(testnam, name, strlen(name)) == 0) create_entry(fp2, entry); else fwrite(record, strlen(record), 1, fp2); } fclose(fp1); fclose(fp2); if (unlink(PASSWD_FILE)) { #ifdef DEBUG perror(PASSWD_FILE); #endif fail(name); } if (rename(TMP_FILE, PASSWD_FILE)) { #ifdef DEBUG perror(TMP_FILE); #endif fail(name); } } create_entry(file, entry) FILE *file; struct passwd *entry; { fprintf(file, "%s:%s:%d:%d:%s:%s:%s\n", entry->pw_name, entry->pw_passwd, entry->pw_uid, entry->pw_gid, entry->pw_gecos, entry->pw_dir, entry->pw_shell); fflush(file); }