/* vi: set sw=4 ts=4 : * pwdutils.c - password read/update helper functions. * * Copyright 2012 Ashwini Kumar */ #include "toys.h" #include int read_password(char * buff, int buflen, char* mesg) { int i = 0; struct termios termio, oldtermio; tcgetattr(0, &oldtermio); tcflush(0, TCIFLUSH); termio = oldtermio; termio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); termio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); tcsetattr(0, TCSANOW, &termio); fputs(mesg, stdout); fflush(stdout); while (1) { int ret = read(0, &buff[i], 1); if ( ret < 0 ) { buff[0] = 0; tcsetattr(0, TCSANOW, &oldtermio); return 1; } else if ( ret == 0 || buff[i] == '\n' || buff[i] == '\r' || buflen == i+1) { buff[i] = '\0'; break; } i++; } tcsetattr(0, TCSANOW, &oldtermio); puts(""); fflush(stdout); return 0; } static char *get_nextcolon(const char *line, char delim) { char *current_ptr = NULL; if((current_ptr = strchr(line, ':')) == NULL) error_exit("Invalid Entry\n"); return current_ptr; } int update_password(char *filename, char* username, char* encrypted) { char *filenamesfx = NULL, *namesfx = NULL; char *shadow = NULL, *sfx = NULL; FILE *exfp, *newfp; int ret = -1; //fail struct flock lock; char *line = NULL; shadow = strstr(filename, "shadow"); filenamesfx = xmsprintf("%s+", filename); sfx = strchr(filenamesfx, '+'); exfp = fopen(filename, "r+"); if(!exfp) { perror_msg("Couldn't open file %s",filename); goto free_storage; } *sfx = '-'; ret = unlink(filenamesfx); ret = link(filename, filenamesfx); if(ret < 0) error_msg("can't create backup file"); *sfx = '+'; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; ret = fcntl(fileno(exfp), F_SETLK, &lock); if(ret < 0) perror_msg("Couldn't lock file %s",filename); lock.l_type = F_UNLCK; //unlocking at a later stage newfp = fopen(filenamesfx, "w+"); if(!newfp) { error_msg("couldn't open file for writing"); ret = -1; fclose(exfp); goto free_storage; } ret = 0; namesfx = xmsprintf("%s:",username); while((line = get_line(fileno(exfp))) != NULL) { if(strncmp(line, namesfx, strlen(namesfx)) != 0) fprintf(newfp, "%s\n", line); else { char *current_ptr = NULL; fprintf(newfp, "%s%s:",namesfx,encrypted); current_ptr = get_nextcolon(line, ':'); //past username current_ptr++; //past colon ':' after username current_ptr = get_nextcolon(current_ptr, ':'); //past passwd current_ptr++; //past colon ':' after passwd if(shadow) { fprintf(newfp, "%u:",(unsigned)(time(NULL))/(24*60*60)); current_ptr = get_nextcolon(current_ptr, ':'); current_ptr++; //past time stamp colon. fprintf(newfp, "%s\n",current_ptr); } else { fprintf(newfp, "%s\n",current_ptr); } } free(line); } free(namesfx); fcntl(fileno(exfp), F_SETLK, &lock); fclose(exfp); errno = 0; fflush(newfp); fsync(fileno(newfp)); fclose(newfp); rename(filenamesfx, filename); if(errno) { perror_msg("File Writing/Saving failed: "); unlink(filenamesfx); ret = -1; } free_storage: free(filenamesfx); return ret; }