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. */
38 int
lutil_get_filed_password(const char * filename,struct berval * passwd)39 lutil_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