diff options
author | Timo Weingärtner <timo@tiwe.de> | 2013-04-29 13:06:26 +0200 |
---|---|---|
committer | Timo Weingärtner <timo@tiwe.de> | 2013-05-12 18:44:18 +0200 |
commit | 138c589dd4cdf68659bfa643e5659fa1200f6081 (patch) | |
tree | cebb8c42cf51cfc0397942a948c872ebc819090f /pam_pwdfile.c | |
parent | 0437f4656f1d5a541b4ab951c457fae19f8deee4 (diff) | |
download | libpam-pwdfile-138c589dd4cdf68659bfa643e5659fa1200f6081.tar.gz |
rework pwdfile reading
* drop rewind(), we read the file just once
* use getline() to get rid of the fixed-size buffer
* let strsep() also handle the newline
* stop at the first line containing the user instead of using the last
Diffstat (limited to 'pam_pwdfile.c')
-rw-r--r-- | pam_pwdfile.c | 60 |
1 files changed, 25 insertions, 35 deletions
diff --git a/pam_pwdfile.c b/pam_pwdfile.c index cd4d941..80cd893 100644 --- a/pam_pwdfile.c +++ b/pam_pwdfile.c @@ -91,43 +91,33 @@ static int lock_fd(int fd) { * if unsucessful, returns 0 */ static int fgetpwnam(FILE *stream, const char *name, char *password) { - char tempLine[256], *tpointer, *curname, *curpass, *fgr; - int loopdone, pwdfound; - int len; + char * linebuf = NULL; + size_t linebuflen; + int pwdfound = 0; - /* go to beginning of file */ - rewind(stream); - /* some control variables */ - loopdone = pwdfound = 0; - /* fgets should do this, but we make sure */ - tempLine[255] = '\0'; /* iterate through lines in file, until end of file */ - do { - /* get the current line */ - fgr = fgets(tempLine,255,stream); - /* if it's valid, go on */ - if ( fgr != NULL) { - /* first get the username out */ - tpointer = tempLine; - curname = strsep(&tpointer,":"); - /* check to see if it's the right one */ - if (strcmp(curname,name)==0) { - /* at least we know our loop is done */ - loopdone = 1; - /* remove possible trailing newline */ - len = strlen(tpointer); - if (tpointer[len - 1] == '\n') - tpointer[len - 1] = '\0'; - /* get the password and put it in its place */ - curpass = strsep(&tpointer,":"); - if (curpass != NULL) { - /* we use bigcrypt pwd len, as this is just a safe maximum */ - strncpy(password,curpass,CRYPTED_BCPWD_LEN+1); - pwdfound = 1; - } /* if (curpass... */ - } /* if (strcmp(curname... */ - } /* if (tempLine... */ - } while (fgr != NULL); + while (getline(&linebuf, &linebuflen, stream) > 0) { + /* strsep changes its argument, make a copy */ + char * nexttok = linebuf; + + /* first field: username */ + char * curtok = strsep(&nexttok, ":"); + + /* skip non-matchin usernames */ + if (strcmp(curtok, name)) + continue; + + /* second field: password (until next colon or newline) */ + curtok = strsep(&nexttok, ":\n"); + + if (curtok) { + /* we use bigcrypt pwd len, as this is just a safe maximum */ + strncpy(password, curtok, CRYPTED_BCPWD_LEN + 1); + pwdfound = 1; + break; + } + } + free(linebuf); /* allocated by getline */ return pwdfound; } |