1#include <stdlib.h> 2#include <stdio.h> 3#include <dlfcn.h> 4#include <security/pam_appl.h> 5#include <syslog.h> 6 7const char libopenpam[] = "/usr/lib/libpam.2.dylib"; 8 9 10#define xlate(oldname, oldvalue, newname, newvalue) \ 11 COMPAT_AUTH_##oldname = oldvalue, 12enum { 13#include "pam_shim_authenticate_flags.h" 14}; 15#undef xlate 16 17int 18xlate_pam_shim_authenticate_flags(int flags) 19{ 20 int newflags = 0; 21 22#define xlate(oldname, oldvalue, newname, newvalue) \ 23 if (flags & COMPAT_AUTH_##oldname) newflags |= newname; 24#include "pam_shim_authenticate_flags.h" 25#undef xlate 26 return newflags; 27} 28 29 30#define xlate(oldname, oldvalue, newname, newvalue) \ 31 COMPAT_CHAUTH_##oldname = oldvalue, 32enum { 33#include "pam_shim_chauthtok_flags.h" 34}; 35#undef xlate 36 37int 38xlate_pam_shim_chauthtok_flags(int flags) 39{ 40 int newflags = 0; 41 42#define xlate(oldname, oldvalue, newname, newvalue) \ 43 if (flags & COMPAT_CHAUTH_##oldname) newflags |= newname; 44#include "pam_shim_chauthtok_flags.h" 45#undef xlate 46 return newflags; 47} 48 49 50#define xlate(oldname, oldvalue, newname, newvalue) \ 51 COMPAT_SESSION_##oldname = oldvalue, 52enum { 53#include "pam_shim_session_flags.h" 54}; 55#undef xlate 56 57int 58xlate_pam_shim_session_flags(int flags) 59{ 60 int newflags = 0; 61 62#define xlate(oldname, oldvalue, newname, newvalue) \ 63 if (flags & COMPAT_SESSION_##oldname) newflags |= newname; 64#include "pam_shim_session_flags.h" 65#undef xlate 66 return newflags; 67} 68 69 70#define xlate(oldname, oldvalue, newname, newvalue) \ 71 COMPAT_AUTH_##oldname = oldvalue, 72enum { 73#include "pam_shim_setcred_flags.h" 74}; 75#undef xlate 76 77int 78xlate_pam_shim_setcred_flags(int flags) 79{ 80 int newflags = 0; 81 82#define xlate(oldname, oldvalue, newname, newvalue) \ 83 if (flags & COMPAT_AUTH_##oldname) newflags |= newname; 84#include "pam_shim_setcred_flags.h" 85#undef xlate 86 return newflags; 87} 88 89 90#define xlate(oldname, oldvalue, newname, newvalue) \ 91 COMPAT_##oldname = oldvalue, 92enum { 93#include "pam_shim_retval.h" 94}; 95#undef xlate 96 97int 98xlate_pam_shim_retval(int retval) 99{ 100#define xlate(oldname, oldvalue, newname, newvalue) \ 101 case COMPAT_##oldname: return newname; 102 switch (retval) { 103#include "pam_shim_retval.h" 104 default: return retval; 105 } 106#undef xlate 107} 108 109 110#define xlate(oldname, oldvalue, newname, newvalue) \ 111 COMPAT_##oldname = oldvalue, 112enum { 113#include "pam_shim_item_type.h" 114}; 115#undef xlate 116 117int 118xlate_pam_shim_item_type(int item_type) 119{ 120#define xlate(oldname, oldvalue, newname, newvalue) \ 121 case COMPAT_##oldname: return newname; 122 switch (item_type) { 123#include "pam_shim_item_type.h" 124 default: return item_type; 125 } 126#undef xlate 127} 128 129 130void dlfailure (const char *caller) 131{ 132 syslog(LOG_ERR, "libpam.1.dylib failed calling %s: %s", caller, dlerror()); 133 abort(); 134} 135 136 137typedef int (*pam_start_func)(const char *, const char *, const struct pam_conv *, pam_handle_t **); 138 139int 140pam_start(const char *service_name, const char *user, const struct pam_conv *pam_conversation, pam_handle_t **pamh) 141{ 142 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 143 if (NULL == openpam) dlfailure("pam_start"); 144 pam_start_func func = dlsym(openpam, "pam_start"); 145 if (NULL == func) dlfailure("pam_start"); 146 return xlate_pam_shim_retval(func(service_name, user, pam_conversation, pamh)); 147} 148 149 150typedef int (*pam_end_func)(pam_handle_t *, int); 151 152int 153pam_end(pam_handle_t *pamh, int pam_status) 154{ 155 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 156 if (NULL == openpam) dlfailure("pam_end"); 157 pam_end_func func = dlsym(openpam, "pam_end"); 158 if (NULL == func) dlfailure("pam_end"); 159 return xlate_pam_shim_retval(func(pamh, pam_status)); 160} 161 162 163typedef int (*pam_authenticate_func)(pam_handle_t *, int); 164 165int 166pam_authenticate(pam_handle_t *pamh, int flags) 167{ 168 int newflags = xlate_pam_shim_authenticate_flags(flags); 169 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 170 if (NULL == openpam) dlfailure("pam_authenticate"); 171 pam_authenticate_func func = dlsym(openpam, "pam_authenticate"); 172 if (NULL == func) dlfailure("pam_authenticate"); 173 return xlate_pam_shim_retval(func(pamh, newflags)); 174} 175 176 177typedef int (*pam_setcred_func)(pam_handle_t *, int); 178 179int 180pam_setcred(pam_handle_t *pamh, int flags) 181{ 182 int newflags = xlate_pam_shim_authenticate_flags(flags); 183 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 184 if (NULL == openpam) dlfailure("pam_setcred"); 185 pam_setcred_func func = dlsym(openpam, "pam_setcred"); 186 if (NULL == func) dlfailure("pam_setcred"); 187 return xlate_pam_shim_retval(func(pamh, newflags)); 188} 189 190 191typedef int (*pam_acct_mgmt_func)(pam_handle_t *, int); 192 193int 194pam_acct_mgmt(pam_handle_t *pamh, int flags) 195{ 196 int newflags = xlate_pam_shim_authenticate_flags(flags); 197 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 198 if (NULL == openpam) dlfailure("pam_acct_mgmt"); 199 pam_acct_mgmt_func func = dlsym(openpam, "pam_acct_mgmt"); 200 if (NULL == func) dlfailure("pam_acct_mgmt"); 201 return xlate_pam_shim_retval(func(pamh, newflags)); 202} 203 204 205typedef int (*pam_chauthtok_func)(pam_handle_t *, int); 206 207int 208pam_chauthtok(pam_handle_t *pamh, int flags) 209{ 210 int newflags = xlate_pam_shim_chauthtok_flags(flags); 211 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 212 if (NULL == openpam) dlfailure("pam_chauthtok"); 213 pam_chauthtok_func func = dlsym(openpam, "pam_chauthtok"); 214 if (NULL == func) dlfailure("pam_chauthtok"); 215 return xlate_pam_shim_retval(func(pamh, newflags)); 216} 217 218 219typedef int (*pam_open_session_func)(pam_handle_t *, int); 220 221int 222pam_open_session(pam_handle_t *pamh, int flags) 223{ 224 int newflags = xlate_pam_shim_session_flags(flags); 225 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 226 if (NULL == openpam) dlfailure("pam_open_session"); 227 pam_open_session_func func = dlsym(openpam, "pam_open_session"); 228 if (NULL == func) dlfailure("pam_open_session"); 229 return xlate_pam_shim_retval(func(pamh, newflags)); 230} 231 232 233typedef int (*pam_close_session_func)(pam_handle_t *, int); 234 235int 236pam_close_session(pam_handle_t *pamh, int flags) 237{ 238 int newflags = xlate_pam_shim_session_flags(flags); 239 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 240 if (NULL == openpam) dlfailure("pam_close_session"); 241 pam_close_session_func func = dlsym(openpam, "pam_close_session"); 242 if (NULL == func) dlfailure("pam_close_session"); 243 return xlate_pam_shim_retval(func(pamh, newflags)); 244} 245 246 247typedef int (*pam_set_item_func)(pam_handle_t *, int, const void *); 248 249int 250pam_set_item(pam_handle_t *pamh, int item_type, const void *item) 251{ 252 int newitemtype = xlate_pam_shim_item_type(item_type); 253 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 254 if (NULL == openpam) dlfailure("pam_set_item"); 255 pam_set_item_func func = dlsym(openpam, "pam_set_item"); 256 if (NULL == func) dlfailure("pam_set_item"); 257 return xlate_pam_shim_retval(func(pamh, newitemtype, item)); 258} 259 260 261typedef int (*pam_get_item_func)(const pam_handle_t *, int, const void **); 262 263int 264pam_get_item(const pam_handle_t *pamh, int item_type, const void **item) 265{ 266 int newitemtype = xlate_pam_shim_item_type(item_type); 267 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 268 if (NULL == openpam) dlfailure("pam_get_item"); 269 pam_get_item_func func = dlsym(openpam, "pam_get_item"); 270 if (NULL == func) dlfailure("pam_get_item"); 271 return xlate_pam_shim_retval(func(pamh, newitemtype, item)); 272} 273 274 275typedef int (*misc_conv_func)(int, const struct pam_message **, struct pam_response **, void *); 276 277int 278misc_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr) 279{ 280 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 281 if (NULL == openpam) dlfailure("misc_conv"); 282 misc_conv_func func = dlsym(openpam, "openpam_ttyconv"); 283 if (NULL == func) dlfailure("misc_conv"); 284 return xlate_pam_shim_retval(func(num_msg, msgm, response, appdata_ptr)); 285} 286 287 288typedef const char * (*pam_strerr_func)(const pam_handle_t *, int); 289 290const char * 291pam_strerror(const pam_handle_t *pamh, int pam_error) 292{ 293 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 294 if (NULL == openpam) dlfailure("pam_strerror"); 295 pam_strerr_func func = dlsym(openpam, "pam_strerror"); 296 if (NULL == func) dlfailure("pam_strerror"); 297 return func(pamh, pam_error); 298} 299 300 301typedef int (*pam_putenv_func)(pam_handle_t *, const char *); 302 303int 304pam_putenv(pam_handle_t *pamh, const char *name_value) 305{ 306 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 307 if (NULL == openpam) dlfailure("pam_putenv"); 308 pam_putenv_func func = dlsym(openpam, "pam_putenv"); 309 if (NULL == func) dlfailure("pam_putenv"); 310 return xlate_pam_shim_retval(func(pamh, name_value)); 311} 312 313 314typedef const char * (*pam_getenv_func)(pam_handle_t *, const char *); 315 316const char * 317pam_getenv(pam_handle_t *pamh, const char *name) 318{ 319 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 320 if (NULL == openpam) dlfailure("pam_getenv"); 321 pam_getenv_func func = dlsym(openpam, "pam_getenv"); 322 if (NULL == func) dlfailure("pam_getenv"); 323 return func(pamh, name); 324} 325 326 327typedef char ** (*pam_getenvlist_func)(pam_handle_t *); 328 329char ** 330pam_getenvlist(pam_handle_t *pamh) 331{ 332 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 333 if (NULL == openpam) dlfailure("pam_getenvlist"); 334 pam_getenvlist_func func = dlsym(openpam, "pam_getenvlist"); 335 if (NULL == func) dlfailure("pam_getenvlist"); 336 return func(pamh); 337} 338 339 340typedef int (*pam_get_data_func)(pam_handle_t *, const char *, const void **); 341int aliased_pam_get_data(pam_handle_t *pamh, const char *module_data_name, const void **data) __asm("_pam_get_data"); 342 343int 344aliased_pam_get_data(pam_handle_t *pamh, const char *module_data_name, const void **data) 345{ 346 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 347 if (NULL == openpam) dlfailure("pam_get_data"); 348 pam_get_data_func func = dlsym(openpam, "pam_get_data"); 349 if (NULL == func) dlfailure("pam_get_data"); 350 return xlate_pam_shim_retval(func(pamh, module_data_name, data)); 351} 352 353 354typedef void (*pam_set_data_cleanup_func)(pam_handle_t, void *, int); 355typedef int (*pam_set_data_func)(pam_handle_t *, const char *, void *, pam_set_data_cleanup_func); 356int aliased_pam_set_data(pam_handle_t *pamh, const char *modue_data_name, void *data, pam_set_data_cleanup_func cleanup) __asm("_pam_set_data"); 357 358int 359aliased_pam_set_data(pam_handle_t *pamh, const char *modue_data_name, void *data, pam_set_data_cleanup_func cleanup) 360{ 361 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 362 if (NULL == openpam) dlfailure("pam_set_data"); 363 pam_set_data_func func = dlsym(openpam, "pam_set_data"); 364 if (NULL == func) dlfailure("pam_set_data"); 365 return xlate_pam_shim_retval(func(pamh, modue_data_name, data, cleanup)); 366} 367 368 369typedef int (*pam_get_user_func)(pam_handle_t *, char **, const char *); 370int aliased_pam_get_user(pam_handle_t *pamh, char **user, const char *prompt) __asm("_pam_get_user"); 371 372int 373aliased_pam_get_user(pam_handle_t *pamh, char **user, const char *prompt) 374{ 375 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 376 if (NULL == openpam) dlfailure("pam_get_user"); 377 pam_get_user_func func = dlsym(openpam, "pam_get_user"); 378 if (NULL == func) dlfailure("pam_get_user"); 379 return xlate_pam_shim_retval(func(pamh, user, prompt)); 380} 381 382 383typedef int (*pam_prompt_func)(const pam_handle_t *, int, char **, const char *, ...); 384 385int 386pam_prompt(pam_handle_t *pamh, int style, const char *prompt, char **user_msg) 387{ 388 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 389 if (NULL == openpam) dlfailure("pam_prompt"); 390 pam_prompt_func func = dlsym(openpam, "pam_prompt"); 391 if (NULL == func) dlfailure("pam_prompt"); 392 return xlate_pam_shim_retval(func(pamh, style, user_msg, "%s", prompt)); 393} 394 395 396typedef int (*pam_get_pass_func)(pam_handle_t *, int, const char **, const char *); 397 398int 399pam_get_pass(pam_handle_t *pamh, const char **passp, const char *prompt, __unused int options) 400{ 401 void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST); 402 if (NULL == openpam) dlfailure("pam_get_pass"); 403 pam_get_pass_func func = dlsym(openpam, "pam_get_authtok"); 404 if (NULL == func) dlfailure("pam_get_authtok"); 405 return xlate_pam_shim_retval(func(pamh, PAM_AUTHTOK, passp, prompt)); 406} 407