1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 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. */ 33int 34lutil_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 *) ber_memalloc( passwd->bv_len + 1 ); 66 if( passwd->bv_val == NULL ) { 67 perror( filename ); 68 fclose( f ); 69 return -1; 70 } 71 72 nread = 0; 73 nleft = passwd->bv_len; 74 do { 75 if( nleft == 0 ) { 76 /* double the buffer size */ 77 char *p = (char *) ber_memrealloc( passwd->bv_val, 78 2 * passwd->bv_len + 1 ); 79 if( p == NULL ) { 80 ber_memfree( passwd->bv_val ); 81 passwd->bv_val = NULL; 82 passwd->bv_len = 0; 83 fclose( f ); 84 return -1; 85 } 86 nleft = passwd->bv_len; 87 passwd->bv_len *= 2; 88 passwd->bv_val = p; 89 } 90 91 nr = fread( &passwd->bv_val[nread], 1, nleft, f ); 92 93 if( nr < nleft && ferror( f ) ) { 94 ber_memfree( passwd->bv_val ); 95 passwd->bv_val = NULL; 96 passwd->bv_len = 0; 97 fclose( f ); 98 return -1; 99 } 100 101 nread += nr; 102 nleft -= nr; 103 } while ( !feof(f) ); 104 105 passwd->bv_len = nread; 106 passwd->bv_val[nread] = '\0'; 107 108 fclose( f ); 109 return 0; 110} 111