xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblutil/passfile.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1*549b59edSchristos /*	$NetBSD: passfile.c,v 1.3 2021/08/14 16:14:58 christos Exp $	*/
24e6df137Slukem 
3d11b170bStron /* $OpenLDAP$ */
42de962bdSlukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
52de962bdSlukem  *
6*549b59edSchristos  * Copyright 1998-2021 The OpenLDAP Foundation.
72de962bdSlukem  * All rights reserved.
82de962bdSlukem  *
92de962bdSlukem  * Redistribution and use in source and binary forms, with or without
102de962bdSlukem  * modification, are permitted only as authorized by the OpenLDAP
112de962bdSlukem  * Public License.
122de962bdSlukem  *
132de962bdSlukem  * A copy of this license is available in the file LICENSE in the
142de962bdSlukem  * top-level directory of the distribution or, alternatively, at
152de962bdSlukem  * <http://www.OpenLDAP.org/license.html>.
162de962bdSlukem  */
172de962bdSlukem 
18376af7d7Schristos #include <sys/cdefs.h>
19*549b59edSchristos __RCSID("$NetBSD: passfile.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
20376af7d7Schristos 
212de962bdSlukem #include "portable.h"
222de962bdSlukem 
232de962bdSlukem #include <stdio.h>
242de962bdSlukem 
252de962bdSlukem #include <ac/stdlib.h>
262de962bdSlukem #include <ac/ctype.h>
272de962bdSlukem #include <ac/string.h>
282de962bdSlukem 
292de962bdSlukem #ifdef HAVE_FSTAT
302de962bdSlukem #include <sys/types.h>
312de962bdSlukem #include <sys/stat.h>
322de962bdSlukem #endif /* HAVE_FSTAT */
332de962bdSlukem 
342de962bdSlukem #include <lber.h>
352de962bdSlukem #include <lutil.h>
362de962bdSlukem 
372de962bdSlukem /* Get a password from a file. */
382de962bdSlukem int
lutil_get_filed_password(const char * filename,struct berval * passwd)392de962bdSlukem lutil_get_filed_password(
402de962bdSlukem 	const char *filename,
412de962bdSlukem 	struct berval *passwd )
422de962bdSlukem {
432de962bdSlukem 	size_t nread, nleft, nr;
442de962bdSlukem 	FILE *f = fopen( filename, "r" );
452de962bdSlukem 
462de962bdSlukem 	if( f == NULL ) {
472de962bdSlukem 		perror( filename );
482de962bdSlukem 		return -1;
492de962bdSlukem 	}
502de962bdSlukem 
512de962bdSlukem 	passwd->bv_val = NULL;
522de962bdSlukem 	passwd->bv_len = 4096;
532de962bdSlukem 
542de962bdSlukem #ifdef HAVE_FSTAT
552de962bdSlukem 	{
562de962bdSlukem 		struct stat sb;
572de962bdSlukem 		if ( fstat( fileno( f ), &sb ) == 0 ) {
582de962bdSlukem 			if( sb.st_mode & 006 ) {
592de962bdSlukem 				fprintf( stderr, _("Warning: Password file %s"
602de962bdSlukem 					" is publicly readable/writeable\n"),
612de962bdSlukem 					filename );
622de962bdSlukem 			}
632de962bdSlukem 
642de962bdSlukem 			if ( sb.st_size )
652de962bdSlukem 				passwd->bv_len = sb.st_size;
662de962bdSlukem 		}
672de962bdSlukem 	}
682de962bdSlukem #endif /* HAVE_FSTAT */
692de962bdSlukem 
704e6df137Slukem 	passwd->bv_val = (char *) ber_memalloc( passwd->bv_len + 1 );
712de962bdSlukem 	if( passwd->bv_val == NULL ) {
722de962bdSlukem 		perror( filename );
73d11b170bStron 		fclose( f );
742de962bdSlukem 		return -1;
752de962bdSlukem 	}
762de962bdSlukem 
772de962bdSlukem 	nread = 0;
782de962bdSlukem 	nleft = passwd->bv_len;
792de962bdSlukem 	do {
802de962bdSlukem 		if( nleft == 0 ) {
812de962bdSlukem 			/* double the buffer size */
824e6df137Slukem 			char *p = (char *) ber_memrealloc( passwd->bv_val,
832de962bdSlukem 				2 * passwd->bv_len + 1 );
842de962bdSlukem 			if( p == NULL ) {
854e6df137Slukem 				ber_memfree( passwd->bv_val );
862de962bdSlukem 				passwd->bv_val = NULL;
872de962bdSlukem 				passwd->bv_len = 0;
88d11b170bStron 				fclose( f );
892de962bdSlukem 				return -1;
902de962bdSlukem 			}
912de962bdSlukem 			nleft = passwd->bv_len;
922de962bdSlukem 			passwd->bv_len *= 2;
932de962bdSlukem 			passwd->bv_val = p;
942de962bdSlukem 		}
952de962bdSlukem 
962de962bdSlukem 		nr = fread( &passwd->bv_val[nread], 1, nleft, f );
972de962bdSlukem 
982de962bdSlukem 		if( nr < nleft && ferror( f ) ) {
994e6df137Slukem 			ber_memfree( passwd->bv_val );
1002de962bdSlukem 			passwd->bv_val = NULL;
1012de962bdSlukem 			passwd->bv_len = 0;
102d11b170bStron 			fclose( f );
1032de962bdSlukem 			return -1;
1042de962bdSlukem 		}
1052de962bdSlukem 
1062de962bdSlukem 		nread += nr;
1072de962bdSlukem 		nleft -= nr;
1082de962bdSlukem 	} while ( !feof(f) );
1092de962bdSlukem 
1102de962bdSlukem 	passwd->bv_len = nread;
1112de962bdSlukem 	passwd->bv_val[nread] = '\0';
1122de962bdSlukem 
1132de962bdSlukem 	fclose( f );
1142de962bdSlukem 	return 0;
1152de962bdSlukem }
116