1228690Sdes/*- 2228690Sdes * Copyright (c) 2011 Dag-Erling Sm��rgrav 3228690Sdes * All rights reserved. 4228690Sdes * 5228690Sdes * Redistribution and use in source and binary forms, with or without 6228690Sdes * modification, are permitted provided that the following conditions 7228690Sdes * are met: 8228690Sdes * 1. Redistributions of source code must retain the above copyright 9255376Sdes * notice, this list of conditions and the following disclaimer. 10228690Sdes * 2. Redistributions in binary form must reproduce the above copyright 11228690Sdes * notice, this list of conditions and the following disclaimer in the 12228690Sdes * documentation and/or other materials provided with the distribution. 13236099Sdes * 3. The name of the author may not be used to endorse or promote 14236099Sdes * products derived from this software without specific prior written 15236099Sdes * permission. 16228690Sdes * 17228690Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18228690Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19228690Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20228690Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21228690Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22228690Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23228690Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24228690Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25228690Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26228690Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27228690Sdes * SUCH DAMAGE. 28228690Sdes * 29255376Sdes * $Id: openpam_subst.c 648 2013-03-05 17:54:27Z des $ 30228690Sdes */ 31228690Sdes 32228690Sdes#ifdef HAVE_CONFIG_H 33228690Sdes# include "config.h" 34228690Sdes#endif 35228690Sdes 36228690Sdes#include <security/pam_appl.h> 37228690Sdes 38228690Sdes#include "openpam_impl.h" 39228690Sdes 40228690Sdes#define subst_char(ch) do { \ 41228690Sdes int ch_ = (ch); \ 42228690Sdes if (buf && len < *bufsize) \ 43228690Sdes *buf++ = ch_; \ 44228690Sdes ++len; \ 45228690Sdes} while (0) 46228690Sdes 47228690Sdes#define subst_string(s) do { \ 48228690Sdes const char *s_ = (s); \ 49228690Sdes while (*s_) \ 50228690Sdes subst_char(*s_++); \ 51228690Sdes} while (0) 52228690Sdes 53228690Sdes#define subst_item(i) do { \ 54228690Sdes int i_ = (i); \ 55228690Sdes const void *p_; \ 56228690Sdes ret = pam_get_item(pamh, i_, &p_); \ 57228690Sdes if (ret == PAM_SUCCESS && p_ != NULL) \ 58228690Sdes subst_string(p_); \ 59228690Sdes} while (0) 60228690Sdes 61228690Sdes/* 62228690Sdes * OpenPAM internal 63228690Sdes * 64228690Sdes * Substitute PAM item values in a string 65228690Sdes */ 66228690Sdes 67228690Sdesint 68228690Sdesopenpam_subst(const pam_handle_t *pamh, 69228690Sdes char *buf, size_t *bufsize, const char *template) 70228690Sdes{ 71228690Sdes size_t len; 72228690Sdes int ret; 73228690Sdes 74228690Sdes ENTERS(template); 75228690Sdes if (template == NULL) 76228690Sdes template = "(null)"; 77228690Sdes 78228690Sdes len = 1; /* initialize to 1 for terminating NUL */ 79228690Sdes ret = PAM_SUCCESS; 80228690Sdes while (*template && ret == PAM_SUCCESS) { 81228690Sdes if (template[0] == '%') { 82228690Sdes ++template; 83228690Sdes switch (*template) { 84228690Sdes case 's': 85228690Sdes subst_item(PAM_SERVICE); 86228690Sdes break; 87228690Sdes case 't': 88228690Sdes subst_item(PAM_TTY); 89228690Sdes break; 90228690Sdes case 'h': 91228690Sdes subst_item(PAM_HOST); 92228690Sdes break; 93228690Sdes case 'u': 94228690Sdes subst_item(PAM_USER); 95228690Sdes break; 96228690Sdes case 'H': 97228690Sdes subst_item(PAM_RHOST); 98228690Sdes break; 99228690Sdes case 'U': 100228690Sdes subst_item(PAM_RUSER); 101228690Sdes break; 102228690Sdes case '\0': 103228690Sdes subst_char('%'); 104228690Sdes break; 105228690Sdes default: 106228690Sdes subst_char('%'); 107228690Sdes subst_char(*template); 108228690Sdes } 109228690Sdes ++template; 110228690Sdes } else { 111228690Sdes subst_char(*template++); 112228690Sdes } 113228690Sdes } 114228690Sdes if (buf) 115228690Sdes *buf = '\0'; 116228690Sdes if (ret == PAM_SUCCESS) { 117228690Sdes if (len > *bufsize) 118228690Sdes ret = PAM_TRY_AGAIN; 119228690Sdes *bufsize = len; 120228690Sdes } 121228690Sdes RETURNC(ret); 122228690Sdes} 123228690Sdes 124228690Sdes/* 125228690Sdes * Error codes: 126228690Sdes * 127228690Sdes * =pam_get_item 128228690Sdes * !PAM_SYMBOL_ERR 129228690Sdes * PAM_TRY_AGAIN 130228690Sdes */ 131228690Sdes 132228690Sdes/** 133228690Sdes * The =openpam_subst function expands a string, substituting PAM item 134228690Sdes * values for all occurrences of specific substitution codes. 135228690Sdes * The =template argument points to the initial string. 136228690Sdes * The result is stored in the buffer pointed to by the =buf argument; the 137228690Sdes * =bufsize argument specifies the size of that buffer. 138228690Sdes * The actual size of the resulting string, including the terminating NUL 139228690Sdes * character, is stored in the location pointed to by the =bufsize 140228690Sdes * argument. 141228690Sdes * 142228690Sdes * If =buf is NULL, or if the buffer is too small to hold the expanded 143228690Sdes * string, =bufsize is updated to reflect the amount of space required to 144228690Sdes * hold the entire string, and =openpam_subst returns =PAM_TRY_AGAIN. 145228690Sdes * 146228690Sdes * If =openpam_subst fails for any other reason, the =bufsize argument is 147228690Sdes * untouched, but part of the buffer may still have been overwritten. 148228690Sdes * 149228690Sdes * Substitution codes are introduced by a percent character and correspond 150228690Sdes * to PAM items: 151228690Sdes * 152228690Sdes * %H: 153228690Sdes * Replaced by the current value of the =PAM_RHOST item. 154228690Sdes * %h: 155228690Sdes * Replaced by the current value of the =PAM_HOST item. 156228690Sdes * %s: 157228690Sdes * Replaced by the current value of the =PAM_SERVICE item. 158228690Sdes * %t: 159228690Sdes * Replaced by the current value of the =PAM_TTY item. 160228690Sdes * %U: 161228690Sdes * Replaced by the current value of the =PAM_RUSER item. 162228690Sdes * %u: 163228690Sdes * Replaced by the current value of the =PAM_USER item. 164228690Sdes * 165228690Sdes * >pam_get_authtok 166228690Sdes * >pam_get_item 167228690Sdes * >pam_get_user 168228690Sdes * 169228690Sdes * AUTHOR DES 170228690Sdes */ 171