1 /* $OpenLDAP: pkg/ldap/libraries/liblutil/passfile.c,v 1.8.2.3 2008/02/11 23:26:42 kurt Exp $ */ 2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2008 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15 16 #include "portable.h" 17 18 #include <stdio.h> 19 20 #include <ac/stdlib.h> 21 #include <ac/ctype.h> 22 #include <ac/string.h> 23 24 #ifdef HAVE_FSTAT 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #endif /* HAVE_FSTAT */ 28 29 #include <lber.h> 30 #include <lutil.h> 31 32 /* Get a password from a file. */ 33 int 34 lutil_get_filed_password( 35 const char *filename, 36 struct berval *passwd ) 37 { 38 size_t nread, nleft, nr; 39 FILE *f = fopen( filename, "r" ); 40 41 if( f == NULL ) { 42 perror( filename ); 43 return -1; 44 } 45 46 passwd->bv_val = NULL; 47 passwd->bv_len = 4096; 48 49 #ifdef HAVE_FSTAT 50 { 51 struct stat sb; 52 if ( fstat( fileno( f ), &sb ) == 0 ) { 53 if( sb.st_mode & 006 ) { 54 fprintf( stderr, _("Warning: Password file %s" 55 " is publicly readable/writeable\n"), 56 filename ); 57 } 58 59 if ( sb.st_size ) 60 passwd->bv_len = sb.st_size; 61 } 62 } 63 #endif /* HAVE_FSTAT */ 64 65 passwd->bv_val = (char *) malloc( passwd->bv_len + 1 ); 66 if( passwd->bv_val == NULL ) { 67 perror( filename ); 68 return -1; 69 } 70 71 nread = 0; 72 nleft = passwd->bv_len; 73 do { 74 if( nleft == 0 ) { 75 /* double the buffer size */ 76 char *p = (char *) realloc( passwd->bv_val, 77 2 * passwd->bv_len + 1 ); 78 if( p == NULL ) { 79 free( passwd->bv_val ); 80 passwd->bv_val = NULL; 81 passwd->bv_len = 0; 82 return -1; 83 } 84 nleft = passwd->bv_len; 85 passwd->bv_len *= 2; 86 passwd->bv_val = p; 87 } 88 89 nr = fread( &passwd->bv_val[nread], 1, nleft, f ); 90 91 if( nr < nleft && ferror( f ) ) { 92 free( passwd->bv_val ); 93 passwd->bv_val = NULL; 94 passwd->bv_len = 0; 95 return -1; 96 } 97 98 nread += nr; 99 nleft -= nr; 100 } while ( !feof(f) ); 101 102 passwd->bv_len = nread; 103 passwd->bv_val[nread] = '\0'; 104 105 fclose( f ); 106 return 0; 107 } 108