1 /*- 2 * Copyright (c) 2001,2003 Networks Associates Technology, Inc. 3 * All rights reserved. 4 * 5 * This software was developed for the FreeBSD Project by ThinkSec AS and 6 * NAI Labs, the Security Research Division of Network Associates, Inc. 7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 8 * DARPA CHATS research program. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote 19 * products derived from this software without specific prior written 20 * permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 42 #include <security/pam_appl.h> 43 #include <security/pam_modules.h> 44 #include <security/openpam.h> 45 46 static int 47 _pam_echo(pam_handle_t *pamh, int flags, 48 int argc, const char *argv[]) 49 { 50 char msg[PAM_MAX_MSG_SIZE]; 51 const void *str; 52 const char *p, *q; 53 int err, i, item; 54 size_t len; 55 56 if (flags & PAM_SILENT) 57 return (PAM_SUCCESS); 58 for (i = 0, len = 0; i < argc && len < sizeof(msg) - 1; ++i) { 59 if (i > 0) 60 msg[len++] = ' '; 61 for (p = argv[i]; *p != '\0' && len < sizeof(msg) - 1; ++p) { 62 if (*p != '%' || p[1] == '\0') { 63 msg[len++] = *p; 64 continue; 65 } 66 switch (*++p) { 67 case 'H': 68 item = PAM_RHOST; 69 break; 70 case 'h': 71 /* not implemented */ 72 item = -1; 73 break; 74 case 's': 75 item = PAM_SERVICE; 76 break; 77 case 't': 78 item = PAM_TTY; 79 break; 80 case 'U': 81 item = PAM_RUSER; 82 break; 83 case 'u': 84 item = PAM_USER; 85 break; 86 default: 87 item = -1; 88 msg[len++] = *p; 89 break; 90 } 91 if (item == -1) 92 continue; 93 err = pam_get_item(pamh, item, &str); 94 if (err != PAM_SUCCESS) 95 return (err); 96 if (str == NULL) 97 str = "(null)"; 98 for (q = str; *q != '\0' && len < sizeof(msg) - 1; ++q) 99 msg[len++] = *q; 100 } 101 } 102 msg[len] = '\0'; 103 return (pam_info(pamh, "%s", msg)); 104 } 105 106 PAM_EXTERN int 107 pam_sm_authenticate(pam_handle_t *pamh, int flags, 108 int argc, const char *argv[]) 109 { 110 111 return (_pam_echo(pamh, flags, argc, argv)); 112 } 113 114 PAM_EXTERN int 115 pam_sm_setcred(pam_handle_t *pamh __unused, int flags __unused, 116 int argc __unused, const char *argv[] __unused) 117 { 118 119 return (PAM_SUCCESS); 120 } 121 122 PAM_EXTERN int 123 pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, 124 int argc, const char *argv[]) 125 { 126 127 return (_pam_echo(pamh, flags, argc, argv)); 128 } 129 130 PAM_EXTERN int 131 pam_sm_open_session(pam_handle_t *pamh, int flags, 132 int argc, const char *argv[]) 133 { 134 135 return (_pam_echo(pamh, flags, argc, argv)); 136 } 137 138 PAM_EXTERN int 139 pam_sm_close_session(pam_handle_t *pamh, int flags, 140 int argc, const char *argv[]) 141 { 142 143 return (_pam_echo(pamh, flags, argc, argv)); 144 } 145 146 PAM_EXTERN int 147 pam_sm_chauthtok(pam_handle_t *pamh, int flags, 148 int argc, const char *argv[]) 149 { 150 151 if (flags & PAM_PRELIM_CHECK) 152 return (PAM_SUCCESS); 153 return (_pam_echo(pamh, flags, argc, argv)); 154 } 155 156 PAM_MODULE_ENTRY("pam_echo"); 157