1/* $NetBSD: passfile.c,v 1.3 2021/08/14 16:14:58 christos Exp $ */ 2 3/* $OpenLDAP$ */ 4/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2021 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 <sys/cdefs.h> 19__RCSID("$NetBSD: passfile.c,v 1.3 2021/08/14 16:14:58 christos Exp $"); 20 21#include "portable.h" 22 23#include <stdio.h> 24 25#include <ac/stdlib.h> 26#include <ac/ctype.h> 27#include <ac/string.h> 28 29#ifdef HAVE_FSTAT 30#include <sys/types.h> 31#include <sys/stat.h> 32#endif /* HAVE_FSTAT */ 33 34#include <lber.h> 35#include <lutil.h> 36 37/* Get a password from a file. */ 38int 39lutil_get_filed_password( 40 const char *filename, 41 struct berval *passwd ) 42{ 43 size_t nread, nleft, nr; 44 FILE *f = fopen( filename, "r" ); 45 46 if( f == NULL ) { 47 perror( filename ); 48 return -1; 49 } 50 51 passwd->bv_val = NULL; 52 passwd->bv_len = 4096; 53 54#ifdef HAVE_FSTAT 55 { 56 struct stat sb; 57 if ( fstat( fileno( f ), &sb ) == 0 ) { 58 if( sb.st_mode & 006 ) { 59 fprintf( stderr, _("Warning: Password file %s" 60 " is publicly readable/writeable\n"), 61 filename ); 62 } 63 64 if ( sb.st_size ) 65 passwd->bv_len = sb.st_size; 66 } 67 } 68#endif /* HAVE_FSTAT */ 69 70 passwd->bv_val = (char *) ber_memalloc( passwd->bv_len + 1 ); 71 if( passwd->bv_val == NULL ) { 72 perror( filename ); 73 fclose( f ); 74 return -1; 75 } 76 77 nread = 0; 78 nleft = passwd->bv_len; 79 do { 80 if( nleft == 0 ) { 81 /* double the buffer size */ 82 char *p = (char *) ber_memrealloc( passwd->bv_val, 83 2 * passwd->bv_len + 1 ); 84 if( p == NULL ) { 85 ber_memfree( passwd->bv_val ); 86 passwd->bv_val = NULL; 87 passwd->bv_len = 0; 88 fclose( f ); 89 return -1; 90 } 91 nleft = passwd->bv_len; 92 passwd->bv_len *= 2; 93 passwd->bv_val = p; 94 } 95 96 nr = fread( &passwd->bv_val[nread], 1, nleft, f ); 97 98 if( nr < nleft && ferror( f ) ) { 99 ber_memfree( passwd->bv_val ); 100 passwd->bv_val = NULL; 101 passwd->bv_len = 0; 102 fclose( f ); 103 return -1; 104 } 105 106 nread += nr; 107 nleft -= nr; 108 } while ( !feof(f) ); 109 110 passwd->bv_len = nread; 111 passwd->bv_val[nread] = '\0'; 112 113 fclose( f ); 114 return 0; 115} 116