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