1 /*- 2 * Copyright (c) 2012 Dag-Erling Smørgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote 14 * products derived from this software without specific prior written 15 * permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $OpenPAM: openpam_straddch.c 938 2017-04-30 21:34:42Z des $ 30 */ 31 32 #ifdef HAVE_CONFIG_H 33 # include "config.h" 34 #endif 35 36 #include <errno.h> 37 #include <stdlib.h> 38 39 #include <security/pam_appl.h> 40 41 #include "openpam_impl.h" 42 43 #define MIN_STR_SIZE 32 44 45 /* 46 * OpenPAM extension 47 * 48 * Add a character to a string, expanding the buffer if needed. 49 */ 50 51 int 52 openpam_straddch(char **str, size_t *size, size_t *len, int ch) 53 { 54 size_t tmpsize; 55 char *tmpstr; 56 57 if (*str == NULL) { 58 /* initial allocation */ 59 tmpsize = MIN_STR_SIZE; 60 if ((tmpstr = malloc(tmpsize)) == NULL) { 61 openpam_log(PAM_LOG_ERROR, "malloc(): %m"); 62 errno = ENOMEM; 63 return (-1); 64 } 65 *str = tmpstr; 66 *size = tmpsize; 67 *len = 0; 68 } else if (ch != 0 && *len + 1 >= *size) { 69 /* additional space required */ 70 tmpsize = *size * 2; 71 if ((tmpstr = realloc(*str, tmpsize)) == NULL) { 72 openpam_log(PAM_LOG_ERROR, "realloc(): %m"); 73 errno = ENOMEM; 74 return (-1); 75 } 76 *size = tmpsize; 77 *str = tmpstr; 78 } 79 if (ch != 0) { 80 (*str)[*len] = ch; 81 ++*len; 82 } 83 (*str)[*len] = '\0'; 84 return (0); 85 } 86 87 /** 88 * The =openpam_straddch function appends a character to a dynamically 89 * allocated NUL-terminated buffer, reallocating the buffer as needed. 90 * 91 * The =str argument points to a variable containing either a pointer to 92 * an existing buffer or =NULL. 93 * If the value of the variable pointed to by =str is =NULL, a new buffer 94 * is allocated. 95 * 96 * The =size and =len argument point to variables used to hold the size 97 * of the buffer and the length of the string it contains, respectively. 98 * 99 * The final argument, =ch, is the character that should be appended to 100 * the string. If =ch is 0, nothing is appended, but a new buffer is 101 * still allocated if =str is NULL. This can be used to "bootstrap" the 102 * string. 103 * 104 * If a new buffer is allocated or an existing buffer is reallocated to 105 * make room for the additional character, =str and =size are updated 106 * accordingly. 107 * 108 * The =openpam_straddch function ensures that the buffer is always 109 * NUL-terminated. 110 * 111 * If the =openpam_straddch function is successful, it increments the 112 * integer variable pointed to by =len (unless =ch was 0) and returns 0. 113 * Otherwise, it leaves the variables pointed to by =str, =size and =len 114 * unmodified, sets :errno to =ENOMEM and returns -1. 115 * 116 * AUTHOR DES 117 */ 118