xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblutil/passfile.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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