openpam_readline.c revision 236099
1115619Sdes/*-
2115619Sdes * Copyright (c) 2003 Networks Associates Technology, Inc.
3228690Sdes * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav
4115619Sdes * All rights reserved.
5115619Sdes *
6115619Sdes * This software was developed for the FreeBSD Project by ThinkSec AS and
7115619Sdes * Network Associates Laboratories, the Security Research Division of
8115619Sdes * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
9115619Sdes * ("CBOSS"), as part of the DARPA CHATS research program.
10115619Sdes *
11115619Sdes * Redistribution and use in source and binary forms, with or without
12115619Sdes * modification, are permitted provided that the following conditions
13115619Sdes * are met:
14115619Sdes * 1. Redistributions of source code must retain the above copyright
15115619Sdes *    notice, this list of conditions and the following disclaimer.
16115619Sdes * 2. Redistributions in binary form must reproduce the above copyright
17115619Sdes *    notice, this list of conditions and the following disclaimer in the
18115619Sdes *    documentation and/or other materials provided with the distribution.
19115619Sdes * 3. The name of the author may not be used to endorse or promote
20115619Sdes *    products derived from this software without specific prior written
21115619Sdes *    permission.
22115619Sdes *
23115619Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24115619Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25115619Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26115619Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27115619Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28115619Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29115619Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30115619Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31115619Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32115619Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33115619Sdes * SUCH DAMAGE.
34115619Sdes *
35236099Sdes * $Id: openpam_readline.c 596 2012-04-14 14:52:40Z des $
36115619Sdes */
37115619Sdes
38228690Sdes#ifdef HAVE_CONFIG_H
39228690Sdes# include "config.h"
40228690Sdes#endif
41228690Sdes
42115619Sdes#include <ctype.h>
43115619Sdes#include <stdio.h>
44115619Sdes#include <stdlib.h>
45115619Sdes
46115619Sdes#include <security/pam_appl.h>
47236099Sdes
48115619Sdes#include "openpam_impl.h"
49115619Sdes
50115619Sdes#define MIN_LINE_LENGTH 128
51115619Sdes
52115619Sdes/*
53115619Sdes * OpenPAM extension
54115619Sdes *
55115619Sdes * Read a line from a file.
56115619Sdes */
57115619Sdes
58115619Sdeschar *
59115619Sdesopenpam_readline(FILE *f, int *lineno, size_t *lenp)
60115619Sdes{
61168463Sdes	char *line;
62115619Sdes	size_t len, size;
63115619Sdes	int ch;
64115619Sdes
65236099Sdes	if ((line = malloc(size = MIN_LINE_LENGTH)) == NULL) {
66236099Sdes		openpam_log(PAM_LOG_ERROR, "malloc(): %m");
67115619Sdes		return (NULL);
68236099Sdes	}
69115619Sdes	len = 0;
70115619Sdes	for (;;) {
71115619Sdes		ch = fgetc(f);
72115619Sdes		/* strip comment */
73115619Sdes		if (ch == '#') {
74115619Sdes			do {
75115619Sdes				ch = fgetc(f);
76115619Sdes			} while (ch != EOF && ch != '\n');
77115619Sdes		}
78115619Sdes		/* eof */
79115619Sdes		if (ch == EOF) {
80228690Sdes			/* done */
81115619Sdes			break;
82115619Sdes		}
83115619Sdes		/* eol */
84115619Sdes		if (ch == '\n') {
85115619Sdes			if (lineno != NULL)
86115619Sdes				++*lineno;
87115619Sdes			/* skip blank lines */
88115619Sdes			if (len == 0)
89115619Sdes				continue;
90115619Sdes			/* continuation */
91115619Sdes			if (line[len - 1] == '\\') {
92115619Sdes				line[--len] = '\0';
93228690Sdes				continue;
94115619Sdes			}
95228690Sdes			/* done */
96228690Sdes			break;
97115619Sdes		}
98115619Sdes		/* anything else */
99236099Sdes		if (openpam_straddch(&line, &size, &len, ch) != 0)
100236099Sdes			goto fail;
101115619Sdes	}
102228690Sdes	if (len == 0)
103228690Sdes		goto fail;
104115619Sdes	if (lenp != NULL)
105115619Sdes		*lenp = len;
106236099Sdes	openpam_log(PAM_LOG_LIBDEBUG, "returning '%s'", line);
107115619Sdes	return (line);
108228690Sdesfail:
109115619Sdes	FREE(line);
110115619Sdes	return (NULL);
111115619Sdes}
112115619Sdes
113115619Sdes/**
114236099Sdes * DEPRECATED openpam_readlinev
115236099Sdes *
116115619Sdes * The =openpam_readline function reads a line from a file, and returns it
117236099Sdes * in a NUL-terminated buffer allocated with =!malloc.
118115619Sdes *
119115619Sdes * The =openpam_readline function performs a certain amount of processing
120228690Sdes * on the data it reads:
121115619Sdes *
122236099Sdes *  - Comments (introduced by a hash sign) are stripped.
123236099Sdes *
124228690Sdes *  - Blank lines are ignored.
125236099Sdes *
126228690Sdes *  - If a line ends in a backslash, the backslash is stripped and the
127228690Sdes *    next line is appended.
128228690Sdes *
129115619Sdes * If =lineno is not =NULL, the integer variable it points to is
130115619Sdes * incremented every time a newline character is read.
131115619Sdes *
132115619Sdes * If =lenp is not =NULL, the length of the line (not including the
133115619Sdes * terminating NUL character) is stored in the variable it points to.
134115619Sdes *
135115619Sdes * The caller is responsible for releasing the returned buffer by passing
136236099Sdes * it to =!free.
137236099Sdes *
138236099Sdes * >openpam_readlinev
139236099Sdes * >openpam_readword
140115619Sdes */
141