Patch to implement an @include directive for use in pam.d config files. Authors: Jan Christoph Nordholz Upstream status: not yet submitted Index: pam/Linux-PAM/libpam/pam_handlers.c =================================================================== --- pam.orig/Linux-PAM/libpam/pam_handlers.c +++ pam/Linux-PAM/libpam/pam_handlers.c @@ -114,6 +114,10 @@ module_type = PAM_T_ACCT; } else if (!strcasecmp("password", tok)) { module_type = PAM_T_PASS; + } else if (!strcasecmp("@include", tok)) { + pam_include = 1; + module_type = requested_module_type; + goto parsing_done; } else { /* Illegal module type */ D(("_pam_init_handlers: bad module type: %s", tok)); @@ -178,14 +182,33 @@ _pam_set_default_control(actions, _PAM_ACTION_BAD); } +parsing_done: tok = _pam_StrTok(NULL, " \n\t", &nexttok); if (pam_include) { - if (_pam_load_conf_file(pamh, tok, this_service, module_type + struct stat include_dir; + if (tok[0] == '/') { + if (_pam_load_conf_file(pamh, tok, this_service, module_type #ifdef PAM_READ_BOTH_CONFS - , !other + , !other #endif /* PAM_READ_BOTH_CONFS */ ) == PAM_SUCCESS) - continue; + continue; + } else if (!stat(PAM_CONFIG_D, &include_dir) && S_ISDIR(include_dir.st_mode)) { + char *include_file; + if (asprintf (&include_file, PAM_CONFIG_DF, tok) < 0) { + pam_syslog(pamh, LOG_CRIT, "asprintf failed"); + return PAM_ABORT; + } + if (_pam_load_conf_file(pamh, include_file, this_service, module_type +#ifdef PAM_READ_BOTH_CONFS + , !other +#endif /* PAM_READ_BOTH_CONFS */ + ) == PAM_SUCCESS) { + free(include_file); + continue; + } + free(include_file); + } _pam_set_default_control(actions, _PAM_ACTION_BAD); mod_path = NULL; must_fail = 1;